HUGO

Automatic submenu in navbar

Good evening.

Recently I have been working on hugo ideas for practice and I have found a case I can’t find the solution for.

I am using a navbar for navigation in the website, and I have an option “proyectos” which is a dropdown and is defined in the config.toml like this:

themes\deltavtheme\layouts\partials\header.html
<div class="collapse navbar-collapse" id="navbarResponsive">
            {{ $currentPage := . }}
            <ul class="navbar-nav ml-auto">
                {{ range .Site.Menus.main }}
                {{ if .HasChildren }}
                <li class="nav-item dropdown no-bg">
                    <a class="nav-link dropdown-toggle" href="{{.URL}}" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true"
                       aria-expanded="false">
                        <span>{{ .Name }}</span>
                    </a>
                    <div class="dropdown-menu " aria-labelledby="navbarDropdown">
                        {{ range .Children }}
                        <a class="dropdown-item" href="{{.URL}}">{{.Name}}</a>
                        {{ end }}
                    </div>
                </li>
                {{else}}
                <li class="nav-item">
                    <a class="nav-link" href="{{.URL}}">
                        {{ .Pre }}
                        <span>{{ .Name }}</span>
                    </a>
                </li>
                {{end}}
                {{end}}
            </ul>
        </div>
config.toml
[menu]
    [[menu.main]]
        name = "Inicio"
        identifier = "inicio"
        url = "/"
        weight = 1

    [[menu.main]]
        name = "Proyectos"
        identifier = "proyectos"
        url = "/proyectos/"
        weight = 2
        [[menu.main]]
            name = "Proyecto 1"
            identifier = "proyecto 1"
            url = "/proyectos/proyecto1/index.html"
            weight = 1
            parent = "proyectos"
        [[menu.main]]
            name = "Proyecto 2"
            identifier = "proyecto 2"
            url = "/proyecto2/index.html"
            weight = 2
            parent = "proyectos"
        [[menu.main]]
            name = "Proyecto 3"
            identifier = "proyecto 3"
            url = "/proyecto3/index.html"
            weight = 3
            parent = "proyectos"

    [[menu.main]]
        name = "Wiki"
        identifier = "wiki"
        url = "/wiki/"
        weight = 3

    [[menu.main]]
        name = "Revista"
        identifier = "revista"
        url = "/revistas/"
        weight = 5

    [[menu.main]]
        name = "Nosotros"
        identifier = "nosotros"
        url = "/nosotros/index.html"
        weight = 6

The problem here is that I want the submenu part to be dinamyc and to be generated automatically based on the pages of “proyectos” so I don’t have to change the config file whith each new page added or removed, I have tried so far changing the child iteration for a range that looks like this:

themes\deltavtheme\layouts\partials\SecondHeader.html
<div class="collapse navbar-collapse" id="navbarResponsive">
            {{ $currentPage := . }}
            <ul class="navbar-nav ml-auto">
                {{ range .Site.Menus.main }}
                {{ if .HasChildren }}
                <li class="nav-item dropdown no-bg">
                    <a class="nav-link dropdown-toggle" href="{{.URL}}" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true"
                       aria-expanded="false">
                        <span>{{ .Name }}</span>
                    </a>
                    <div class="dropdown-menu " aria-labelledby="navbarDropdown">
                        {{ range where .Site.Pages "Section" "proyectos" }}
                        <a class="dropdown-item" href="{{.URL}}">{{.Name}}</a>
                        {{ end }}
                    </div>
                </li>
                {{else}}
                <li class="nav-item">
                    <a class="nav-link" href="{{.URL}}">
                        {{ .Pre }}
                        <span>{{ .Name }}</span>
                    </a>
                </li>
                {{end}}
                {{end}}
            </ul>
        </div>

But this raises an error saying that there can’t be a Site range inside the Menu range, so I thought about create this HTML part by using Scratch, but I am not sure about how to add an HTML string with inline arguments to Scratch.

If there is an easier way or a better one any answer is welcome.

Thank you for any help.

Instead of doing this:

{{ range .Site.Menus.main }}
  {{ range .Site.Pages }} 
    {{ .Title }}<br>
  {{ end }}
{{ end }}

Do either this:

{{ range .Site.Menus.main }}
  {{ range $.Site.Pages }} 
    {{ .Title }}<br>
  {{ end }}
{{ end }}

Or this:

{{ range .Site.Menus.main }}
  {{ range site.Pages }} 
    {{ .Title }}<br>
  {{ end }}
{{ end }}
1 Like

Works perfectly, thanks!!

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