Wie funktioniert die Jinja2 "rekursiv" - tag eigentlich ab?
Ich versuche zu schreiben ein sehr einfaches, tree-walking-Vorlage in jinja2, mit einige benutzerdefinierte Objekte überladen mit speziellen Methoden (getattr -, getitem, etc) scheint Es einfach, und die entsprechende python-Fuß des Baumes funktioniert gut, aber es gibt etwas über die Art und Weise, dass Jinja ist die Rekursion funktioniert, dass ich nicht verstehe. Der code ist unten dargestellt:
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)
Die Vorlage ist das auslösen einer Ausnahme, als wenn die Rekursion eigentlich nicht stattfinden. Der innere Ruf ist gemacht, aber irgendwie ist der Verweis auf "Kategorie" bezieht sich noch auf die Eltern. Was gibt es hier? Es muss etwas sehr grundlegendes was mir fehlt, ist, wie diese rekursive templates die funktionieren sollen. (Oder etwas sehr grundlegend dumm, dass ich das Tue, das kann ich einfach nicht sehen.
- Sie sollten die posten auf dem pocoo-libs-mailing-Liste. Armin (Schöpfer von Jinja) werden sehen, Ihre post dort. groups.google.com/group/pocoo-libs/topics
Du musst angemeldet sein, um einen Kommentar abzugeben.
Als ich sehe aus Ihrem code, den Sie verstehen rekursiv korrekt, außer einer Sache: es ersetzt iterierbar in der for-Anweisung, aber nicht update-variable (
category
im code), der ursprünglich aus der it. Damit Sie verschachtelte Schleife durchläuft Kinder, aberset
tag lookups im originalcategory
, nicht einer, der an dieloop()
.Schlage ich vor, ändern
__iter__()
Methode zurückself.items.iteritems()
und Vorlage: