我一直在努力创建一个Jinja2扩展几个小时,似乎我肯定会陷入一个特定点:将列表参数传递给Call节点。我试图通过其他一些工作扩展获得灵感,但我无法理解为什么我的东西在我的参考代码中不起作用。
基本上我想要的是在我的模板中有这样的东西:
{% usebundle "common", "treeview" %}
这应该将'common'和'treeview'字符串添加到上下文中的某个列表中。
以下是我的代码的关键部分:
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
我尝试了几件事,但让我说问题确实是参数格式(解析函数中names
值的内容)的问题是,如果我替换nodes.List(names)
通过nodes.Const(42)
,我在回调参数中收到了正确的42
值。
[编辑]此版本代码的错误详细信息如下:
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'
答案 0 :(得分:2)
CallBlock期望实际调用作为第一个参数,而不是一些调用列表。
所以,你只需要使用
nodes.CallBlock(call, [], [], [])
而不是
nodes.CallBlock([call], [], [], [])