Section variable defined on a node

I have two related questions.

I’m trying to highlight which section of my site the user is currently on in the navbar. I’m going to use the Hugo “section” and if it matches the navbar link I’m going to change its class.

Unfortunately, it looks like .Section is only defined when .IsPage is true, which means that list nodes (e.g. /posts/, prior to /posts/mypost) don’t get a good .Section. So question 1, how am I supposed to be getting the section name on a node?

For now, I’m attempting to get it by using the node’s .Title, which after getting lowercased is close, but I only want to use .Title if .Section is undefined and .IsPage is false.

So I have this:

      {{ $active_section := .Section }}
      {{ if (and (eq (len $active_section) 0) (not .IsPage)) }}
        {{ $active_section := (lower .Title) }}
      {{ end }}

Unfortunately, Go templates don’t let you mutate variables defined outside inside of an if block, so $active_section is never the .Title after the if block.

I was reading golang-nuts, and Steven Blenkinsop suggested creating a cell type so you could do mutations in templates. Regardless of how I end up getting the section, this seems immensely useful. Does something like this already exist, or would it be possible to add?


Update: I just found, which is basically the cell thing above. Yay!

lol, I switched to try and use a prefix match with .Url, but of course that’s only defined on Nodes and not Pages. :frowning:

Wasn’t an immediately obvious idea to me but you can combine strings and booleans in Go templates, which aren’t strongly typed like Go is.

So I settled on

{{ $active_section := (or .Section (or (and (not .IsPage) (lower .Title)) ""))}}

Hugo 0.14 is just around the corner.

With it comes a new feature I named Section Menu for “the Lazy Blogger”.

It will be part of the public docs, until then you can read about it at the bottom here:

I’m reading the docs, but it’s unclear how that helps this (what I think should be simple and straightforward) case. Can you elaborate?

Well, I wrote the documentation for the “section menu” feature – I don’t believe I can make it much clearer. But I’m from Norway, so maybe someone else with better grasp of the English language could give it a try. But to me it looks like exactly what you try to achieve with your slightly hackish code.

I did it this way:

{{ $currentNode := . }}
{{ range .Site.Menus.sections }}
    {{if or ($currentNode.IsMenuCurrent "sections" .) ($currentNode.HasMenuCurrent "sections" .) }}

Note that i called the sections menu “sections” in my config.toml. Also, if you want th highligt the section in a path-like style, e.g.: “Sitename/Sectionname”, put it all in the same line as your “Sitename/” string without spaces between each pair of “}} {{”, like so: “}}{{”, or you’ll end up with: “Sitename/ Sectionname”.