Can't get a very simple menu to work

Hi, I’m new to Hugo, and trying to build a very simple site with a “Home” page and a section “News” with blog posts. I want to have a menu with these two options and highlight the active menu section, but after hours of reading the docs and examples still can’t get this to work, and I don’t understand why.
In my config.yaml I have the following:

menu:
    main:
    - name: Home
      pageRef: / 
    - name: News
      pageRef: /News

And in my header.html this template code:

<ul>
    {{ $currentpage := . }}
    {{ range site.Menus.main }}
    <li><a {{ if $currentpage.IsMenuCurrent "main" . }}class="active"{{ end }} href="{{ .Url }}">{{ .Name }} (from Menus.main)</a></li>
    {{ end }}
</ul>

However none of the two menu items is shown with class “active”… what am I doing wrong?
Any tips on how to go about debugging this?
Thanks in advance

Which version of Hugo?

 hugo version
hugo v0.96.0-2fd4a7d3d6845e75f8b8ae3a2a7bd91438967bbb linux/amd64 BuildDate=2022-03-26T09:15:58Z VendorInfo=gohugoio

Thanks

PS By the way, I see I crossed variables, in the config.yaml I have PageRef, in the template it’s Url. This is because I was trying both (as I see both in the documentation and forum posts, which is also confusing to me). I’ve switched everything back to PageRef.

So, this:

href="{{ .Url }}"

should be this:

href="{{ .URL }}"

Other than that, can you describe what’s not working?

The URL’s work, but the class="active" never gets applied. So somehow I’m not completely understanding what $currentPage.isMenuCurrent "main" . is doing - is it doing some kind of object comparison, should I change the menu entries in config.yml, etc? (How does it determine true or false, since it seems to come out as false always?)

When I use your menu entries in site config, and your code, the active class is applied when visiting the home page and the news list page.

Did you expect something different?

It might be helpful if you could share your project repository.

I’m gobsmacked, as I do not see the “active” class applied at all…
I’m happy to share the project, but then I have to put it on Github somewhere, and it may look very disorganized (for the record, I’m trying to develop a theme from scratch, and switching back and forth between it and a now hacked up tutorial theme. So you’d see two themes, some content, a few pictures and bogus new items).
Give me 5 minutes to put it under Git and post it on Github and I’ll post the link here.

Here’s a simple working example:

git clone --single-branch -b hugo-forum-topic-44318 https://github.com/jmooring/hugo-testing hugo-forum-topic-44318
cd hugo-forum-topic-44318
hugo server
1 Like

OK, thanks, I’ll take a look!
In the meantime, my WIP is here: GitHub - tonvanbart/learn-hugo-templating
“europrez” is the theme I’m building, “zeo” is the tutorial theme I’m hacking around in.

Couple of things…

1) In your header partial, replace this:

href="{{ .PageRef }}"

with this:

href="{{ .URL }}"

2) Whenever you call this partial, you must pass the current page context. In some places you have this:

{{ partial "header.html" }}  # INCORRECT

In other places you have this:

{{ partial "header.html" . }}  # CORRECT

OK, thanks, I think I get it - not passing the current page context is the problem, right? And on yours it then works, since you have the “menu” code inline in baseof.html and then it already has the context?
One final question, why do you have to define pageRef in config.yaml but then use URL in the template?

And thanks again - I have experience with Kubernetes, which uses Helm, which uses Go templating, I thought I’d got this. Apparently, not yet :wink:
The ones that have the . dot came from the generated template skeleton, and I completely missed in when adding the partial to my own stuff.

Yes.

First, notice that .PageRef is not included in list of menu variables that you can use in a menu template. See:
https://gohugo.io/variables/menus/

Second, when defining a menu entry in site configuration, set url for external links, and set pageRef for internal links. See:
https://gohugo.io/content-management/menus/#properties-site-configuration

Third, the .URL variable in a menu template returns

the .RelPermalink of the page associated with the menu entry. For menu entries pointing to external resources, the url property of the menu entry.

And “the page associated with the menu entry” is determined by the pageRef menu entry property.

Again, see https://gohugo.io/variables/menus/.

2 Likes

Side note: the pageRef menu property was introduced in v0.86.0 which, among other things, resolved an issue where .Page.HasMenuCurrent and .Page.IsMenuCurrent failed when defining menu entries in site configuration.

Many of the themes, examples, and tutorials in the wild are out of date, and wrong.

Thanks again for the explanations, that was very helpful!
I’ve made the changes to the templates, now it seems to be half working - when I choose “Home”, that menu entry is highlighted, but when I choose “News”, that entry is not for some reason. (I’ve pushed the changes.)
And indeed I’ve noticed the version differences, I started out with the Giraffe Academy tutorial, which was good, but gave me some headaches straight off the bat since it’s based on an older version.

I forgot to ask, is there a trick to show for e.g. everything that’s inside $currentPage in one go? I was looking at the reference docs and listing individual properties of the Page object in one of the templates, but iterating over the whole thing would be super helpful.

Your template structure is… not quite right. Take a hard look at the example I provided.

The baseof layout is typically the “chrome” for the entire site. Then you define the inside in the other layouts. You’ve kind of mixed things up, where the list page doesn’t use the baseof layout, and consequently does not include the head partial (where the CSS is).

I don’t understand the question.

In the meantime, I was flipping back and forth between your example and my effort, and I noticed the same - I just pushed a commit titled “proper use of partials”, now it seems to be working as intended.

My question was about if there is is some way to “see” all the properties in some object. For example in Javascript an object is actually a kind of dict, and it’s possible to iterate over all the entries, so you see all the properties and functions in there. In Java you’d just hook up a debugger and have a look at the innards of a variable.
While playing with Hugo templates I feel like I’m flying blind a bit so I was wondering if there was some trick to do a similar thing.
You’re right to point me to the documentation by the way, and I should look at that more - I guess I’ve gotten a bit lazy over the years having these tools at my disposal…

You can use this to view context of SINGLE pages, maps, and data files:

<pre>{{ jsonify (dict "indent" "  ") . }}</pre>

It will bomb (for a good reason) on SECTION pages (home, list, taxonomy, term) because these templates receive .Pages in context, and the jsonify template function can’t deal with that.

1 Like

Awesome! Thank you.

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