I’m not sure if I’m missing something, or this is a bug (I have not yet tested previous versions of Hugo to check if this is a regression). I figured I’d check here before opening an issue on GitHub.
Here’s the build of Hugo I’m currently running (latest as of this date)
$ hugo version
hugo v0.84.1+extended darwin/amd64 BuildDate=unknown
If I create a menu with more than 10 items in my config.yaml (have not tested other formats e.g. toml yet) as follows.
menu:
main:
- name: One
url: /one
weight: 1
- name: Two
url: /two
weight: 2
- name: Three
url: /three
weight: 3
# ...
- name: Nine
url: /nine
weight: 9
# the following do not show
- name: Ten
url: /ten
weight: 10
- name: Eleven
url: /eleven
weight: 11
When executing the following template, Hugo does not render anything (starts at 0, so this is attempting to render the 10th and 11th element in the menu).
{{ index .Site.Menus.main 9 }}
{{ index .Site.Menus.main 10 }}
On the other hand, this renders the menu map just fine.
{{ index .Site.Menus.main 8 }}
This does not look like intended behaviour to me, but perhaps I’m unaware of some limitations within Hugo. Any help/insight would be appreciated.
I am unable to reproduce this problem. Please share your repository so that we can dig a little deeper.
Managed to track down the issue. Again, not sure if this is a bug or expected behaviour, but it sure was non-obvious (and as far as I can tell, not documented).
If two or more menu-items have the same name, Hugo will only render the first menu item. In other words, the following config does not work as I expected it to.
menus:
main:
- name: One
url: /one
weight: 1
- name: One # <- same name
url: /two
weight: 2
- name: Three
url: /three
weight: 3
It seems like Hugo strips out the menu item from the array based on the value of name, even if it has a different url or pre value.
While I came across this issue during development (used the same name as a placeholder), I could see this being an edge-case where someone needs two menu-items with the same name but different links/styles (perhaps using the pre value to add a CSS class). The fact that it is an array and not a map makes this issue much less obvious.
Well of course. That is how it is supposed to be. Each menu item needs to have a unique Name.
If Hugo didn’t ignore menu items with the same Name after the first occurence, then it would most likely encounter a Race Condition as it wouldn’t know which one of the two identical menu items to render.
See https://gohugo.io/variables/menus/#menu-entry-variables.
.Identifier
string Value of the identifier key if set for the menu entry. This value must be unique for each menu entry. It is necessary to set a unique identifier manually if two or more menu entries have the same .Name .
I guess what was confusing was the fact that this was an array, not a map. Had this been a map, it would be immediately obvious that this behaviour was not supported. Would be a behaviour worth documenting.
Let me correct my post above.
If a menu item shares the same .Name with another one, then each one needs a unique .Identifier as @jmooring reminded us above.
Aha! missed that. Thanks for this @jmooring