A shelf of old folders full of files.

Add Archives to Hugo

One thing that I felt was missing from Hugo, now that I’ve converted my site from WordPress, is the yearly archive feature. I mean, it’s essential! I have a whole 1, one, post from 2019, so I clearly need that.

Ok, so maybe not. But, it is nice to have in place for later nontheless. Searching online led me to this discussions thread on the Hugo forum.

There is no such feature it seems.

I’ll Make it Myself Then

It can’t be that hard to just build it. In fact, the solution is mostly there in that thread already, so I gave it a go. Here is my solution.

The taxonomy feature of Hugo is very customisable, so all that is needed is to add it to the config and to the posts. Then you need to prepare some templates.

First, I had to add the year taxonomy, and add a way to generate the permalinks to the archive page. All my posts are saved under the path /blog, so I changed the example from the discussion thread to this:

# Content Settings
  category: categories
  tag: tags
  year: year

  blog: "/blog/:year/:month/:slug/"
  year: "/blog/:slug/"

While this is not strictly necessary, I wanted a more descriptive header on my archive pages, so I modified my layouts/_default/term.html template as well to include a header prefix for the yearly archive:

<article id="main-article" class="list-container">
  <h1 class="list-title">
    {{- if eq .Type "categories" -}}
    {{- end -}}
    {{- if eq .Type "tags" -}}
    {{- end -}}
    {{- if eq .Type "year" -}}
    {{- end -}}
    {{- .Title | title -}}
  {{ range .Paginator.Pages }}
    {{ .Render "summary"}}
  {{ end }}
  <div class="pagination-box">
    {{ template "_internal/pagination.html" . }}

As you can see, it already contained prefixes for categories and tags.

Archives in the Sidebar

Of course, I also need a partial to include in my sidebar where I want to list the archive. I opted to generate the list in reverse order, with the current year first, but it is trivial to change it to increasing order instead.

My solution is the following:

<div class="sidebar-item sidebar-categories sidebar-list">
  <h3>Blog Archive</h3>
  {{ range .Site.Taxonomies.year.Alphabetical.Reverse }}
    <li><a href="{{ .Page.Permalink }}">Posts from {{ .Page.Title }}</a> ({{ .Count }})</li>
  {{ end }}

This partial is now included on the root /blog page, and for now, nowhere else.

That is pretty much all that was needed for me. The rest is handled by existing templates for categories and tags.

Updating the Archetype

If you have an archetype for generating new posts, adding the year value to the front matter is as easy as:

title: "{{ replace .Name "-" " " | title }}"
date: {{ dateFormat "2006-01-02" now }}
year: {{ dateFormat "2006" now }}
draft: true

It’s handy so you don’t have to remember to add it to new posts as it gets pre-filled by the hugo new command.

I hope this was helpful to someone else!

Tags: hugo, themes, archive


You can use your Mastodon account to comment on this post by replying to this thread.

Alternatively, you can copy and paste the URL below into the search field of your Fediverse app or the web interface of your Mastodon server.

The Mastodon integration is based on the implementation by Carl Schwan.