Highlight Section's Menu Item when in any page of that section

I am making navigation for my site using .Site.Menus

Here are relevant code snippets :-


# config.toml

[[menu.main]]
name = "Blog"
url = "/blog/"
weight = 10

[[menu.main]]
name = "About"
url = "/about/"
weight = 20

I took following template code from Hugo docs on Menus and added to my site.

<!-- layouts/partials/menu.html -->

<ul id="sidebar">
	{{ $currentNode := . }}
	{{ range .Site.Menus.main }}
	<li class="{{if $currentNode.IsMenuCurrent}}selected{{end}}">
		<a href="{{.Url}}">{{.Name}}</a>
	</li>
	{{ end}}
</ul>

Now, the problem is when,

Navigating to           | Menu item 'blog' is
----------------------- | -------------------
/blog/                  |  selected
/blog/hello-world/      |  -
/blog/2015/03/xyz       |  -

I want menu item blog to be selected, when any page of ‘blog’ section is rendered.

1 Like

If you have a separate single template for your blogs, you can make that top one active since it will only be rendered for them.

If you’re using the same template for multiple types, you can test the section and highlight based on that.

Me too!

See:

Note, this is currently possible by defining what menu parent each blog post belongs to in front matter, then use both IsMenuCurrent and HasMenuCurrent to do the active styling.

If you use archetypes to create new blog posts, this is trivial.

But for me, it seemed to be a little bit too much work, esp. if you like to juggle the posts around a bit by doing plain move.

The above COULD MAYBE be done by some Go template constructs, but that would look very hackish.

And that might be the reason why the PR above isn’t merged - it kinda looks and is a little bit hackish.

But it solves 70% of all menu use cases right out of the box, and even more with some manual twiddling.

So, it is a useful hack. I use it on several of my sites.

@michael_henderson @bjornerik Thanks for suggestions.

After trying out different approaches, I settled for using template based approach.
Here’s a simple example of what it did.

<!-- layouts/partials/menu.html -->

<ul id="navbar">
	<li class='{{if eq .Url "/"}}selected {{end}}'>
		<a href="/">Home</a>
	</li>
	<li class='{{if eq .Url "/blog/"}}selected {{end}}{{if eq .Section "blog"}}selected {{end}}'>
		<a href="/blog/">Blog</a>
	</li>
	<li class='{{if .IsPage}}{{if eq .RelPermalink "/about/"}}selected {{end}}{{end}}'>
		<a href="/about/">About</a>
	</li>
</ul>

Here, /about is part of section root with permalink /:filename/. Thus, It is a page and doesn’t have .Url variable. Better Explained here

Code above looks little hackish But It works. I would have abstracted those if conditions, if template had support for shortcodes.

2 Likes