6

Jinja2 エクステンションを作成するのに数時間苦労してきましたが、特定の 1 つの点に固執しているようです: リスト引数を Call ノードに渡すことです。他のいくつかの機能する拡張機能でインスピレーションを得ようとしましたが、参照コードが機能するのに自分のものが機能しない理由がわかりません。

基本的に私が欲しいのは、テンプレートにこのようなものを含めることです:

{% usebundle "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'
4

1 に答える 1

2

CallBlock は、呼び出しのリストではなく、実際の呼び出しを最初の引数として想定しています。

だから、あなたはただ使う必要があります

nodes.CallBlock(call, [], [], [])

それ以外の

nodes.CallBlock([call], [], [], [])
于 2013-03-05T10:55:23.973 に答える