I have the following dictionary:
{'a': {'b': {'c': {}}}}
And the following Jinja2 template:
{% for key in dictionary recursive %}
<li>{{ key }}
{% if dictionary[key] %}
<ul>{{ loop(dictionary[key]) }}</ul>
{% endif %}
</li>
{% endfor %}
But Jinja2 always output:
<ul>
<li>a</li>
<ul>
<li>b</li>
</ul>
</ul>
My understood is that using recursive, it would show me the "c" element too, but it only works for a depth of 2. Why is dictionary
not changing to the dictionary[key]
at every loop iteration ? The dictionary
is always the original dictionary
.
You're right, dictionary
isn't being updated in the recursion calls, and the loop cannot continue because the keys aren't found.
A workaround to this problem is using just the variables assigned in the for loop. In the dictionary example, this means to iterate through the items of the dictionary instead of just the keys:
from jinja2 import Template
template = Template("""
{%- for key, value in dictionary.items() recursive %}
<li>{{ key }}
{%- if value %}
Recursive {{ key }}, {{value}}
<ul>{{ loop(value.items())}}</ul>
{%- endif %}
</li>
{%- endfor %}
""")
print template.render(dictionary={'a': {'b': {'c': {}}}})
The output of this script is:
<li>a
Recursive a, {'b': {'c': {}}}
<ul>
<li>b
Recursive b, {'c': {}}
<ul>
<li>c
</li></ul>
</li></ul>
</li>
where you can see that recursion on the b
key works fine because both key
and value
are updated on each iteration of the loop (I added the "Recursive key, value" message to the template to make it clear).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With