Active menu page from structure field

I have a site menu that is build with a structure because the client wants to be able to manage it themself and it can contain pages from the site, external links and pdf documents. Unfortunately because of this I can’t use $page->isActive() to get the active page an active class.

Not only the parent pages itself should get the active class but also the parent pages if you’re on a child page. I solved this by using this php:

$protocol = stripos($_SERVER['SERVER_PROTOCOL'],'https') === 0 ? 'https://' : 'http://';
$actual_link = "$protocol$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]"; 
$parent_link = dirname("$actual_link");

And I add an active class to pages like this:

<?php foreach ($site->pagesInMenu()->toStructure() as $menuItem): ?>
  <li <?php e($actual_link === $menuItem->menuItemURL()->toLinkObject()->url() || $parent_link === $menuItem->menuItemURL()->toLinkObject()->url() , ' class="active"') ?>> <a <?php if ($menuItem->newTab()->toBool() === true): ?> target='_blank' <?php endif ?> href="<?= $menuItem->menuItemURL()->toLinkObject()->url() ?>"><h3><?= $menuItem->menuItemText() ?></h3></a></li>
<?php endforeach ?>

Which works fine for all the pages and children of the pages but there is also a home menu item that always get’s the active class. Is there a way to exclude this within this solution? Or is there a better solution for this within Kirby?

Hi,
Have you seen the menu builder cookbook?

Best

Hi Jan, Thanks for your reply, yes I’ve looked through it but couldn’t really find a solution for the setup I’ve used. Great for using in a future project though!

Kirby 4 will come with a new link field that allows to select either a page, a file or enter an external URL. If you use the link field within the structure field, you will be able to differentiate between the different options and look up the page object.

You can already try it out in the Kirby 4 alpha, however we don‘t recommend using it in production yet.

If you need a solution in Kirby 3, I’d recommend to use a toggles field (with options page/file/external) together with a pages field, a files field and an url field (with the when option to show them conditionally based on the selected toggle value). Let me know if you need a code example.

Hi,
you can also use the pagename, I’m not sure if its the slug or the templatename, as a paramter for $page.

page('pagename')->isActive()

It is true if you are on this site. So you can take it from your loopobject and pass it to the pageobject.

Thanks for the response! I’m waiting for Kirby 4 since I need to have it live on production. For now I solved it by adding

&& $parent_link !== $site->url()

to the if statement. I know it doesn’t deserve a beauty award but it does the job for now :slight_smile: