How to let header.html make a decision based on the actual page?

Hi, I’m quite new to Hugo, but it’s not too difficult and I like it. I’m creating a personal theme using Foundation 5. Not very difficult either.

I’m having a problem using Hugo’s variables. I’m creating a top bar menu. Leaving out any irrelevant stuff, my code from the partial header.html looks like this:

{{ if eq .RelPermalink "/about/"}}
  <li class="active"><a href="/about/">About</a></li>
{{ else }}
  <li><a href="/about/">About</a></li>
{{ end }}

(All this could be done on one line of code, but let’s keep it simple here.)

This is what I’m trying to do. A button can be either active or inactive. When for example the about page was loaded, this should also be reflected to the menu button by making it active (it changes color).

I was wondering which variable I should use in order for my header partial to be able to determine by which page it is included. The .Section variable seemed the most obvious: just compare it to “/about/”. If it does, make the button active. However, .Section somehow doesn’t have a value. (Why?) Anyway, I decided to use .RelPermalink. This raises an error message, but it still works!

ERROR: 2015/09/26 template: theme/partials/header.html:41:17: executing “theme/partials/header.html” at <.RelPermalink>: RelPermalink is not a field of struct type *hugolib.Node in theme/partials/header.html

This error doesn’t mean anything to me (yet), I might be doing something wrong. I hope someone is able to tell me. Perhaps, you know a better way of achieving my goal. If not, there’s still another problem: my site’s root index page (themes/name/layouts/index.html). I’d expect its .RelPermalink variable to have a value like “/” or “”. However, it doesn’t have a value at, all and Hugo stops processing the header.html file.

I would have tried to not reinvent the wheel and had a look at this:

1 Like

Thanks @bep, I’m going to do that. Using Hugo’s menuing system will also make my site menu more dynamically configurable.

I found an answer to my questions by the way. It is good habit to provide the solution to a support forum, even if one finds it oneself: someone else might benefit from it. I’ll post the solution in a few minutes…

As promised, the answers to my own questions, and a working solution…

The key problem was: I didn’t realize a root “home” page is a node. Nodes and pages have different variables however. Now knowing this, let’s try:

{{ if eq .URL "/"}}<some code that makes the Home menu active{{ end }}
{{ if eq .RelPermalink "/about/"}}<some code that makes the About menu active>{{ end }}

This will not work, because if the document is a page, line 1 refers to a node variable called .URL. It doesn’t know about this variable, so rendering the partial is stopped. The same goes for a node, which in line 2 tries to use a page variable called .RelPermalink. Functions: IsNode and IsPage come to the recue…

<li{{ if .IsNode }}{{ if eq .URL "/" }} class="active"{{ end }}{{ end }}><a href="/">Home</a></li>
<li{{ if .IsPage }}{{ if eq .RelPermalink "/about/"}} class="active"{{ end }}{{ end }}><a href="/about/">About</a></li>

It might indeed still be better to use Hugo’s native menuing facilities. I still expect the need to include code that separates the handling of nodes and pages, but when using something like {{ range … }} over every menu item, this won’t be a problem.

1 Like