10th+ menu item not rendering (bug?)

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 .

2 Likes

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

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.