Best way to build dynamic sub menus?

What is the best way to build a dynamic sub menu? My site structure is something like this:

Home

  • News
  • About
    — Club
    — History
  • Tickets
  • Jobs
  • Media
    — Videos
    — Photos
  • Contact

Now, when I build the menu and call for all subpages of “Home”, I will get the first layer. The problem is, the “About” and “Media” links should not have a link to their page, because a click on this item should open the sub menu. When I do the normal foreach loop, every item is the same. The next problem, I need the subpages of “About” and “Media”. How can I integrate this into my menu loop? Ofcourse, I do not need the subpages of the “News” page.

Right now I did build my menu line by line by myself. All links are build with the find() function and if the client changes the name of the page or changes the status to draft, the line does not work anymore and the error page appears.

<ul>
   <li><a href="<?= $site->url() ?>">Start</a></li>
   <li><a href="javascript:void(0)" class="nav-nfk" onclick="toggleSubNav1()"><?= $site->find("netzwerk")->title() ?></a></li>
   <ul class="nav-sub-1">
      <?php foreach($site->find("netzwerk")->children()->listed() as $subpage): ?>
      <li><a href="<?= $subpage->url() ?>"><?= $subpage->title() ?></a></li>
      <?php endforeach ?>
   </ul>
   <li><a href="<?= $site->find("news")->url() ?>"><?= $site->find("news")->title() ?></a></li>
   <li><a href="<?= $site->find("projekte")->url() ?>"><?= $site->find("projekte")->title() ?></a></li>
   <li><a href="<?= $site->find("termine")->url() ?>"><?= $site->find("termine")->title() ?></a></li>
   <li><a href="javascript:void(0)"  class="nav-nfk" onclick="toggleSubNav2()"><?= $site->find("bildung")->title() ?></a></li>
   <ul class="nav-sub-2">
      <?php foreach($site->find("bildung")->children()->listed() as $subpage): ?>
      <li><a href="<?= $subpage->url() ?>"><?= $subpage->title() ?></a></li>
      <?php endforeach ?>
   </ul>
   <li><a href="<?= $site->find("jobs")->url() ?>"><?= $site->find("jobs")->title() ?></a></li>
   <li><a href="<?= $site->find("presse")->url() ?>"><?= $site->find("presse")->title() ?></a></li>
</ul>

So, what is the best way to build a dynamic sub menu, where the client can change names and the status of the subpages.

Just for giggles… since you never got an answer. First, did you ever solve this because I need the same - but for 2 or 3 levels.
However, this works automatically for main pages and children… for anyone finding this thread like I did.

<?php
$items = false;
if ($root = $pages->findOpen()) {
    // get visible children for the root item
    $items = $root->children()->listed()->filterby('Template', 'page');
}
if ($items && $items->isNotEmpty()): 
        if ($page->parents()->count() > 0 ): ?> // page is child - main button is PAGE
            <a class="ds-menu-item menu-parent" href="<?= $page->parent()->url() ?>"><?= html($page->parent()->title()) ?></a>
        <?php else: ?> // no children so main button is HOME
            <a class="ds-menu-item menu-home" href="<?= url('') ?>">HOME</a>
        <?php endif; ?>
    <?php foreach ($items as $item): ?>
        <a class="ds-menu-item" href="<?= $item->url() ?>"><?= $item->title()->html() ?></a>
    <?php endforeach; ?>
<?php else: ?> // not a child page so normal first-level menu
    <a class="ds-menu-item menu-home" href="<?= url('') ?>">HOME</a>
    <?php $items = $pages->listed()->filterby('Template', 'page');
    if ($items->isNotEmpty()):
        foreach ($items as $item): ?>
            <a class="ds-menu-item" href="<?= $item->url() ?>"><?= $item->title()->html() ?></a>
        <?php endforeach; ?>
    <?php endif; ?>
<?php endif; ?>
<a class="ds-menu-item menu-back" href="javascript:history.back()">BACK</a>

Check out this post. I had the same question and posted the working code at the end of the post:

Thanks but that isn’t what I’m after. Your code build a menu with submenus.
I need one flat menu. It shows my 7 ‘root’ pages.
If I open a page with children, the whole menu is replaced with the page itself, and it’s children.

Home
 - p1
 - p2
 - p3
    --p3-sub1
    --p3-sub2
        ---sub2-subsub1
        ---sub2-subsub2
    --p3-sub3
- p4
- p5

On the home page the menu is: HOME | p1 | p2 | p3 | p4 | p5
On p3 - the menu is: p3 | p3-sub1 | p3-sub2 | p3-sub3

working so far. But then on p3-sub2 the menu still reads: p3 | p3-sub1 | p3-sub2 | p3-sub3
Where it should read: p3-sub2 | -sub2-subsub1 | -sub2-subsub2

Sorry, my answer was addressed to u13712.
His question was about navigation with another layer.
Unfortunately, I do not have a solution for your case.

No worries. I got there anyway… Thanks.

1 Like