Skip to main content
  1. Posts/

Adding Series and Navigation links to Hugo page

·699 words·4 mins·
Author
Nick Dumas
Table of Contents
blogging-with-quartz - This article is part of a series.
Part 3: This Article

What am I Doing?
#

As I write more posts, I realize I’m writing groups of posts that are narratively linked, to speak. The best example is this series, Blogging with Quartz. There are others, but I’m still working on a system for cross-linking between posts. More on that later.

I also realized that there’s simply no way to view anything but the most recent N posts on the index page. I’ve forgotten what the current value of N is but that’s neither here nor there.

Users can’t navigate free. The closest they can get is walking the tag graph and hoping that gets them somewhere.

Why does it work?
#

Quartz is great, looks awesome and uses Hugo which means its super configurable. The templates are powerful and very polarizing.

Why doesn’t it work?
#

Quart’s layout seems to be build around organize discovery of notes through hand crafted landing pages. For the blog, I’m not interested in that. I want users to be able to page through my posts backwards and forwards chronologically like any actual blog site.

Quartz has tags but it lacks a way of saying “These posts aren’t chronologically adjacent but they form a sequence”. It looks like most tools call this a “series” of posts, so that’s what I went with.

Making it happen
#

Chronological Adjacency
#

Hugo helps us here by providing page variables specifically for this: Next and NextInSection. This partial ends up being really straightforward. It’s also got a style, pagination that I’m going to leverage.

    {{partial "prev-next.html" .}}

Just a few if statements and calling .Permalink to get a URL. I chose to use the *InSection variants because I probably will be introducing more content types over time and I may as well fix this beforehand. Below is layouts/partials/prev-next.html

{{ if or .NextInSection .PrevInSection }}
<nav class="pagination">
    {{ if .PrevInSection }}
    <ol>
        <li>
            <a href="{{ .PrevInSection.Permalink }}">
                <span class="button__icon"></span>
                <span class="button__text">{{ .PrevInSection.Title }}</span>
            </a>
        </li>
        {{ end }}
        {{ if .NextInSection }}
        <li>
            <a href="{{ .NextInSection.Permalink }}">
                <span class="button__text">{{ .NextInSection.Title }}</span>
                <span class="button__icon"></span>
            </a>
        </li>
    </ol>
    {{ end }}
</nav>
{{ end }}

There’s also a small block of custom CSS, necessary to reset some padding and make the links flow horizontally with a bit of a margin to keep them legible. Shown is a portion of asset/styles/custom.scss.

...
nav.pagination {
                border: 1px solid black;
                ol {
                        padding-inline-start: 0px; 
                }
                li {
                                margin: .25em;
                                display: inline-block;
                }
}
...
Two links pointing to a post published before this one titled 'Ashes to Ashes, Buffs to Buffs', and one published later titled 'Never forget is_alert_recovery'
Pretty snazzy, right?

Planning for the Future
#

Tags are cool, but they don’t tell a story. My ambition vastly outstrips my talent and so no project I undertake will ever fit in a single post.

To that end, I put this together. I definitely got this from somewhere, but I can’t remember where now. Sorry. Another very simple invocation.

    {{partial "series-header.html" . }}

This generates a short list linking to all the other posts in a given series.

{{- if .Params.series -}}
{{- with index (.GetTerms "series") 0 -}}
<div class="post-series notice--info">
        <h3 id="series">This post is part of the <a href="{{ .Permalink }}" style="font-weight: bold">{{ .LinkTitle }}</a> series.</h3>

    {{- end -}}
    {{- $series := where .Site.RegularPages.ByDate ".Params.series" "intersect" .Params.series -}}
    {{- with $series -}}
            <ol>
                {{- range . -}}
                <li>
                    {{- if eq .File.UniqueID $.File.UniqueID -}}
                    <b>{{ .Title }}</b>
                    {{- else -}}
                    <a href="{{ .Permalink }}">{{ .Title }}</a>
                    {{- end -}}
                </li>
                {{- end -}}
            </ol>
    {{- end -}}
</div>

{{- end -}}

notice--info just pulls a color from the base definitions. It ads a little visual pop.

...
.notice--info {
    @include notice(var(--primary));
}
...
Screenshot of text on a website describing an article and its membership in a series called 'blogging-with-qurtz'
You can even click the name to take you to a list of the rest of the posts in the series

Webdev is tedious
#

I’d love to be able to test this locally. It only takes approximately thirty seconds from pushing a change to having a fresh build of the site, but that’s still hella slow when you’re trying to rapidly iterate on CSS and stuff.

I’m really happy with how this looks, though, and I’m excited to keep tweaking things. I’ve got 30 tabs open with Hugo templates and toolkits that I’m gonna rifle through and try to find inspiration in.

blogging-with-quartz - This article is part of a series.
Part 3: This Article

Related

Gardening with Quartz
·1660 words·8 mins
When you want a container built right, you have to do it yourself.
Automating Caddy on my DigitalOcean Droplet
·712 words·4 mins
Automation ambitions fall flat
Copying HTML files by hand is for suckers
·1186 words·6 mins
How I built a drone instance and pipeline to publish my blog