Sub-Links Not Marked as Active

Hi all,

On my site, I have the main navigation menu that lists all the sections, such as:

Blog (www.domain.com/blog)
About (www.domain.com/about)
CV (www.domain.com/cv)

The following code correctly marks a link as active:

 {{- define "section-tree-nav" }}
{{- $currentNode := .currentnode }}
{{- with .sect}}
{{- if and .IsSection (or (not .Params.hidden) $.showhidden)}}
    {{- $numberOfPages := (add (len .Pages) (len .Sections)) }}
    {{- safeHTML .Params.head}}
    <li data-nav-id="{{.RelPermalink}}" class="nav-item my-1
        {{- if .IsAncestor $currentNode}} parent{{end}}
        {{- if eq .RelPermalink $currentNode.RelPermalink}} active{{end}}
        {{- if .Params.alwaysopen}} alwaysopen{{end -}}
        {{- if ne $numberOfPages 0 }} haschildren{{end}}
        ">
        <!-- I'm the params head -->
        <a class="nav-link p-0" href="{{.RelPermalink}}" {{- if eq "Skills Reference" .Params.Title}}target="_blank" {{end}}><h6>{{safeHTML .Params.Pre}}{{.Title}}{{safeHTML .Params.Post}}{{- if eq "Skills Reference" .Params.Title}}<i id="skills-ref-external-icon" class="fas fa-external-link-alt"></i>{{end}}</h6>
        </a>
      {{- if and (ne $numberOfPages 0) (ne "Skills Reference" .Params.Title) }}
        <ul class="list-unstyled ml-2">
          {{- .Scratch.Set "pages" .Pages }}
          {{- if .Sections}}
          {{- .Scratch.Set "pages" (.Pages | union .Sections) }}
          {{- end}}
          {{- $pages := (.Scratch.Get "pages") }}

        {{- if eq .Site.Params.ordersectionsby "title"}}
          {{- range $pages.ByTitle }}
            {{- if and .Params.hidden (not $.showhidden) }}
            {{- else}}
            {{- template "section-tree-nav" dict "sect" . "currentnode" $currentNode }}
            {{- end}}
          {{- end}}
        {{- else}}
          {{- range $pages.ByWeight }}
            {{- if and .Params.hidden (not $.showhidden) }}
            {{- else}}
            {{- template "section-tree-nav" dict "sect" . "currentnode" $currentNode }}
            {{- end}}
          {{- end}}
        {{- end}}
        </ul>
      {{- end}}
    </li>
    {{- if eq "Skills Reference" .Params.next}}
      <hr class="solid-nav-separator">
    {{- end }}
{{- else}}
    {{- if not .Params.Hidden }}
        <li data-nav-id="{{.RelPermalink}}" class="nav-item my-1 {{- if eq .RelPermalink $currentNode.RelPermalink}} active{{end -}}">
                <!-- I'm the params hidden -->
                 <a href="{{.RelPermalink}}" class="nav-link p-0">
                    {{safeHTML .Params.Pre}}{{.LinkTitle}}{{safeHTML .Params.Post}}
                </a>
        </li>
    {{- end}}
{{- end}}
{{- end}}
{{- end}}

For example, if you’re at www.domain.com/about/, the about link in the sidebar is correctly set to active with the code above.

I override this menu if we’re on a specific page. For example, if you’re on www.domain.com/blog/, the menu is overridden to list the child pages, such as blog/post1, blog/post2, etc so the sidebar now looks like:

Post 1 (www.domain.com/blog/post1/)
Post 2 (www.domain.com/blog/post2/)

Now, if a user clicks Post 1 in the sidebar, it should also be marked as active, but the following code doesn’t seem to do that:

{{define "skills-ref-menu"}}
{{- $currentNode := . }}

{{- range .menu}}
<li data-nav-id="{{.RelPermalink}}" class="nav-item my-1 {{- if eq .RelPermalink $currentNode.RelPermalink}} active{{end}}
        ">
        <a class="nav-link p-0" href="{{.RelPermalink}}"><h6>{{safeHTML .Params.Pre}}{{.Title}}{{safeHTML .Params.Post}}</h6></a>
</li>
{{- end }}
{{- end }}

From what I can tell, $currentNode.RelPermalink is nil, so {{- if eq .RelPermalink $currentNode.RelPermalink}} active{{end}} is never satisfied. Is there a different way to do this? Can I somehow compare the .RelPermalink to everything after the hostname in the URL (e.g. www.domain.com/blog/post1/ → /blog/post1)?

eq returns the boolean truth of an argument.
in checks if an element matches -among others- a substring.

Using if in .RelPermalink .CurrentSection should render the active class in pages below the parent section.

Also I am not aware of a built-in .currentnode Hugo variable.
That is why I would suggest that you use .CurrentSection instead.

Also see:

Maybe I can illustrate what I mean with some screenshots.

Here, I’m at www.domain.com/getting-started/. Notice how “Getting Started” is purple (i.e. active) in the sidebar:
Screen Shot 2021-01-27 at 3.52.02 PM

This is using the first block of code in the OP. At this level, there’s also a “Skills Reference” link (www.domain.com/skills-reference/).

Here, I’m at www.domain.com/skills-reference/browse. Notice how “Browse” is not purple in this case:
Screen Shot 2021-01-27 at 3.52.18 PM

I want “Browse” to be marked as active in this case. Using if in .RelPermalink .CurrentSection doesn’t appear to work in this case.

I was able to figure this out. I needed to pass the current node to my template, so I changed:

{{- template "skills-ref-menu" dict "menu" $pages.ByTitle "pages" .Site.Pages "sortTerm" $sortTerm}}

to pass $current, which is set to $current := ., to the template:

{{- template "skills-ref-menu" dict "menu" $pages.ByTitle "pages" .Site.Pages "sortTerm" $sortTerm "currentnode" $current}}

Then, I changed:

{{define "skills-ref-menu"}}
{{- $currentNode := . }}

{{- range .menu}}
<li data-nav-id="{{.RelPermalink}}" class="nav-item my-1 {{- if eq .RelPermalink $currentNode.RelPermalink}} active{{end}}
        ">
        <a class="nav-link p-0" href="{{.RelPermalink}}"><h6>{{safeHTML .Params.Pre}}{{.Title}}{{safeHTML .Params.Post}}</h6></a>
</li>
{{- end }}
{{- end }}

to use the currentnode variable:

{{define "skills-ref-menu"}}
{{- $currentNode := .currentnode }}

{{- range .menu}}
<li data-nav-id="{{.RelPermalink}}" class="nav-item my-1 {{- if eq .RelPermalink $currentNode.RelPermalink}} active{{end}}">
        <a class="nav-link p-0" href="{{.RelPermalink}}"><h6>{{safeHTML .Params.Pre}}{{.Title}}{{safeHTML .Params.Post}}</h6></a>
</li>
{{- end }}
{{- end }}

I usually do this way:

in my header.hml

{{ $url := .RelPermalink }}
{{- $section := .Section }}

Then for top navigation links:

  {{ range .Site.Menus.main }}
              {{ if .HasChildren }}
              <li class="dropdown">
                <a href="#" title="{{ .Title }}" class="menu {{ if eq $section .URL}} active {{end}}dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
                  aria-expanded="false">{{ .Name }}</a>
                <ul class="dropdown-menu">
                  {{ range .Children }}
                  {{- $url2 := .URL }}
                  <a class="dropdown-item {{ if eq $url $url2  }}active{{ end }}" href="{{ .URL | absLangURL }}">{{ .Name }}</a>
                  {{ end }}
                </ul>
              </li>
              {{ else }}
              <li><a class="menu {{ if eq $section .URL}} active {{end}}" title="{{ .Title }}" href="{{ .URL | absLangURL }}">{{ .Name }}</a></li>
              {{ end }}
              {{ end }}
1 Like

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