2012-08-16 6 views
6

He estado luchando para crear una extensión Jinja2 durante algunas horas, y parece que definitivamente estoy atrapado en un punto en particular: pasar argumentos de lista a un nodo de llamada. Intenté obtener inspiración con algunas otras extensiones de trabajo y no puedo ver por qué mis cosas no funcionan mientras mi código de referencia sí.Pase argumento de lista a un nodo de llamada en una extensión Jinja2

Básicamente lo que quiero es tener este tipo de cosas en mis plantillas:

{% usebundle "common", "treeview" %}

esto hay que añadir las cuerdas 'comunes' y '' TreeView a alguna lista en el contexto.

Estas son las piezas clave de mi código:

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 

He intentado varias cosas, pero lo que me hace decir que el problema realmente está en el formato de parámetro (el contenido de mi valor names en el función de análisis) es que si reemplazo nodes.List(names) por nodes.Const(42), recibo un valor correcto de 42 en el parámetro de devolución de llamada.

[EDIT] Los detalles del error para esta versión del código es el siguiente:

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' 
+1

Para tener una mejor respuesta que querrá incluir su mensaje de error y/o el rastreo completo. – stderr

Respuesta

2

CallBlock espera de llamada real como primer argumento, no una lista de llamadas.

lo tanto, sólo tiene que utilizar

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

en lugar de

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