Hello,
I’m new to Go and HUGO and was recently tasked to re-structure our documentation website. The main deal was to move our content to use 3-level menu entries organized within 3 different menus. I haven’t found all the directions I needed for this in HUGO’s documentation but was able to find my way by reading various discussions here. That’s my chance to contribute back my findings to the community and maybe help someone else in a similar situation.
Up till now we just weren’t using HUGO’s menus for real, but iterating directly from specific parameters set on the header of the pages. That looked interesting under a certain perspective because whenever we had a new page added we just didn’t needed to do anything other than fill the page’s header space accordingly. However, it limited certain things, like the implementation of nested menus.
I’ve started by following the directions on the main menus page and modified our config.yaml by adding a menu section and filling it with our three main menus as well as their “children” pages, something that resembles the following structure:
params:
...
menu:
"getting started":
- Name: "Overview"
Weight: 1
Identifier: "overview"
Url: "..."
- Name: "Requirements"
Weight: 2
Identifier: "requirements"
Url: "..."
- Name: "Installing"
Weight: 3
Identifier: "installing"
Url: "..."
- Name: "Windows"
Weight: 1
Identifier: "windows"
Parent: "installing"
Url: "..."
- Name: "Linux"
Weight: 2
Identifier: "linux"
Parent: "installing"
Url: "..."
- Name: "RedHat"
Weight: 1
Identifier: "redhat"
Parent: "linux"
Url: "..."
- Name: "Ubuntu"
Weight: 2
Identifier: "ubuntu"
Parent: "linux"
Url: "..."
"how to use":
- Name: "How it works"
Weight: 1
Identifier: "howitworks"
Url: "..."
- Name: "Navigation"
Weight: 2
Identifier: "navigation"
Url: "..."
- Name: "Settings"
Weight: 1
Identifier: "settings"
Url: "..."
"general reference":
- Name: "Performance"
Weight: 1
Identifier: "performance"
Url: "..."
- Name: "Supported systems"
Weight: 2
Identifier: "supported"
Url: "..."
- Name: "Troubleshooting"
Weight: 3
Identifier: "troubleshooting"
Url: "..."
That should do for our example here. Note however that the first time I tried to iterate over the set of menus (.Site.Menus) I found out they were sorted in alphabetical order, and not in the order I’ve listed them in the config.yaml. As it turns out, .Site.Menus is a dictionary of menus, in the form of:
type Menus map[string]*Menu
We can’t set weights for menus the same way we can for menu entries so what I ended up doing was defining my desired order in a new variable under the params section of config.yaml:
params:
...
menuOrder: ["getting started", "how to use", "general reference"]
and then I arranged our navigation.html to iterate over menuOrder (instead of .Sites.Menu), like this:
<div class="docs-nav">
<div class="docs-nav-blk">
{{ range $menu_name := .Site.Params.menuOrder }}
{{ $menu := index $.Site.Menus $menu_name }}
<strong class="docs-nav-title">{{ $menu_name }}</strong>
<ul class="docs-nav-list">
{{ $currentPage := . }}
{{ range $menu }}
{{ if .HasChildren }}
<li class="dropdown">
<a class="drop-trigger" href="{{.URL}}">
{{ .Pre }}
<span>{{ .Name }}</span>
</a>
<ul class="drop-menu">
{{ range .Children }}
{{ if .HasChildren }}
<li>
<a href="{{.URL}}">
{{ .Pre }}
<span>{{ .Name }}</span>
</a>
<ul>
{{ range .Children }}
<li><a href="{{.URL}}"> {{ .Name }} </a> </li>
{{ end }}
</ul>
{{else}}
<li>
<a href="{{.URL}}">
{{ .Pre }}
<span>{{ .Name }}</span>
</a>
{{end}}
</li>
{{end}}
</ul>
{{else}}
<li>
<a href="{{.URL}}">
{{ .Pre }}
<span>{{ .Name }}</span>
</a>
{{end}}
</li>
{{end}}
</ul>
{{end}}
</div>
</div>
Two observations:
-
I’ve spent a long time working on this tidbit:
{{ range $menu_name := .Site.Params.menuOrder }}
{{ menu := index .Site.Menus $menu_name }}
what happens here is that the map[string]*Menu structure
from .Site.Menus forces the string key to lowercase: you can write menu names however you want just make sure you type them in lower case in the .Params.menuOrder list used to sort the menus order.
-
The CSS I’ve used to display the sub-menus (“dropdown” and “drop-menu” classes) came from the Learn Enough CSS & Layout to Be Dangerous tutorial; I known very little about frontend programming and their work helped me understand how CSS behaves, so kudos to them!
-
I would have added more links to the external documentation I’ve discussed here but as a new user of this forum I can only post 2 links.
Here’s how the example I’ve used above looks like when I hover the mouse over the “Installing” entry: