{blogdown}: add metadata to Lithium-themed posts

blogdown
hugo
r
yaml
Author
Published

September 6, 2019

Lithium metal burning. It swells and looks a bit like forbidden cauliflower at one point.

Modifying lithium metal with heat (via Giphy).

tl;dr

Add author name, categories and tags to the posts of your Lithium-themed {blogdown} site. Might work for other themes.

Note

This blog is no longer made with {blogdown}. It uses Quarto instead.

Lithium

This blog is generated using Yihui Xie’s {blogdown}, which is built on the Hugo framework.

A number of site-wide themes have been ported for use with {blogdown}. This site uses the clean and simple Lithium theme by Jonathan Rutheiser, modified for {blogdown} by Yihui.

The Lithium template doesn’t display author names, categories and tags by default. I’ve been adding author names manually and the number of posts is large enough now that exploring categories and tags is worthwhile.

I initially found it tricky to add these bits of metadata to each post, so I’m recording it here.

YAML

You provide metadata for your posts in the YAML header (YAML is just some human-readable code often used for configuration). The information can then be extracted and presented on the front-end. The ‘Update Metadata’ option from the {blogdown} RStudio addin is useful for making changes to the YAML.

Here’s the YAML for the post you’re reading currently:

---
title: '{blogdown}: add metadata to Lithium-themed posts'
author: Matt Dray
date: 2019-09-06
categories:
  - blog-meta
  - code
slug: lithium-metadata
tags:
  - blogdown
  - hugo
  - lithium
  - r
  - yihui
---

You need to make sure the author, categories and tags elements are completed before they can be extracted and displayed on your posts.

You need to update the files that specify the layout of your site, but where are they? And how do you translate these YAML elements into parameters that are understood in those files?

What’s missing where?

The basics of what you need to do is all laid out in the excellent blogdown: Creating Websites with R Markdown book by Yihui, Amber Thomas, Alison Hill.

The file describing the layout of your posts—the one you need to edit—is on this path: layouts/_default/single.html (see the default template).

It’s an HTML file, so has lots of things like <h1 class="article-title">. This is pretty classic HTML that declares a top-level header and a class that can be styled with CSS.

But what we really care about are the things that look like {{ .Title }}. The parameter names embraced in double-curly brackets refer to our YAML elements, but they don’t necessarily have the same name (title in YAML and .Title here, for example).

So <h1 class="article-title">{{ .Title }}</h1> will return the title of the post as an HTML header that will be styled as the article-title class.

Modifications

I hadn’t added the author name in the past because I wasn’t sure what the right parameter was. I found it in section 2.5.1 of the blogdown book: .Params.author.

This meant I could arrange some metadata at the top of my posts in the form Firstname Lastname / DD Mon YYY / X min read with the line {{ .Params.author }} / {{ .Date.Format "02 Jan 2006" }} / {{ .ReadingTime }} min read to get what I wanted.

Displaying categories and tags is trickier. It’s not just about finding the right parameters, but also involves looping through the categories and tags specified in each post’s YAML. Fortunately, the code is provided in section 2.5.2 of the blogdown book, under the bullet ‘Display categories and tags in a post if provided in its YAML’. It looks like this:

<p class="terms">
  {{ range $i := (slice "categories" "tags") }}
  {{ with ($.Param $i) }}
  {{ $i | title }}:
  {{ range $k := . }}
  <a href='{{ relURL (print "/" $i "/" $k | urlize) }}'>{{$k}}</a>
  {{ end }}
  {{ end }}
  {{ end }}
</p>

I slid this into my single.html file with some trial and error, using a <br> linebreak tag to split the categories and tags onto two separate lines.

Side by side

The default

A default Lithium-themed post with filler text, showing the date under the title and the reading time in a box in the upper right.

The default output for a Lithium-themed post is produced with the following single.html file:

{{ partial "header.html" . }}

<main class="content" role="main">

  <article class="article">
    {{ if eq .Section "post" }}
    <span class="article-duration">{{ .ReadingTime }} min read</span>
    {{ end }}

    <h1 class="article-title">{{ .Title }}</h1>

    {{ if eq .Section "post" }}
    <span class="article-date">{{ .Date.Format "2006-01-02" }}</span>
    {{ end }}

    <div class="article-content">
      {{ .Content }}
    </div>
  </article>

  {{ partial "disqus.html" .}}

</main>

{{ partial "footer.html" . }}

Modified

Below is what the updated posts look like. Note that I’ve also updated the styles and fonts as well as the layout. You can read a previous post about how to update the typeface.

A post showing the modified Lithium theme on this blog, with the author, date, reading time, categories and tags under the title.

My modifications to the Lithium layout in the layouts/_default/single.html file:

{{ partial "header.html" . }}

<main class="content" role="main">

    <h1 class="article-title">{{ .Title }}</h1>

    {{ if eq .Section "post" }}
    <span class="article-meta">
      {{ .Params.author }} / {{ .Date.Format "02 Jan 2006" }} / {{ .ReadingTime }} min read <br>
      {{ range $i := (slice "categories" "tags") }}
      {{ with ($.Param $i) }}
      {{ $i | title }}:
      {{ range $k := . }}
      <a href='{{ relURL (print "/" $i "/" $k | urlize) }}'>{{ $k }}</a>
      {{ end }}<br>
      {{ end }}
      {{ end }}<br>
    </span>
    
    {{ end }}
    
    <div class="article-content">
      {{ .Content }}
    </div>

  {{ partial "disqus.html" .}}

</main>

{{ partial "footer.html" . }}

Note that I created the new class article-meta to control the styles for this metadata block.

Improvements

Let me know if this is worth optimising. Like I say: it was trial and error, really.

Thanks to Maëlle Salmon for pointing out the correct filepath at which to edit the single.html file. I also recommend you check out Alison Hill’s tweet reminder of which {blogdown} folders you should and shouldn’t modify within.

Environment

Session info
Last rendered: 2023-07-24 20:33:40 BST
R version 4.3.1 (2023-06-16)
Platform: aarch64-apple-darwin20 (64-bit)
Running under: macOS Ventura 13.2.1

Matrix products: default
BLAS:   /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/lib/libRblas.0.dylib 
LAPACK: /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/lib/libRlapack.dylib;  LAPACK version 3.11.0

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

time zone: Europe/London
tzcode source: internal

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

loaded via a namespace (and not attached):
 [1] htmlwidgets_1.6.2 compiler_4.3.1    fastmap_1.1.1     cli_3.6.1        
 [5] tools_4.3.1       htmltools_0.5.5   rstudioapi_0.15.0 yaml_2.3.7       
 [9] rmarkdown_2.23    knitr_1.43.1      jsonlite_1.8.7    xfun_0.39        
[13] digest_0.6.33     rlang_1.1.1       fontawesome_0.5.1 evaluate_0.21    

Reuse

CC BY-NC-SA 4.0