Hello,

I am trying to implement Nunjucks' RemoteExtension in Jinja2.
The RemoteExtension info is 
at http://mozilla.github.io/nunjucks/api.html#custom-tags
And I am using as a base example the FragmentCacheExtension example from 
the docs: http://jinja.pocoo.org/docs/dev/extensions/#example-extension

The idea is to be able to request remote content (identified by a given 
URL) and act upon it.
An example template might look like this:


content before 

{% remote "http://google.com.br"; %}

do something when the request is ok

{% error %}

do something else when the request failed

{% endremote %}

content after


Here is the extension class I wrote:


   1. import jinja2
   2. import jinja2.ext
   3. import jinja2.nodes
   4. import tornado.httpclient
   5. 
   6. class RemoteExtension(jinja2.ext.Extension):
   7.  
   8.     tags = set(['remote'])
   9.  
   10.     def __init__(self, environment):
   11.         super(RemoteExtension, self).__init__(environment)
   12.         # TODO: Add some defaults?!
   13.  
   14.     def parse(self, parser):
   15.         lineno = parser.stream.next().lineno
   16.         args = [parser.parse_expression()]
   17.         body = parser.parse_statements(['name:endremote', 
   'name:error'])
   18.         args += body
   19.         if parser.stream.skip_if('name:error'):
   20.             error_body = parser.parse_statements(['name:endremote'],
    drop_needle=True)
   21.         else:
   22.             error_body = [jinja2.nodes.Const(None)]
   23.             parser.stream.skip()
   24.         args += error_body
   25.  
   26.         # this works: return jinja2.nodes.Const('simple text')
   27.  
   28.         # this gives the error: "NameError: global name 't_1' is not 
   defined"
   29.         return jinja2.nodes.CallBlock(self.call_method(
   '_remote_support', args), [], [], []).set_lineno(lineno)
   30.  
   31.     def get_http_client(self):
   32.         return tornado.httpclient.AsyncHTTPClient()
   33.  
   34.     def _remote_support(self, url, body, error_body, caller):
   35.         # TODO: perform async HTTP request with Tornado (check if 
   it's at all possible...?!)
   36.         pass
   

When I run my program, the template is loaded and parsed (seemingly 
correctly) but the failure occurs when the rendering is executed.

ERROR:tornado.application:Uncaught exception GET / (::1)
HTTPServerRequest(protocol='http', host='localhost:5001', method='GET', 
uri='/', version='HTTP/1.1', remote_ip='::1', headers={'Accept-Language': 
'pt-BR,pt;q=0.8,he;q=0.6,en;q=0.4,es;q=0.2', 'Accept-Encoding': 'gzip, 
deflate, sdch', 'Host': 'localhost:5001', 'Accept': 
'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) 
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.93 Safari/537.36', 
'Connection': 'keep-alive', 'Cookie': 
'_xsrf=2|0ec96e53|896b633859a2ccf783ab4cd6a0f609fb|1415573549; 
brlvs=bc386d71-595d-4f55-84fd-e3396067fdbe; s_v19=1420032782119; 
s_ria=flash%2016%7Csilverlight%20not%20detected; 
nav23155=13777809082_1131_8:15:14:11_PortoAlegre:SmallAppliance-Household-Family:Movie-Vehicle-Funny:Explorers;
 
s_val=http%3A%2F%2Flocalhost%3A8080%2Fparceiros.html%7C; s_cc=true; 
dmpaudm=; dmpaudc=00000m_000000; 
uv=1272ab117a197e17cdce5911ee2621542c5b4a31548fe8028573d61ce84dc12cc7b8bb3de8cedeeee;
 
_ga=GA1.1.1072705065.1420032782', 'Cache-Control': 'max-age=0'})
Traceback (most recent call last):
  File 
"/Users/roi.avidan/.virtualenvs/renderer/lib/python2.7/site-packages/tornado/web.py",
 
line 1332, in _execute
    result = method(*self.path_args, **self.path_kwargs)
  File "/Users/roi.avidan/code/python/Terra/renderer/app.py", line 11, in 
get
    return self.render2('remote.html', **data)
  File "/Users/roi.avidan/code/python/Terra/renderer/HandlerWithJinja.py", 
line 46, in render2
    content = self.render_template(template_name, **kwargs)
  File "/Users/roi.avidan/code/python/Terra/renderer/HandlerWithJinja.py", 
line 24, in render_template
    content = template.render(kwargs)
  File 
"/Users/roi.avidan/.virtualenvs/renderer/lib/python2.7/site-packages/jinja2/environment.py",
 
line 969, in render
    return self.environment.handle_exception(exc_info, True)
  File 
"/Users/roi.avidan/.virtualenvs/renderer/lib/python2.7/site-packages/jinja2/environment.py",
 
line 742, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "templates/remote.html", line 2, in top-level template code
    {% remote "http://google.com.br"; %}
*NameError: global name 't_1' is not defined*


I should add that I am using Jinja2 with Tornado, hence the tornado 
references in the above stack trace.

Have been able to trace the error up to a certain point in the file 
"environment.py":

class Template(object):

           ...

def render(self, *args, **kwargs):

    """This method accepts the same arguments as the `dict` constructor:

    A dict, a dict subclass or some keyword arguments.  If no arguments

    are given the context will be empty.  These two calls do the same::


        template.render(knights='that say nih')

        template.render({'knights': 'that say nih'})


    This will return the rendered template as unicode string.

    """

    vars = dict(*args, **kwargs)

    try:

        return concat(self.root_render_func(self.new_context(vars)))    * <---- 
exception happens here*

    except Exception:

        exc_info = sys.exc_info()

    return self.environment.handle_exception(exc_info, True)


Since Jinja compiles it's templates, I am not able to get into the point 
where the exception occurs and inspect the stack trace, but I was able to 
obtain the generated template code used for my function:

from __future__ import division
from jinja2.runtime import LoopContext, TemplateReference, Macro, Markup, 
TemplateRuntimeError, missing, concat, escape, markup_join, unicode_join, 
to_string, identity, TemplateNotFound
name = 'remote.html'

def root(context, environment=environment):
    if 0: yield None
    yield u'before\n'
    def macro():
        t_1 = []
        pass
        return concat(t_1)
    caller = Macro(environment, macro, None, (), (), False, False, False)
    yield 
context.call(environment.extensions['RemoteExtension.RemoteExtension']._remote_support,
 
'http://google.com.br',
    t_1.append(
        u'\nok body\n',
    ),
    t_1.append(
        u'\nerror body\n',
    ), caller=caller)
    yield u'\nafter'

blocks = {}
debug_info = '2=8'


I am not sure what I am doing wrong.
Any help is most appreciated!!

Thanks in advance,

Roi

-- 
You received this message because you are subscribed to the Google Groups 
"pocoo-libs" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/pocoo-libs.
For more options, visit https://groups.google.com/d/optout.

Reply via email to