# Show active menu items when using Structured Fields

**URL:** <https://forum.getkirby.com/t/show-active-menu-items-when-using-structured-fields/26077>\
**Category:** Questions\
**Tags:** v3\
**Created:** [July 26, 2022, 12:44pm UTC](https://forum.getkirby.com/t/show-active-menu-items-when-using-structured-fields/26077 "2022-07-26T12:44:38Z")\
**Posts on this page:** 18\
**Page:** 1

<div class="post-metadata">

**Author:** ![LordCanis](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/lordcanis/32/16516_2.png) [@LordCanis](https://forum.getkirby.com/u/LordCanis)\
**Post date:** [July 26, 2022, 12:44pm UTC](https://forum.getkirby.com/t/show-active-menu-items-when-using-structured-fields/26077/1 "2022-07-26T12:44:38Z")

</div>

Hi,

I defined my menu using a structured field.  
I want to highlight the active link.

```auto
<?php
  $items = $site->menu_items()->toStructure();
  foreach ($items as $item): ?>
  <li>
    <a <?php e($item->isOpen(), ' class="active-link"') ?> href="<?= $site->url() ?><?= $item->item_link() ?>">
      <?= $item->item_name() ?>
    </a>
  </li>
<?php endforeach ?>

```

I think the “isOpen” only works with “\<?php foreach ($site-\>children()-\>listed() as $item): ?\>” right?  
How is it possible to highlight an active link when i use a structured field?

Thank you for yor help.

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [July 26, 2022, 3:57pm UTC](https://forum.getkirby.com/t/show-active-menu-items-when-using-structured-fields/26077/2 "2022-07-26T15:57:27Z")

</div>

What do your menu items actually link to? Pages?

---

<div class="post-metadata">

**Author:** ![LordCanis](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/lordcanis/32/16516_2.png) [@LordCanis](https://forum.getkirby.com/u/LordCanis)\
**Post date:** [July 26, 2022, 5:54pm UTC](https://forum.getkirby.com/t/show-active-menu-items-when-using-structured-fields/26077/3 "2022-07-26T17:54:17Z")

</div>

Hi Sonja,

some items link to pages and some items are anchors.

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [July 26, 2022, 6:08pm UTC](https://forum.getkirby.com/t/show-active-menu-items-when-using-structured-fields/26077/4 "2022-07-26T18:08:19Z")

</div>

Well, unfortunately you didn’t post your structure field, but for the actual page links, you can convert the field value to page with `toPage()`. For this object you can then test if the item is open.

If the value is just a string, it really depend to which page they actually link. Is it just a URL in that case?

Otherwise, you would have to check the URL to determine which link is active.

> **[Url::current()](https://getkirby.com/docs/reference/objects/http/url/current)**
>
> Returns the current url with all bells and whistles

---

<div class="post-metadata">

**Author:** ![LordCanis](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/lordcanis/32/16516_2.png) [@LordCanis](https://forum.getkirby.com/u/LordCanis)\
**Post date:** [July 27, 2022, 11:44am UTC](https://forum.getkirby.com/t/show-active-menu-items-when-using-structured-fields/26077/5 "2022-07-27T11:44:41Z")

</div>

My structure field:

```auto
menu_items:
  label: Menü-Punkte
  type: structure
  fields:
    item_name:
      label: Beschriftung
      type: text
    item_link:
      label: link
      type: text

```

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [July 27, 2022, 6:02pm UTC](https://forum.getkirby.com/t/show-active-menu-items-when-using-structured-fields/26077/6 "2022-07-27T18:02:09Z")

</div>

Ok, since you are not storing pages but only text or urls, you have to check if the current urls is the same as your item link.

---

<div class="post-metadata">

**Author:** ![bigskillet](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/bigskillet/32/14377_2.png) [@bigskillet](https://forum.getkirby.com/u/bigskillet)\
**Post date:** [January 29, 2024, 7:23pm UTC](https://forum.getkirby.com/t/show-active-menu-items-when-using-structured-fields/26077/7 "2024-01-29T19:23:09Z")

</div>

Can you please provide an example of how to use the `Url::current()` object? I’m not having much luck with it.

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [January 29, 2024, 7:27pm UTC](https://forum.getkirby.com/t/show-active-menu-items-when-using-structured-fields/26077/8 "2024-01-29T19:27:52Z")

</div>

> [@bigskillet](#):
>
> the `Url::current()` object?

I’m afraid I don’t quite understand the question. `Url::current()` is a method (not an object) that is just used like that, no params, no nothing., so you just echo it (or use it for comparisions):

```auto
<?= Url::current() ?>

```

and will return the current Url (with query strings or params etc. if applicable)

---

<div class="post-metadata">

**Author:** ![bigskillet](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/bigskillet/32/14377_2.png) [@bigskillet](https://forum.getkirby.com/u/bigskillet)\
**Post date:** [January 29, 2024, 7:47pm UTC](https://forum.getkirby.com/t/show-active-menu-items-when-using-structured-fields/26077/9 "2024-01-29T19:47:25Z")

</div>

I see… the below works similar to `isActive()`, but I need it to work like `isOpen()`:

`<?php e(Url::current() == $item->link()->toUrl(), 'aria-current="page"') ?>`

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [January 29, 2024, 7:54pm UTC](https://forum.getkirby.com/t/show-active-menu-items-when-using-structured-fields/26077/10 "2024-01-29T19:54:37Z")

</div>

Could you please provide more context. The original TO asked about structure field items… What would be your equivalent to a parent page in this context? what is `$item`?

---

<div class="post-metadata">

**Author:** ![bigskillet](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/bigskillet/32/14377_2.png) [@bigskillet](https://forum.getkirby.com/u/bigskillet)\
**Post date:** [January 29, 2024, 8:01pm UTC](https://forum.getkirby.com/t/show-active-menu-items-when-using-structured-fields/26077/11 "2024-01-29T20:01:17Z")

</div>

I’m trying to rebuild the [starterkit](https://github.com/getkirby/starterkit/blob/main/site/snippets/header.php#L81) menu using structured mixed links as shown on the [menu builder](https://getkirby.com/docs/cookbook/templating/menu-builder) page.

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [January 29, 2024, 8:10pm UTC](https://forum.getkirby.com/t/show-active-menu-items-when-using-structured-fields/26077/12 "2024-01-29T20:10:19Z")

</div>

With a nested structure field? Which example exactly? Or please post your code…

---

<div class="post-metadata">

**Author:** ![bigskillet](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/bigskillet/32/14377_2.png) [@bigskillet](https://forum.getkirby.com/u/bigskillet)\
**Post date:** [January 29, 2024, 8:18pm UTC](https://forum.getkirby.com/t/show-active-menu-items-when-using-structured-fields/26077/13 "2024-01-29T20:18:03Z")

</div>

One level, not nested. The code below works fine when on the actual page, but the active state does not remain when drilling down into a section. For example,` /works` vs `/works?filter=Residential`

```auto
<?php $items = $site->headerMenu()->toStructure(); ?>
  <?php if ($items->isNotEmpty()) : ?>
    <nav class="menu">
      <ul role="list" class="flex gap-x-6 md:gap-x-9 lg:gap-x-11">
        <?php foreach ($items as $item) : ?>
          <li>
            <a href="<?= $item->link()->toUrl() ?>" <?php e(Url::current() == $item->link()->toUrl(), 'aria-current="page"') ?>>
              <?= $item->linkTitle()->or($item->link()->html()) ?>
            </a>
          </li>
        <?php endforeach ?>
      </ul>
    </nav>
  <?php endif ?>

```

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [January 29, 2024, 8:37pm UTC](https://forum.getkirby.com/t/show-active-menu-items-when-using-structured-fields/26077/14 "2024-01-29T20:37:56Z")

</div>

> [@bigskillet](#):
>
> ut the active state does not remain when drilling down into a section

Really sorry, maybe we have a wording problem here. Your example uses a url query string, that cannot possibly work when you compare a nomal page link with `Url::current()` which returns exactly a Url **with** the query string included.

Don’t think there is a method for that, you either have to construct it from the uri object, or use

```auto
$_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']

```

Not sure what you mean by “drilling down into a section”.

If you are using only pages as links, you could compare to the current `$page->url()`, if you are only dealing with pages, you could also convert the stored UUID to a page object, which would allow you to use `$page->isActive()` and `isOpen`

Maybe I should extend the recipe a bit…

---

<div class="post-metadata">

**Author:** ![bigskillet](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/bigskillet/32/14377_2.png) [@bigskillet](https://forum.getkirby.com/u/bigskillet)\
**Post date:** [January 29, 2024, 8:52pm UTC](https://forum.getkirby.com/t/show-active-menu-items-when-using-structured-fields/26077/15 "2024-01-29T20:52:31Z")

</div>

I’m using mixed links.

Using `isOpen()` on a [normal menu](https://getkirby.com/docs/cookbook/templating/menus) using pages will set the link active no matter what level you’re at. For example:

```auto
/projects
/projects/project-name

```

…but with a [mixed link structured menu](https://getkirby.com/docs/cookbook/templating/menu-builder), there’s no way to do it. Using `Url::current()` only sets the link active at the top level `/projects`, similar to how `isActive()` works on normal menus.

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [January 29, 2024, 9:35pm UTC](https://forum.getkirby.com/t/show-active-menu-items-when-using-structured-fields/26077/16 "2024-01-29T21:35:50Z")

</div>

```auto
<?php $items = $site->headerMenu()->toStructure(); ?>
  <?php if ($items->isNotEmpty()) : ?>
    <nav class="menu">
      <ul role="list" class="flex gap-x-6 md:gap-x-9 lg:gap-x-11">
        <?php foreach ($items as $item) : ?>
          <li>
            <a <?= ($p = $item->link()->toPage()) && $p->isOpen() ? 'aria-current="page"' : '' ?> href="<?= $item->link()->toUrl() ?>">
              <?= $item->linkTitle()->or($item->link()->html()) ?>
            </a>
          </li>
        <?php endforeach ?>
      </ul>
    </nav>
  <?php endif ?>

```

---

<div class="post-metadata">

**Author:** ![bigskillet](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/bigskillet/32/14377_2.png) [@bigskillet](https://forum.getkirby.com/u/bigskillet)\
**Post date:** [January 29, 2024, 9:44pm UTC](https://forum.getkirby.com/t/show-active-menu-items-when-using-structured-fields/26077/17 "2024-01-29T21:44:51Z")

</div>

That works, thank you!

Where is the `$p` coming from? It’s an abbreviation for the [$page object](https://getkirby.com/docs/reference/objects/cms/page)?

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [January 29, 2024, 10:29pm UTC](https://forum.getkirby.com/t/show-active-menu-items-when-using-structured-fields/26077/18 "2024-01-29T22:29:09Z")

</div>

> [@bigskillet](#):
>
> `$p` coming from

It’s a variable I define inline here : `$p = $item->link()->toPage()`, checking if this **is** a page object.
