+
We are excited to announce Grafana Labs is to acquire Kausal. Read more

Fancy Blog Post Headers with Avatars for Hugo

Twitter profile image
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!

Kausal's mission is to enable software developers to better understand the behaviour of their code. We combine Prometheus monitoring, log aggregation and OpenTracing-compatible distributed tracing into a hosted observability service for developers.
Contact us to get started.