HasMenuCurrent working as documented?

Hi everybody,

While working on the navigation for a documentation theme, I may have found a glitch in the function HasMenuCurrent. It generates the class .has-active in my templates. This class also appears on list pages with the class .is-active (generated by IsMenuCurrent), where it should not be, as the documentation states, if I understand correctly.

The source for documentation is available here: https://github.com/bowman2001/perplexdoc. I’ve managed to correct the glitch with a CSS workaround and the navigation bar is working as it is supposed to. But you can see is-active and has-active together in the code of the published site https://perplex.desider.at/doc.

Thanks,
Georg

I didn’t implement this, originally, but we agree that both IsMenuCurrent and HasMenuCurrent can return true for a given page?

Yes, but I haven’t expected both functions to return true for the same page. For a given menu, either the page is the current one (.IsMenuCurrent) or it is its parent (or parents parent …) (.HasMenuCurrent). Maybe I don’t understand the whole purpose of these functions, but this is how I understand the docs.

I just did some experimentation, and IsMenuCurrent works for me as documented, but HasMenuCurrent does not.

If I’m on a page /foo/ and that’s a list page with posts under it, HasMenuCurrent is true even though it’s the page directly linked by the menu item, contrary to the documentation. If /foo/ is a regular page (not a list page) then HasMenuCurrent is false (while IsMenuCurrent is true as expected).

Thanks for your clarification @i40west. I can also watch this behavior only for list pages.

@i40west and @Georg

How have you defined the menu? In front matter, or site configuration?

If you have defined it in site configuration, do you specify the url property for internal links, or the pageRef property instead?

My sidebar menu entries are generated from front-matter only like this:

---
author: Georg Makowski
date: "2021-09-07T21:33:03+02:00"
description: What's special about _Perplex_?
featImg: hal-gatewood-tZc3vjPCk-Q-unsplash.jpg
menu:
  doc:
    identifier: layout
    name: Layout
    parent: intro
    pre: dashboard
subtitle: false
title: Layout
weight: 5
---

Thanks for looking into this @jmooring.

@jmooring In the project I was testing with, I define the menu entries in front matter, with url. So I have a list page with this in front matter:

[menu]
[menu.nav]
identifier = "posts"
name = "Posts"
url = "/posts/"
weight = 4

and a regular page that has:

[menu]
[menu.nav]
identifier = "stuff"
name = "Stuff"
url = "/stuff/"
weight = 6

and do this:

{{- if .Site.Menus.nav }}
    <nav>
        {{ $currentPage := . -}}
        {{- range .Site.Menus.nav -}}
        <a class="{{ if or ($currentPage.IsMenuCurrent "nav" .) ($currentPage.HasMenuCurrent "nav" .) }}active{{end}}" href="{{ .URL }}">
            {{- .Name -}}
        </a>
        {{ end -}}
    </nav>
{{ end }}

This behaves as I intended because I’m using both IsMenuCurrent and HasMenuCurrent interchangeably and I wanted that behavior. But, in this setup, if I’m on /posts/ then both IsMenuCurrent and HasMenuCurrent are true. On /stuff/, which is not a list page, only IsMenuCurrent is true.

1 Like

OK, thanks, that all looks fine.

Notes:

  • There’s no need to specify identifier if name is not duplicated within the menu
  • When defining a menu entry in front matter you can omit the url
2 Likes

My partial for the menu list is a little bit longer, here’s the link to the repo: perplexdoc/menu-list.html at main · bowman2001/perplexdoc · GitHub

Thanks for the tip. I removed all identifiers for single pages. But my navigation still needs explicitly set identifiers for list pages, which are menu parents. They create unique checkboxes for opening the sub-menues.

If the variable .Identifier would be auto-generated from the .Name in case there is no identifier given in the parameters, I could omit most of them, too.

Back to the original question:

Is .HasMenuCurrent working as documented?

The answer is no, and the documentation correctly states how it should behave.

HasMenuCurrent should return false when .IsMenuCurrent is true.

Here’s one example of why this is a problem:

{{ $ariaCurrent := "" }}
{{ if $page.IsMenuCurrent $menu $item }}
  {{ $ariaCurrent = "page" }}
{{ end }}
{{ if $page.HasMenuCurrent $menu $item }}
  {{ $ariaCurrent = "true" }}
{{ end }}

So when I visit a list page, the aria-current attribute will be incorrect.

I can work around that by reversing the sequence, or with an if-else, but I shouldn’t have to.

1 Like

The .HasMenuCurrent method behaved as documented with v0.85.0 and earlier. We broke something in v0.86.0.

Git bisect says that d831d2f is the first bad commit.

See https://github.com/gohugoio/hugo/issues/9846.

1 Like

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.