Navigations and menus are an essential part of any website. Automad provides convenient ways to iterate the pages of a site recursively and therefore allows for creating site trees in a few simple steps. For simple cases, the navTree function generates a complete tree in a single statement. In case you need full control over the generated markup, you can build your own tree using a recursive snippet. Conceptually, building such a tree can be divided into three steps.
Defining a Recursive Snippet
A recursive snippet is a snippet that conditionally calls itself. While iterating a pagelist of type children, the snippet calls itself in order to start a new iteration over the children of the current page in the loop. A typical snippet looks as follows:
<@ snippet navigation @>
<ul class="menu">
<@ foreach in pagelist @>
<li>
<a href="@{ url }">@{ title }</a>
<# Call the snippet recursively. #>
<@ if @{ :pagelistCount } @>
<@ navigation @>
<@ end @>
</li>
<@ end @>
</ul>
<@ end @>
Since the context changes to the current page in each iteration, :pagelistCount returns the number of children of that page. That way, the snippet only calls itself for pages that actually have children.
Configuring the Pagelist
The pagelist has to be of type children. Note that it is important to not define the context option. The context can then change dynamically within the snippet defined above.
<@ newPagelist {
type: 'children',
excludeHidden: true
} @>
Starting the Recursion
In a last step, the root of the navigation tree has to be defined using a with statement and the snippet has to be called once in order to start the recursion.
<@ with '/' @>
<@ navigation @>
<@ end @>
Expanding the Current Path
In larger sites, it is often desirable to only expand the branches of the tree that lead to the current page. The :currentPath and :current runtime variables can be used to test whether a page is part of the current path or is the current page itself. The following example is a simplified version of the sidebar navigation of the Standard Lite theme, which uses details elements that are open for all pages in the current path:
<@~ snippet treeNode ~@>
<li>
<@ if @{ :pagelistCount } ~@>
<details<@ if @{ :currentPath } @> open<@ end @>>
<summary>
<a
href="@{ url }"
<@ if @{ :current } @>class="active"<@ end @>
>
@{ title }
</a>
</summary>
<ul>
<@~ tree ~@>
</ul>
</details>
<@ else @>
<a
href="@{ url }"
<@ if @{ :current } @>class="active"<@ end @>
>
@{ title }
</a>
<@~ end ~@>
</li>
<@~ end @>
<@~ snippet tree ~@>
<@ newPagelist {
context: false,
type: 'children'
} ~@>
<@~ foreach in pagelist @>
<@~ treeNode ~@>
<@ end ~@>
<@~ end @>
<nav>
<@ with '/' ~@>
<ul>
<@~ tree ~@>
</ul>
<@~ end @>
</nav>