Linking to the previous and next page in a taxonomy term in Hugo

Something that can be slightly tricky to achieve within Hugo’s taxonomy system is linking to the previous and next page within a particular taxonomy term. For example, if you have a Series taxonomy, you might want to link to the previous and next page in that series on each page in it.

One way to solve this is to loop through all the pages in the taxonomy term and grab the previous and next pages on the way.

That looks like this in a template:

{{ if isset .Params "series" }}
  {{ $seriesTitle := index .Params.series 0 }}
  {{ $currentLink := .Permalink }}
  {{ $wholeSeries := (index .Site.Taxonomies.series ($seriesTitle | urlize)).Pages.ByWeight.Reverse }}
  {{ range $index, $page := $wholeSeries }}
    {{ if eq $currentLink $page.Permalink }}
      {{ if gt $index 0 }}
          {{ .Scratch.Set "prevInSeries" (index $wholeSeries (sub $index 1)) }}
      {{ end }}
      {{ if lt $index (sub (len $wholeSeries) 1) }}
          {{ .Scratch.Set "nextInSeries" (index $wholeSeries (add $index 1)) }}
      {{ end }}
    {{ end }}
  {{ end }}

  {{ with index .Scratch.Values "prevInSeries" }}
      <a href="{{ .Permalink }}" rel="prev">&larr; {{ .Title }}</a>
  {{ end }}
  {{ with index .Scratch.Values "nextInSeries" }}
      <a href="{{ .Permalink }}" rel="next">{{ .Title }} &rarr;</a>
  {{ end }}
{{ end }}

This does get quite hard to follow in Go’s template syntax, but it does the job.

It works like this:

  1. Get the title of the series we’re interested in.
  2. Get the link of the current page as an identifier.
  3. Get the whole series ordered by taxonomy term weight in ascending order.
  4. Loop through all the pages in the series, keeping track of the index.
  5. When we hit the current page, use Scratch to store the previous and next page if each exists.
  6. After the loop, render the previous and next page links if they exist in Scratch.

Having the range loop structure also means you could render out a table of contents for the series while doing that.

This seems like a lot of template code, but is of course more than fast enough when being run during the site build, so you won’t notice any difference.

Tech mentioned