Harry Cresswell

Fixing breaking changes when upgrading Hugo

Unless you want to use new features, or you’re working on a Hugo project built with a newer version, then there’s no real need to upgrade your version of Hugo. You can run an old version of Hugo and everything will continue to work just fine.

However, if you do find yourself needing to upgrade Hugo for whatever reason, you’re probably wondering if anything is going to break in your existing projects when you upgrade to the latest version. It’s a reasonable concern.

Last week I upgraded my Hugo version from 0.55.6 to Hugo 0.80. I sort of expected everything to break, so I had a contingency plan in the form of Fernando Medina Corey’s article on using legacy versions. But to my surprise, after the upgrade I was pleased to find very few errors.

The main issue - which seems like a common one - is content from sections not rendering on a homepage. To be clear what I mean by this, section content is content stored in a sub directory of the content directory i.e ./content/supplier.

To render section specific content on a homepage in the past you might have nested a where clause in your range. Something like this:

{{ range (where .Pages "Type" "supplier") | first 2  }}
  {{ .Content }}
{{ end }}

But with Hugo 0.80 this no longer works.

In easiest way to fix this (in plain english) is as follows:

In Go templating that will look something like this:

{{ $pages := where site.RegularPages "Type" "in" site.Params.supplierSection }}
{{ range $pages | first 2  }}
  {{ .Content }}
{{ end }}

If it wasn’t clear from this example, you can assign your section to any variable name you like in your config file. It doesn’t have to be in the mainSections array as suggested in the Hugo docs. Consider the below example.

//config.toml
[params];
mainSections = ["blog", "docs"]; // use an array as suggested in the Hugo docs
supplierSection = "supplier"; // this also works great
interviewSection = "interview"; // as does this

If you have a few different sections and don’t want to combine content from both sections into one array to range over then the second option is probably the best way to go.

I had another very similar issue on another project which involved paginating through pages in a section from on the homepage.

{{ $paginator := .Paginate (where .Pages "Type" "writing") 6 }}
<ul class="PostList">
{{ range (.Paginator 6).Pages }}
  {{ partial "post-list-item.html" . }}
{{ end }}
</ul>

{{ partial "pagination.html" . }}

The fix was almost identical as before. But this time passing the $pages variable to .Paginate function stored in a second variable called $paginator and ranging over that instead.

{{ $pages := where site.RegularPages "Type" "in" site.Params.mainSections }}
{{ $paginator := .Paginate $pages }}
<ul class="PostList">
{{ range $paginator.Pages }}
  {{ partial "post-list-item.html" . }}
{{ end }}
</ul>

{{ partial "pagination.html" . }}

It’s worth noting if you’re using pagination on a list page everything should still work as normal but if it’s not then it’s probably an issue with .Pages vs .RegularPages, as explained in Alexandros’s comment about this.

I’ll return to this article and document any errors I get the next time I upgrade, but that’s all for now.

Further reading #

Monthly Newsletter

Once a month I curate a newletter for designers and developers interested in CSS, Jamstack and keeping it simple. Check out past issues to get an idea.