Suppose I have a tree-like data structure in Python:
class Node:
def __init__(self, name: str, neighbors: Optional[Iterable[Node]] = None) -> None:
self.name = name
self.neghbors = neighbors or []
grand_child1 = Node("grand_child1")
grand_child2 = Node("grand_child1")
child = Node("child", [grand_child1, grand_child2])
root = Node("root", [child])
Now I want to render this structure into a ul
in HTML
. I want the output to be something like this:
<ul>
<li>root</li>
<ul>
<li>child</li>
<ul>
<li>grand_child1</li>
<li>grand_child2</li>
</ul>
<ul>
</ul>
To do this I want to use a Jinja
template. The what I want to extract from each node is the same, it's just that I want to capture the tree structure and avoid duplicate code.
Is there a way to use a template recursively? Something like this:
<ul>
{% for root in roots %}
<li>{{ root.name }}</li>
{# this template applied for the neighbors #}
{% endfor %}
</ul>
Turns out you can define macros in jinja
which work like functions. Something like this will do the trick:
{% macro make_ul(roots) -%}
<ul>
{% for root in roots %}
<li>{{ root.name }}</li>
{{ make_ul(root.neighbors) }}
{% endfor %}
</ul>
{%- endmacro %}
{{ make_ul(roots) }}
This way the macro will call itself recursively till it hits the leaves of the tree.