Setting a value based on either default/global/section/page params

So I wanted to set a header class (e.g. colors scheme) at either the global, section, or page level. This is what I came up with, if it helps someone else. If there’s a better way to do it, please chime in.


1) Get page or config-set Param, with a default.

{{ $headerClasses := $.Param "headerClasses" | default "classes" }}

That one line gets us most of the way, but it doesn’t allow us to get a value set at the section level, so we turn to the clunky part:

2) set the section, and if the page has a section, get the parameter from the page, but if not, look to see if the section has one set.

{{ $section := .Site.GetPage "section" .Section }}
{{ if $section}}
  {{ $headerClasses := $section.Param "headerClasses" | default $headerClasses }}
  {{ $headerClasses := .Params.headerClasses | default $headerClasses }}
  {{ $.Scratch.Add "headerClasses" $headerClasses }}
{{ end }}

We can’t get a variable from inside of a conditional, so use Scratch


3) Call it again to sweep up, either getting the scratch value or the originally set value:

{{ $headerClasses := $.Scratch.Get "headerClasses" | default $headerClasses }}

Here’s a GIST with the entire thing with inline comments.


The following forum posts informed the above:
how-to-override-a-site-param-with-a-section-param
cant-define-variable-inside-ispage-block

Note: This posting is as of Hugo v0.20.7

2 Likes

This is currently a fairly ineffective way of doing it (see https://github.com/spf13/hugo/issues/3503), and I would suggest you create some kind of structure for both section and site headerClasses in your site config, and then build on that. Map lookups are cheap.

What I’m trying to accomplish here is to be able to set the value directly from a page, or a page’s section, so setting up the structure from the config would defeat the purpose, though perhaps I don’t understand what you’re suggesting here:

Given that you currently (most likely) have a limited amount of sections, that configuration could easily live with the site config and then have the regular pages have their own. I was just saying that your code would be ineffective for bigger sites. But up to you.

Ah, right. I agree, it’s not very practical, but it gets me what I wanted, which is to let the client to be able to edit those values from an external editor interface. They could conceivably edit values in the config, but I’m not sure that would help too much given that I need to set either page or section value. Just constraining it to be set at the page level would be easier, but not too helpful.

The site has 12 sections and a few thousand pages. I benchmarked it and it didn’t seem to have an appreciable impact on build times.

Anyway, this should improve on the performance bit:

https://github.com/spf13/hugo/commit/fbb78b89df8ccef8f0ab26af00aa45d35c1ee2cf

Awesome, thanks!