My menu code is below. All my nested sections are inside the blog section e.g content/blog/news. I am using pageref for the menu link to show and style active menus differently. The menu has a blog item and the second is a sections item with all the nested sections as its children.
I am facing an issue, however, where the blog menu entry appears active when any of the nested items are selected (with both IsMenuCurrent and HasMenuCurrent. I replaced pageref with url for the blog menu item and it works, but I lose the active class for the item when I navigate to the blog section. Is there a way to exclude the active class for the blog section when I click on the nested section, but retain it only when I navigate to the blog section itself?
<ul class="main-menu">
{{- $currentPage := . }}
{{- range site.Menus.main }}
{{- if .HasChildren }}
<li class="menu-item">
<a class="menu-link" href="#">{{ .Name }}<span>▾</span></a>
<ul class="submenu">
{{- range .Children }}
<li class="submenu-item">
<a href="{{ .URL }}" {{- if or ($currentPage.IsMenuCurrent "main" .) ($currentPage.HasMenuCurrent "main" .) }} class="submenu-link active" aria-current="page" {{ end }}>{{ .Name }}</a>
</li>
{{- end }}
</ul>
</li>
{{- else }}
<li class="menu-item">
<a href="{{ .URL }}" {{- if or ($currentPage.IsMenuCurrent "main" .) ($currentPage.HasMenuCurrent "main" .) }} class="menu-link active" aria-current="page" {{ end }}>{{ .Name }}</a>
</li>
{{- end }}
{{- end }}
</ul>
I use it to target single pages within a nested section, where the menu item is active when a post in that section is opened. So, that means there is no workaround for this?
[[menu.main]]
name = 'Posts'
pageRef = '/posts'
[[menu.main]]
name = 'Foo'
pageRef = '/posts/foo'
parent = 'Posts'
[[menu.main]]
name = 'Bar'
pageRef = '/posts/foo/bar'
parent = 'Foo'
[[menu.main]]
name = 'Test'
pageRef = '/posts/foo/bar/test'
parent = 'Bar'
The HasMenuCurrent method returns true for all but the current entry when visiting /posts/foo/bar/test. This is useful for setting aria-current="true" on parent items. For example, when visiting /posts/foo/bar/test:
My menu structure is like this (in config/_default/menu.toml)
[[main]]
name = "Blog"
pageref = "/blog"
weight = 1
[[main]]
name = "sections"
identifier = "sections"
weight = 2
[[main]]
name = "news"
pageref = "/blog/news"
weight = 1
parent = "sections"
<!-- All other nested sections go here in the same format -->
So, if I understand your solution, I need to add a class entry to the blog menu? How would the conditions look after modifying for example? I was thinking of editing my CSS to exclude the class, but I am curious how your suggestion would look like.
Edit: The class returns an empty string. But using pre with safeHTMLAttr inserts the content as expected.
Edit 2: Somehow, IsMenuCurrent works with pages in the current menu. I could swear when I first tried Hugo, it didn’t work hence why I used HasMenuCurrent. Removing the latter makes the menu’s active class to work as expected. So, that’s out of the way.
Thanks! I have been using pre and appending safeHTMLAttr to it in the past. This is much better and I would recommend it goes in that section of the docs.