I have a niche case where I’m not building a website but a kind of App. I’d like to ‘automate’ menus, such that if we open a page that has children, the page becomes the first menu item, and the children populate the menu. I have this working, but only for the first children. If a child also has children, it doesn’t pick this up.
Does anyone know how I might modify my code so that it ‘steps down’ the tree like this?
Here is the code that works up to first level children. Sorry if it’s a mess - I am not a great coder.
<?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 ): ?>
<a class="ds-menu-item menu-parent" href="<?= $page->parent()->url() ?>"><?= html($page->parent()->title()) ?></a>
<?php else: ?>
<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: ?>
<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>
$pages
refers to the first level pages, hence the open root page will always be a first level page.
It should work if you always use $page
(i.e. the current page) as your basis. Then get the children of this page.
The first link would be $page
, with the other links going to $page->children()
If I understood correctly what you want to achieve, that is…
Thanks. The page not pages got me part way there. It also needs a ‘we reached the end of the branch’ check so current siblings still show (the if count===0 bit in the code below). For some reasons $pages->siblings() returns nothing for me no matter where I used it, so I had to use the clunky feeling $pages->parent()->children()
I know I’m doing weird niche stuff… but… for anyone else who wants to build a menu that ‘walks down the tree’ (rather than adding menu->submenu->subsub etc.) then this code will do it.
Maybe useful for building a widget in a sidebar, that shows the current page and its siblings?
<?php
$items = $page->children()->listed()->filterby('Template', 'page');
$parentPage = $page->parent();
if ($items->isNotEmpty() || $parentPage ):
if ($parentPage): ?>
<a class="ds-menu-item menu-parent" href="<?= $page->parent()->url() ?>"><?= html($page->parent()->title()) ?></a>
<?php if (count($items) === 0): $items = $page->parent()->children(); endif; ?>
<?php else: ?>
<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: ?>
<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>