On the backend, i am getting a folder structure from an API. I recursively iterate over this structure to get all folders. These are then all stored in a 'flat' ordered dictionary. Each folder is stored with some properties to define the structure, the id of the parent folder, the amount of subfolders it has and if itself is a subnode or not.
Now from this ordered dict I am trying to make a nice hierarchical view with Genshi, but the furthest I've gotten so far is the template below. This results in only 2 levels, the root level, and one level below. Any folder even deeper will be displayed at the second level.
I am trying to do this without having to resort to doing a lot of relation checking on the initial parsing of the data to get the level a folder is at and stuff. Does anyone have any clever ideas?
<body>
<div class="main_content">
<h1>Catalogue Tree</h1>
<ul>
<li py:for="nodeId, nodeProps in nodes.iteritems()">
<a py:if="nodeProps['SubNode'] == False" href="${tg.url('/node/' + nodeId)}">${nodeProps['Name']}</a>
<py:if test="nodeProps['SubNode'] == True">
<ul>
<a href="${tg.url('/node/' + nodeId)}">${nodeProps['Name']}</a>
</ul>
</py:if>
</li>
</ul>
</div>
</body>
As I commented, you can solve your issue with a recursive macro created with the py:def
directive. Here's my attempt at a solution (note, I don't have genshi
installed on my system, so this is untested):
<ul py:def="display_nodes(node_ids)">
<li py:for="node_id in node_ids">
<a href="${tg.url('/node/' + node_id)}">${nodes[node_id]['Name']}</a>
<py:if test="nodes[node_id]['SubNodes']">
${display_nodes(nodes[node_id]['SubNodes'])}
</py:if>
</li>
</ul>
${display_nodes(root_nodes)}
This part of the template expects two parameters to be passed, a nodes
dictionary that has all the nodes in it, and a root_nodes
sequence that includes the IDs of all the top level nodes. The structure this creates is a little different than what the code you've linked to does, as it includes the list of child nodes in the <li>
tag of their parent. I'm not sure if that makes any difference or not in the rendering, but it seemed most correct to me to do it that way.