Creating a menu with subpages and filter

I’m a little stuck here. What I’m trying to create is a menu with 5 items, 4 items should show a submenu (only the direct children) and 1 item (about) should show a filter instead of children().

I tried excluding about by creating “$noabout = $pages->not(‘about’);” and just adding it after the foreach method. This works for the main menu. The submenu should only show the children of clicked menu points so i was using “$page->children()”. But this creates some problems:

  1. It will obviously show the children of subpages and so on. I want to show only page (menu) and children (submenu) but no grandchildren and so on.

  2. It will also show the children of “about”, but I don’t wanna display those (I want to display a filter instead). This makes my taking it out of the foreach loop pointless…

I hope this is somehow understandable, I find it very hard to describe this problem…

Not really :wink:

Maybe we can start by you posting the code that you tried?

Thought so, i’m sorry. I will post code. Info: The main menu items are About, Projects (this is the one with a filter instead submenu), Team, Jobs, Contact
For the main menu I tried:

<?php
$excluded = $pages->not('projects');
?>

<nav>
    <ul>
        <?php foreach($excluded->listed() as $main_menu): ?>
            <li>
                <a href="<?= $main_menu->url() ?>">
                  <?= $main_menu->title()->html() ?>
                </a>
            </li>
        <?php endforeach ?>
    </ul>
</nav>

This will show all the main-menu items (aka pages) except projects. My thought was to put projects in front of the foreach-loop as a simple

  • -element.
    The sub-menu should show all the children elements of those pages, so:

    <nav>
        <ul>
            <?php foreach($page->children() as $sub_menu): ?>
                <li>
                    <a href="<?= $sub_menu->url() ?>">
                        <?= $sub_menu->title()->html() ?>
                    </a>
                </li>
            <?php endforeach ?>
        </ul>
    </nav>
    
    

    The problem here is that it also shows the children of the projects page (since it is not excluded) and it also shows children of the children. I want the sub-menu to “stop” with the first children.
    I tried:

    <?php if ($child->parents()->count() < 1):?>
          <p> <?= $child->title() ?></p>
    <?php endif;?>
    

    That didn’t work…

    For the projects I thought about adding a static filter with all the filter options I need but since it is not part of the foreach it is not dynamic.

    So the problem is that I want a submenu that will only show the direct children of the main pages and nothing further down the tree and I want one of the elements to display a filter instead of those sub-pages.

  • Ok, so the submenu is separate from the main menu, and you only want to show it for the first level pages.

    So you can check the depth() of the page in the page tree and also make sure it’s not the projects page with an if statement like this:

    <?php if ($page->depth() === 1 && ! $page->is(page('projects') : ?>
    <nav>
        <ul>
            <?php foreach($page->children() as $sub_menu): ?>
                <li>
                    <a href="<?= $sub_menu->url() ?>">
                        <?= $sub_menu->title()->html() ?>
                    </a>
                </li>
            <?php endforeach ?>
        </ul>
    </nav>
    <?php endif ?>
    

    And for the filters you want to show, you can also do this conditionally

    <?php if ($page->is(page('projects') : ?>
      <!-- your filters here -->
    <?php endforeach ?>
    

    Not quite getting why you want to exclude the about aka projects page from the main menu :thinking:?

    Haha, I didn’t really want to exclude it. It was just a dumb idea. Your solution works like a charm!!
    Thank you so much. This is awesome.