Estoy tratando de escribir una plantilla muy simple para caminar sobre árboles en jinja2, usando algunos objetos personalizados con métodos especiales sobrecargados (getattr, getitem, etc.) Parece sencillo, y el camino de python equivalente funciona bien, pero hay algo sobre la forma en que funciona la recursión de Jinja que no entiendo. El código se muestra a continuación:¿Cómo funciona realmente la etiqueta "recursiva" de Jinja2?
from jinja2 import Template
class Category(object):
def __init__(self, name):
self.name = name
self.items = {}
self.children = True
def __iter__(self):
return iter(self.items)
def add(self, key, item):
self.items[key] = item
return item
def __getitem__(self, item):
return self.items[item]
def __getattr__(self, attr):
try:
return self.items[attr]
except KeyError:
raise AttributeError(attr)
def __str__(self):
return "<Category '%s'>" % self.name
template = '''
<saved_data>
{% for key in category recursive %}
{% set item = category[key] %}
{% if item.children %}
<category name="{{key}}">
{{ loop(item) }}
</category>
{% else %}
<item name="{{ key }}" value="{{ item }}" />
{% endif %}
{% endfor %}
</saved_data>
'''
b = Category('root')
c = b.add("numbers", Category('numbers'))
c.add("one", 1)
c.add("two", 2)
c.add("three", 3)
d = b.add("letters", Category('letters'))
d.add('ay','a')
d.add('bee','b')
d.add('cee','c')
e = d.add("bools", Category('bools'))
e.add('tru', True)
e.add('fals', False)
def walk(c, depth=0):
for key in c:
item = c[key]
print (' '*depth) + str(item)
if hasattr(item, 'children'):
walk(item, depth+3)
print "Python walking the tree:"
walk(b)
print ""
print "Jinja2 Walking the tree:"
t = Template(template)
print t.render(category = b)
La plantilla genera una excepción como si la recursión en realidad no tuviera lugar. La llamada interna se realiza, pero de alguna manera la referencia a 'categoría' todavía se refiere al padre. ¿Qué da aquí? Debe haber algo muy fundamental que me falta acerca de cómo se supone que estas plantillas recursivas funcionan. (O algo muy fundamentalmente tonto que estoy haciendo que simplemente no puedo ver.
Debe publicar en la lista de correo de pocoo-libs. Armin (creador de Jinja) verá tu publicación allí. http://groups.google.com/group/pocoo-libs/topics –