Hugo Content Management Series

Since I started using Hugo, I noticed a lack of plugins or shortcodes for lists of related or featured posts. For bloggers and digital-marketing / content writers, it’s valuable to list: related posts, featured content or content in a series.

This post will focus on_ Series of Posts or Articles which have a shared topic_ and showing these on your homepage, list or another page.

I’ll show you to

  1. Enable the series taxonomy and series list page
  2. Add extra Params in your Front Matter called series to your markdown content
  3. List posts in a series code for your theme (worked example)
  4. Using IF - ELSE logic to show / hide this Series or Related posts
  5. Consider how to test this
  6. Resolve issues if they crop up

This is all part of a series on Content Management in Hugo and you can see in sidebar other posts in the series …

Enable the new Taxonomy Series

What we want to do here is enable the Series taxonomy - so you can use the list layouts as you would for tags or categories. If you don’t want to do this, then you don’t need to add it.

But … if you don’t do this step, then you won’t have series taxonomy pages and lists of content can be sorted wrong.

Open your config file and add this in:

1
2
3
4
[taxonomies]
    category = "categories"
    series = "series"
    tag = "tags"

When adding custom taxonomies, you need to put in the default taxonomies too, if you want to keep them.

Front Matter Changes

For the series part to work, when writing your markdown content, you add a parameter in the front matter.

The top of your markdown files will look like this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
---
title: "My post title"
date: 2020-06-06
categories: 
- Hugo
tags: 
- Hugo
author: Your Name
draft: true
Series: Hugo Content Management
---

We can then access this front matter using .Params

Modify your Theme

Go ahead add open your theme layout (for your standard post or sidebar)

Here is the basic code to query the series param, I’ve highlighted the key lines

1
2
3
4
5
6
7
{{$related := where .Site.RegularPages ".Params.series" "eq" .Params.series }}
<h3>Posts in this Series</h3>
	<ul>
	  {{ range $related }}
	      <li><a href="{{ .Page.RelPermalink }}">{{ .Page.Title }}</a></li>
	  {{ end }}
	</ul>

So this code will only show if the Series Param is added on your markdown content - and then it looks for other posts that equal (‘eq’) the same series description. After that its simple.

You can now hide this widget / container from your side with 2 bits of logic related code

If the post / article has series meta data - then this section of code is run. If not - nothing happens … make sure you add the {{ end }}

1
2
3
4
5
6
7
8
9
{{ if isset .Params "series" }}
{{$related := where .Site.RegularPages ".Params.series" "eq" .Params.series }}
	<h3>Posts in this Series</h3>
	<ul>
	  {{ range $related }}
	      <li><a href="{{ .Page.RelPermalink }}">{{ .Page.Title }}</a></li>
	  {{ end }}
	</ul>
{{ end }}

Worked Example: if you already have a Latest Post Section / Sidebar

I already have a section showing my Latest Posts — you can see it on myblog and my theme has a sidebar.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
{{ if isset .Params "series" }}
      {{ $name := .Params.series }}
        <div class="widget mb-5">
          <h4 class="mb-4 widget-title">Articles in this series on
            <a href="{{ `series/` | relLangURL }}{{ $name | urlize | lower }}">{{$name}}</a></h4>
          <ol class="list-unstyled">
            {{$related := where .Site.RegularPages ".Params.series" "eq" .Params.series }}
            {{ range $related }}
            <li class="d-flex mb-4">
              <div class="post-body">
                <span class="text-capitalize">- {{ dateFormat "Monday, Jan 2, 2006" .Date }}</span>
               <a href="{{ .Permalink }}">
                 <h5>{{ .Title }}</h5>
               </a>
             </div>
           </li>{{ end }}
         </ol>
       </div>

Extending this, I also want to hide the ‘related’ content section if I’m looking at a post in a series - because there is no point is crowding the screen with unrelated content … So we will make use of {{ if }} and {{ else }}.

I won’t put all the code .. but here’s the idea:

1
2
3
4
5
6
7
8
{{ if isset .Params "series" }}
	<h4 class="mb-4 widget-title">Articles in this series on ...
	...
{{else}}
	...
	<h4 class="mb-4 widget-title">Related Posts</h4>
	...
{{ end }}

Note - {{ if isset }} is a test to see if the markdown content has the series param

Test Driven Development

If you are thinking of Automated Testing with Selenium or other tools … be sure to wrap any custom code with class elements that make them easy to identify for testing.

Test and Go …

So now you have the idea …

  1. Save the file
  2. Commit your changes to Git
  3. Run Hugo server -D and browse to http://Localhost to check every thing is work fine

If you find a problem

  • check the series name in your front matter
  • Sort order looks wrong - check if the series taxonomy is added
  • Also .. try browsing to http://Localhost/series>/<series-name>

Did you find this helpful? Please let me know

Linkage

Subscribe to my Newsletter
Email: First Name:

We use Mailchimp as our marketing platform. By clicking below to subscribe, you acknowledge that your information will be transferred to Mailchimp for processing. Learn more about Mailchimp's privacy practices here.