Skip to content

pbMenu ​

Resource tree for navigation.

[[!pbMenu? &parent=`0` &level=`3` &tpl=`menuItem`]]

Parameters ​

ParameterDefaultDescription
parent0Root of the tree. 0 means the site root.
level3How many levels deep to walk.

Plus the shared output parameters from Intro.

Each row carries its children ​

Unlike a flat list, every item has a children collection, so one chunk renders the whole tree by calling itself:

php
<li>
    <a href="{$item.url}">{$item.title}</a>
    {if $item.children}
        <ul>
            {foreach $item.children as $child}
                {'menuItem'|chunk: ['item' => $child]}
            {/foreach}
        </ul>
    {/if}
</li>

The snippet does not fill active

An item does carry active, is_ancestor and has_active_child, but they are only populated when Resource::getMenu() is called with its third argument — the id of the current page. Neither pbMenu nor the menu modifier passes it, so {if $item.active} in a chunk never fires. Mark the current item by comparing ids yourself for now: {if $item.id == $modx->resource->id}.

{insert} and {include} share scope

The loop variable is visible inside the included chunk — that is what makes the recursion above work. It also means a variable you set in the parent can leak in and surprise you. Name loop variables deliberately.

Examples ​

Top-level menu, one level ​

[[!pbMenu? &level=`1` &tpl=`menuItem`]]
[[!pbMenu? &parent=`[[*id]]` &level=`2` &tpl=`menuItem`]]

From Fenom ​

php
{foreach menu(0, 2) as $item}
    <a href="{$item.url}">{$item.title}</a>
{/foreach}

A menu item is an array, not a model: read it with a dot, not with ->. The keys are id, parent, template, class_key, title (menutitle or pagetitle), pagetitle, menutitle, alias, uri, url (the finished href, language prefix included), link_attributes, description, introtext, isfolder, menuindex, new_until, level, content, children.

© PageBlocks 2019-present