Fancy Blog Post Headers with Avatars for Hugo
on Sep 1, 2017
What better way to start a blog than a post about blog headers. Our blog (and website) is built with Hugo, a static website generator. This post shows how we configured the post layout to display nicely formatted headers with the author’s avatar.
Setting up a blog in Hugo
Posts in Hugo usually go in the content/post
directory.
Since these are blog posts (or a “section” in Hugo terms), we renamed content/post
to content/blog
.
Don’t forget to set pluralizeListTitles = false
in config.toml
, otherwise you end up with the page title “Blogs”.
Next we installed the Tachyons theme, to have a minimal CSS framework. Unfortunately the theme comes with an outdated version. If you place a new version of Tachyons in the theme, you run into trouble: The layout partials rely on the outdated class names. We did it anyway, and simply modified all layout classes to use the latest ones, mostly so we can rely on the latest Tachyons documentation.
Configuring the Blog page
Initially, we wanted to show the full posts when viewing the blog.
The rendering of the blog post should be the same whether you access it via the blog or a post’s permalink.
To make this happen, both the main loop in layouts/_default/section.html
and the single view layouts/_default/single.html
use the li.html
template:
Section template:
{{ partial "header.html" . }}
<main class="center mw7 mv4">
<h1 class="fw2 mid-gray ph2">{{ .Title }}</h1>
{{ range .Data.Pages.GroupByDate "2006" }}
{{ range .Pages }}
{{ .Render "li"}}
{{ end }}
{{ end }}
</main>
{{ partial "footer.html" . }}
Single template:
{{ partial "header.html" . }}
<main class="center mw7 mv4">
{{ .Render "li"}}
</main>
{{ partial "footer.html" . }}
Authors as Data
It would be really great if we did not have to specify the author’s full name, Twitter handle, and photo in each posting.
Hugo’s data
index to the rescue.
We simple create a yml
file for each author in data/authors
.
For example, my file david.yml
looks like this:
twitter: https://twitter.com/davkals
photo: https://www.gravatar.com/avatar/HASH
name: "David Kaltschmidt"
Now a posting can reference it via its frontmatter:
---
title: "Fancy Blog Post Headers with Avatars for Hugo"
date: 2017-08-26T13:58:10+01:00
author: david
---
Displaying the Author Avatar
The final piece is to configure the li.html
template to use the author data referenced in the frontmatter.
Here is our template:
<header class="mv4">
<h1 class="fw4 tc mb2">
<a class="black-60 dim link" title="Permalink: {{ .Permalink }}" href="{{ .Permalink }}">{{ .Title }} {{ if .GetParam "draft"}}[DRAFT]{{end}}</a>
</h1>
{{ $date := .Date.Format "Jan 2, 2006" }}
{{ with index .Site.Data.authors .Params.author }}
<div class="tc mt3">
<div class="tc black-40 dib center relative">
<img src="{{.photo}}" alt="Twitter profile image" width="40" height="40" class="br-100 absolute" style="top: -2px; left: -50px"/>
<a href="{{.twitter}}" target="_blank" title="{{.name}} on Twitter" rel="author" noreferrer class="link dim mid-gray">
{{ .name }}
</a>
<br /> on {{ $date }}
</div>
</div>
{{ end }}
</header>
This works as follows: .Params.author
gives you the frontmatter field author
, so in this case the value is david
.
That value is passed as argument to the data retrieval function index
, along with the path to the authors directory.
Then we use with
to change the context in that block to be the author’s data.
Inside the block we can reference the fields from the yml
file, e.g., .twitter
is the twitter
field.
The only thing we had to be careful about is the post date.
We had to save it to a variable as it was a property of the post, but was going to be used inside the author block.
Eh voilĂ , fancy headers!