Próbuję napisać bardzo prosty szablon chodzenia po drzewach w jinja2, używając pewnych niestandardowych obiektów z przeciążonymi specjalnymi metodami (getattr, getitem, itp.) Wydaje się to proste, a równoważny spacer pythonowy z drzewa działa dobrze, ale jest coś w sposobie, w jaki działa rekursja Jinji, której nie rozumiem. Kod jest wyświetlany poniżej:Jak działa tag rekurencyjny 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)
Szablon zgłasza wyjątek, tak jakby rekursja faktycznie nie miała miejsca. Wywołanie wewnętrzne jest wykonane, ale jakoś odniesienie do "kategorii" nadal odnosi się do rodzica. Co daje tutaj? Musi istnieć coś bardzo podstawowego, czego mi brakuje na temat tego, jak te szablony rekurencyjne mają działać. (Lub coś bardzo głupiego, co robię, czego po prostu nie widzę)
Powinieneś publikować na liście dyskusyjnej pocoo-libs. Armin (twórca Jinja) zobaczy twój post. http://groups.google.com/group/pocoo-libs/topics –