4

Given a structure that has, for example, three levels of content—how do I just iterate over it and create a nested <ul> reflecting the hierarchy and containing the title and slug (as a link) of each entry?

The following just gives me a flat representation of the structure:

<div class="panel">
    <h2>People</h2>
    <ul>
        {% for entry in craft.entries.section('people') %}
            <li><a href="{{ entry.url }}">{{ entry.title }}</a></li>
        {% endfor %}
    </ul>
</div>
Victor
  • 8,376
  • 1
  • 34
  • 61
hamishtaplin
  • 776
  • 8
  • 16

2 Answers2

6

This could be achieved through a recursive macro:

{% macro recursive_nav(entries, depth) %}
{% import _self as self %}
<ul>
    {% for e in entries %}
        <li>
            <a href="{{ e.url }}">{{ e.title }}</a>
            {% if e.hasDescendants() %}
                {{ self.recursive_nav(e.children, depth+1) }}
            {% endif %}
        </li>
    {% endfor %}
</ul>
{% endmacro %}

And then to use it in your template:

{% import '_macros/recursive-nav.twig' as rn %}
{% set entry = craft.entries.section('people').level(1) %}
<div class="panel">
    <h2>People</h2>
    {{ rn.recursive_nav(entry, 1) }}
</div>

This was borrowed and slightly modified from Marion's answer here. That question is also a great resource for other ways to achieve this result.

Peter Tell
  • 1,828
  • 12
  • 19
  • Great answer. I guess this isn't possible without the macro unless you know how many levels deep you'll be going. – hamishtaplin Sep 09 '14 at 14:10
  • Right because the macro is used for recursion. If you know how many levels you're going you can just keep looping. You could also setup a macro to only loop a finite amount or accept a number of levels as a variable. – Peter Tell Sep 09 '14 at 14:11
6

Craft's built-in {% nav %} tag would save you having to write your own recursive macro:

Adapted from http://buildwithcraft.com/docs/templating/nav

<div class="panel">
    <h2>People</h2>
    <ul>
        {% nav entry in craft.entries.section('people') %}
            <li>
                <a href="{{ entry.url }}">{{ entry.title }}</a>
                {% ifchildren %}
                    <ul>
                        {% children %}
                    </ul>
                {% endifchildren %}
            </li>
        {% endnav %}
    </ul>
</div>

It's not quite as flexible, but is more readable. It should be all you need if it's just links to the entries you want, and it might be a tiny bit faster, but I haven't actually compared twig's compiled macro vs it's tag code.

Mike Pepper
  • 4,391
  • 17
  • 26