Hugo Simple Post Archive

Time 3 minute read
A simple post archive with Hugo (Image)
A simple post archive with Hugo (Image)

This post is part of the Blogging with Hugo series.

When I designed this theme I wasn’t actually planning on creating an archive page. Now, a couple of months and several written posts later I figured, it might not be the worst thing to have.

In my opinion, two points speak for a blog archive:

  • No clicking through the pagination necessary to find relevant content
  • Having a nice overview of existing content (and what I’ve achieved in a year)

On top of that, with no out-of-the-box search feature available for static sites (though possible, looking at you, Lunr.js), skimming through post titles may lead to surprising discoveries.

The archive layout I’m aiming at, is a list of all posts, grouped by year. Simple and effective.

First, we’ll need a new static page. For Hugo, this will be a new section. It will be located in the content folder:

└── content

Front matter for this file looks like this:

title: "Archive"
type: archive
summary: This page contains an archive of all posts.

It’s not much, but we don’t need that much metadata anyway. A title to display, the type of section and a summary, if you like.

Once this file is created, you can already navigate to it. If you run your site locally, using the hugo server command, go to http://localhost:1313/archive. Depending on your default layout for single pages, it might not show much, just the title.

Time to deal with the layout.

Either in your site’s layout folder, or in the layout folder of your theme, create another folder called archive, containing the file single.html.

└── layout
    └── archive
        └── single.html

Since the section page is declared as type: archive, it will pick up the template file located in the archive folder. Here’s the bare bones layout. I removed all custom styles to make it clearer.

{{ define "main" }}
  <h1>{{ .Title }}</h1>

  // Display actual content, if available 
  {{ .Content }}

  // Group all pages by year
  {{- range (.Site.RegularPages.GroupByDate "2006") -}}
    // Take only pages of type "post" into account
    {{- $posts := (where .Pages "Type" "post") -}}
    {{- $posts_count := len $posts -}}
    // .Key is the current year
    // Check if it is an actual year and it contains any posts
    {{ if and (gt .Key 1) (gt $posts_count 0) }}
      // Display the year
      <h2>{{ .Key }}</h2>
      // Create a ul element containing all posts ...
        // ... and iterate over all pages of type "post"
        {{ range (where .Pages "Type" "post") }}
          // Skip hidden posts
          {{ if (ne .Params.hidden true) }}
              // Display the post's date
                {{ .Date.Format "Jan 02" }}
              // Display a link with the post's title
              <a href="{{ .RelPermalink }}">
                <span>{{ .Title }}</span>
          {{ end }}
        {{ end }}
    {{ end }}
  {{ end }}
{{ end }}

That’s it! The gist is: group all pages by year, and then iterate over these page but only render actual blog posts. You can check out the result at my archive.

This series

  1. Chringel Hugo Theme
  2. Inline SVG Icons For Hugo
  3. Isso - An Alternative Commenting System For Hugo
  4. umami - A Google Analytics Alternative For Hugo
  5. Automatically Deploy a Hugo Website to a Remote Host Using Github Actions
  6. Hugo Simple Post Archive
  7. Random Cover Image

Share Social Interact With This Post At: Logo Mastodon Mastodon Logo Twitter Twitter
Calendar Posted:
Person Posted By:
Folder Open Categories: Tutorials Coding
Pricetags Tags: Hugo Archive Partial


Das ist witzig, weil es auch schon ein kommerzielles Archiv-System gibt, das so ähnlich heißt.