HUGO

Front matter for nested menu does not work

I’m trying to create a website with a nested menu/sub menu. I created some pages:

test/content/topone/index.md front matter:

---
Title: "Title for first top page"
Date: "2021-02-20T18:05:19+01:00"
Menu:
  main:
    title: "Title within menu for first top page"
    Name: "Name for First Top page"
    LinkTitle: "Link Title for first top page"
    Weight: 100
    Identifier: "topone"
---

test/content/topone/subone.md front matter:

---
Title: "title for first sub page of first top page"
Menu:
  main:
    title: "Title within menu for first sub of first top"
    Name: "name for Fist Sub page of first top page"
    LinkTitle: "Link title for first sub page of first top page"
    Weight: 120
    Identifier: "subonetopone"
    Parent: "topone"
---

as well as an according template file test/themes/test/layouts/partials/header.html:

<a href="{{ .Site.BaseURL }}" title="Go to home page">Homepage</a>
<h1>{{ .Title }}</h1>
<nav>
  <ul>
    {{ $currentPage := . }}
    {{ range .Site.Menus.main }}
      {{ if .HasChildren }}
        <li {{ if $currentPage.HasMenuCurrent "main" . }} class="active" {{ end }}>
          {{ $title_text := print .Title | safeHTML }}
          <a href="{{ .URL }}" title="{{ $title_text }}">
            {{ $link_text := print .Name | safeHTML }}
            Has-sub: {{ $link_text }}
          </a>
          <ul>
            {{ range .Children }}
              <li {{ if $currentPage.IsMenuCurrent "main" . }} class="active" {{ end }}>
                {{ $title_text := print .Title | safeHTML }}
                <a href="{{ .URL }}" title="{{ $title_text }}">
                  {{ $link_text := print .Name | safeHTML }}
                  is-sub: {{ $link_text }}
                </a>
              </li>
            {{ end }}
          </ul>
        </li>
      {{ else }}
        <li {{ if $currentPage.IsMenuCurrent "main" . }} class="active" {{ end }}>
          {{ $title_text := print .Title | safeHTML }}
          <a href="{{ .URL }}" title="{{ $title_text }}">
            {{ $link_text := print .Name | safeHTML }}
            no-sub: {{ $link_text }}
          </a>
        </li>
      {{ end }}
    {{ end }}
  </ul>
</nav>

But .HasChildren returns false for index.md and no menu entry for subone.md is generated. You can find the example in a repository: GitHub - sjjh/test
What am I doing wrong? :confused: Thx for any help!

Could the weird uppercase syntax be the reason? The documentation uses only lowercase frontmatter parameters.

no, unfortunately apparently not (I changed the files in the repo accordingly).

Well, then let’s go through some common issues :slight_smile:

  • the name parameter is an identificator for your menu item. remove spaces and special characters from it.
  • you have identifier and name as parameters. both might have the same meaning. so if you check for parent “topone” it might find “name for first top page” and break. remove either name or identifier and fix parent to the remaining one (still without spaces)
content
├── topone
│   ├── index.md <-- should be _index.md
│   ├── subone.md
│   └── subtwo.md
├── toptwo
│   ├── index.md <-- should be _index.md
│   ├── subone.md
│   └── subtwo.md
└── _index.md

Tried that without any luck.

I thought that identifier takes over the role of name if both are present (and I thought about using name in my menu template). Nevertheless I tried with removing name, only using identifier without luck.

Thanks, that worked! I (apparently wrongly) assumed, that the (only) difference between index.md and _index.md is that the former is a single page and the later a list page (which can contain snippets of content from sub pages), but that both types could have sub pages in a nested menu.
So if I understand it correctly now, only list pages can have sub pages at all.
@davidsneighbour thanks for you help as well.

Edit: in the test project it now works, but in the “real” one not :frowning: Will need to investigate further…
Edit2: Did find the mistake (intending error in front matter). solved. :slight_smile:

Regarding the related documentation PR

Only list pages can have child pages.

This is not true. In your case, by placing an index.md file in the directory, you told Hugo that the directory was a leaf bundle, which means that the other markdown files did not exist as pages.

I see – that connection wasn’t clear to me. Do you have an idea for a better rephrasing of the docs, to make it clearer?

The issue you ran into with menus was a side effect of creating a leaf bundle (index.md) instead of a branch bundle (_index.md). Both of these are page bundles, which is covered pretty well here:

Indeed there it says for leaf bundles

Does not allow nesting of more bundles under it

Which I both forgot about and didn’t understand that “more bundles” includes arbitrary named[1] child pages as well. So how about adding a sentence “Remember, that leaf bundles cannot contain nested pages.” to the menu documentation for added clarity?

[1] as the page bundle documenation only mentions index.mdand _index.md explicitly.

I really appreciate your effort to improve the documentation, but I think verbiage related to leaf bundles belongs with the page bundle documentation.

In your case, you added a menu item to a markdown file that was not rendered. Any markdown file other than index.html in a leaf bundle is a page resource, and will not be rendered as a page. If it is not rendered as a page, everything in the file (including front matter) is ignored.

The same thing would have happened in a branch bundle if one of the markdown files was flagged with draft = true in front matter.

I see, fair enough. :slight_smile: And I do agree with you. Let’s then just hope, that the next person is smarter than me and/or finds this thread. :slight_smile:
Thanks again for your (very quick!) help, much appreciated.

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