I've been struggling to create a Jinja2 extention for some hours now, and it seems I'm definitely stuck on one particular point: passing list arguments to a Call node. I tried to get inspiration with some other working extentions and I can't see why my stuff does not work while my reference code does.
Basically what I want is to have this kind of stuff in my templates:
{% usebundle "common", "treeview" %}
This should add the 'common' and 'treeview' strings to some list in the context.
Here are the key parts of my code:
class MyExtension(Extension):
def __init__(self, environment):
super(MyExtension, self).__init__(environment)
def parse(self, parser):
lineno = parser.stream.next().lineno
names = []
while parser.stream.current.type != 'block_end':
names.append(parser.parse_expression())
parser.stream.skip_if('comma')
# At this point, names is a correctly filled array of names
call = self.call_method('_callback', args=[nodes.List(names)])
result = nodes.CallBlock([call], [], [], [])
result.set_lineno(lineno)
return result
def _callback(self, names, caller=None):
# Here names should contain a list of names, but it's either undefined or
# a list of Undefined, or I get an error before reaching this callback
# (generally saying that arguments cannot be read)
pass
I tried several things, but the thing that makes me say that the problem really is in the parameter format (the contents of my names
value in the parse function) is that if I replace nodes.List(names)
by nodes.Const(42)
, I receive a correct 42
value in the callback parameter.
[EDIT] The error details for this version of the code is the following:
Exception on /login [GET]
Traceback (most recent call last):
File "E:\Python27\lib\site-packages\flask-0.9-py2.7.egg\flask\app.py", line 1687, in wsgi_app
response = self.full_dispatch_request()
File "E:\Python27\lib\site-packages\flask-0.9-py2.7.egg\flask\app.py", line 1360, in full_dispatch_request
rv = self.handle_user_exception(e)
File "E:\Python27\lib\site-packages\flask-0.9-py2.7.egg\flask\app.py", line 1358, in full_dispatch_request
rv = self.dispatch_request()
File "E:\Python27\lib\site-packages\flask-0.9-py2.7.egg\flask\app.py", line 1344, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "E:\myapplication\user.py", line 126, in login
return template_or_json('user/login.html', form=form)
File "E:\myapplication\ajax.py", line 32, in template_or_json
return render_template(template_name, **context)
File "E:\Python27\lib\site-packages\flask-0.9-py2.7.egg\flask\templating.py", line 125, in render_template
context, ctx.app)
File "E:\Python27\lib\site-packages\flask-0.9-py2.7.egg\flask\templating.py", line 107, in _render
rv = template.render(context)
File "E:\Python27\lib\site-packages\jinja2-2.6-py2.7.egg\jinja2\environment.py", line 894, in render
return self.environment.handle_exception(exc_info, True)
File "E:\myapplication\templates\user\login.html", line 1, in top-level template code
{% extends "layout.html" %}
File "E:\Python27\lib\site-packages\jinja2-2.6-py2.7.egg\jinja2\environment.py", line 443, in _generate
return generate(source, self, name, filename, defer_init=defer_init)
File "E:\Python27\lib\site-packages\jinja2-2.6-py2.7.egg\jinja2\compiler.py", line 63, in generate
generator.visit(node)
File "E:\Python27\lib\site-packages\jinja2-2.6-py2.7.egg\jinja2\visitor.py", line 38, in visit
return f(node, *args, **kwargs)
File "E:\Python27\lib\site-packages\jinja2-2.6-py2.7.egg\jinja2\compiler.py", line 803, in visit_Template
frame.inspect(node.body)
File "E:\Python27\lib\site-packages\jinja2-2.6-py2.7.egg\jinja2\compiler.py", line 201, in inspect
visitor.visit(node)
File "E:\Python27\lib\site-packages\jinja2-2.6-py2.7.egg\jinja2\visitor.py", line 38, in visit
return f(node, *args, **kwargs)
File "E:\Python27\lib\site-packages\jinja2-2.6-py2.7.egg\jinja2\compiler.py", line 347, in visit_CallBlock
self.visit(node.call)
File "E:\Python27\lib\site-packages\jinja2-2.6-py2.7.egg\jinja2\visitor.py", line 39, in visit
return self.generic_visit(node, *args, **kwargs)
File "E:\Python27\lib\site-packages\jinja2-2.6-py2.7.egg\jinja2\visitor.py", line 43, in generic_visit
for node in node.iter_child_nodes():
AttributeError: 'list' object has no attribute 'iter_child_nodes'
CallBlock expects actual call as the first argument, not some list of calls.
So, you just have to use
nodes.CallBlock(call, [], [], [])
instead of
nodes.CallBlock([call], [], [], [])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With