I am trying to implement a global switch for the main navigation. This needs to be able to switch between different versions.
I have menus defined for each version of the documentation (v1, v2). Parameters define the menu names and the default menu.
config.toml
[params]
menuNames = ["v1", "v2"]
menuname = "v2"
[[menu.v1]]
name = "Getting Started"
identifier = "getting-started"
weight = 1000
[[menu.v2]]
name = "Getting Started"
identifier = "getting-started"
weight = 1000
content
/content/docs/v1/getting-started/introduction.md
+++
title = "Introduction"
linktitle = "Introduction"
weight = 10
menuname = "v1"
[menu.v1]
parent = "getting-started"
+++
intro version 1
/content/docs/v2/getting-started/introduction.md
+++
title = "Introduction"
linktitle = "Introduction"
weight = 10
menuname = "v2"
[menu.v1]
parent = "getting-started"
+++
intro version 2
I having problems getting the default navigation.html partial template to work. It looks like this
<ul>
{{ $menuname := $.Param "menuname" }}
{{ $.Scratch.Add "menuname" $menuname }}
{{ $.Scratch.Add "menu" .Site.Menus.v1 }}
{{ if eq ($.Scratch.Get "menuname") "v2" }}
{{ $.Scratch.Set "menu" .Site.Menus.v2 }}
{{ end }}
{{ $currentNode := . }}{{ range ($.Scratch.Get "menu") }}{{ if .HasChildren }}
<li{{ if $currentNode.HasMenuCurrent ($.Scratch.Get "menuname") . }} class="is-active"{{ end }}>{{ .Name }}
<ul>{{ range .Children }}
<li{{ if $currentNode.IsMenuCurrent ($.Scratch.Get "menuname") . }} class="is-active"{{ end }}><a href="{{ .URL }}">{{ .Name }}</a></li>{{ end }}
</ul>
</li>{{ else }}
<li{{ if $currentNode.HasMenuCurrent ($.Scratch.Get "menuname") . }} class="is-active"{{ end }}>{{ .Name }}</li>{{ end }}
{{ end }}
</ul>
I am trying to get the $menuname from either the .Page or .Site {{ $menuname := $.Param "menuname" }}
and getting error <$.Param>: Param is not a field of struct type *hugolib.Page in theme/partials/navigation.html
Then I want to select the menu based on the name, and add it to .Scratch (variables didn’t work). Finally render the menu items by iterating the selected menu.
Apart from the wrong usage of the $.Param function, would this approach work?
I did manage to get it to work by repeating the range
portion for each distinct menu, but that seemed like a lot of repetition.
I am probably missing an simple way of getting the range
command to work with a dynamically selected menu like
{{ range .Site.Menus.{{$.Param "menuname"}} }}
which doesn’t work.
Any advice appreciated.
Using the .Scratch for the menuname
as below works
<ul>
{{ $.Scratch.Add "menuname" .Site.Params.menuname }}
{{ if isset .Params "menuname" }}
{{ $.Scratch.Set "menuname" .Params.menuname }}
{{ end }}
{{ $.Scratch.Add "menu" .Site.Menus.v1 }}
{{ if eq ($.Scratch.Get "menuname") "v2" }}
{{ $.Scratch.Set "menu" .Site.Menus.v2 }}
{{ end }}
{{ $currentNode := . }}{{ range ($.Scratch.Get "menu") }}{{ if .HasChildren }}
<li{{ if $currentNode.HasMenuCurrent ($.Scratch.Get "menuname") . }} class="is-active"{{ end }}>{{ .Name }}
<ul>{{ range .Children }}
<li{{ if $currentNode.IsMenuCurrent ($.Scratch.Get "menuname") . }} class="is-active"{{ end }}><a href="{{ .URL }}">{{ .Name }}</a></li>{{ end }}
</ul>
</li>{{ else }}
<li{{ if $currentNode.HasMenuCurrent ($.Scratch.Get "menuname") . }} class="is-active"{{ end }}>{{ .Name }}</li>{{ end }}
{{ end }}</ul>
However that does not seem very elegant. Am I missing an alternative?