89 lines
3 KiB
Markdown
89 lines
3 KiB
Markdown
---
|
|
title: "Highlighting the active menu item in Hugo"
|
|
date: 2023-07-03T22:19:00-04:00
|
|
topics: ['hugo','web design']
|
|
---
|
|
|
|
I've recently been developing sites for some family/friends.
|
|
I had one person request highlighting the currently selected menu item.
|
|
I had built a custom theme which used a navbear defined in the site wide `hugo.toml`.
|
|
There were a few different solutions but I wanted to highlight the solution I ended up using for my use case.
|
|
A dummy of my site directory set up is:
|
|
|
|
```
|
|
content
|
|
|-- section1
|
|
|--_index.md
|
|
|--section1Post.md
|
|
|-- section2
|
|
|--_index.md
|
|
|--section2Post.md
|
|
|-- section3
|
|
|--_index.md
|
|
```
|
|
|
|
In my header partial I created a menu by looping over the entries in `[[menu.main]]` defined in the `hugo.toml`.
|
|
It's important here to end the `url` with a `/`.
|
|
Hugo adds an ending `/`, to the urls of the pages that it creates.
|
|
While this might not be necessary to make the hyperlink work, it will be necessary to get the highlighting correct.
|
|
The definition of the menu looks like:
|
|
|
|
```
|
|
[menu]
|
|
[[menu.main]]
|
|
name= "section1"
|
|
url= "/section1/"
|
|
weight= "1"
|
|
[[menu.main]]
|
|
name= "section2"
|
|
url= "/section2/"
|
|
weight= "2"
|
|
[[menu.main]]
|
|
name= "section3"
|
|
url= "/section3/"
|
|
weight= "3"
|
|
```
|
|
|
|
The original header partial is pretty simple.
|
|
I just loop over the range `.Site.Menus.main` and insert a `<div class="item">` which is my div class for a navbar menu item.
|
|
I populate the text and link from the variables associated with the main menu item.
|
|
This is all wrapped within a `<nav>` element with other items and stylings that create the overall navigation menu.
|
|
The loop for insertion of menu items is below:
|
|
|
|
```
|
|
{{ range .Site.Menus.main }}
|
|
<div class="item">
|
|
<a href="{{ .URL }}">
|
|
{{ $text := print .Name | safeHTML }}
|
|
{{ $text }}
|
|
</a>
|
|
</div>
|
|
{{ end }}
|
|
```
|
|
|
|
As I mentioned before, there were a few different solutions but the one I went with was to save the menu item url and the current page url into two separate variables.
|
|
**I can then compare these to determine whether the current page corresponds to a menu item and if so I change the class of the div from a normal menu item to the activated menu item class.**
|
|
This concept can be seen in action in the following code snippet:
|
|
|
|
```
|
|
{{ $currentPage := . }}
|
|
{{ range .Site.Menus.main }}
|
|
{{ $menu_item_url := .URL | relLangURL }}
|
|
{{ $page_url:= $currentPage.RelPermalink | relLangURL }}
|
|
<div
|
|
{{ if eq $menu_item_url $page_url }}
|
|
class="active-item"
|
|
{{else}}
|
|
class="item"
|
|
{{ end }}
|
|
>
|
|
<a href="{{ .URL }}">
|
|
{{ $text := print .Name | safeHTML }}
|
|
{{ $text }}
|
|
</a>
|
|
</div>
|
|
{{ end }}
|
|
```
|
|
|
|
I hope that this is helpful to somebody else as it took me a decent amount of time to try the different recommended methods before I found this one.
|
|
As always shoot me an email if you have any thoughts or comments!
|