DEV Community

Ana Ulin 😻
Ana Ulin 😻

Posted on • Originally published at anaulin.org on

Adding Structured Book Data to My Blog Posts

I’ve been slowly working on taking more control over my own data, extracting it from corporate silos and keeping my own copies of it. One piece of this effort is making myself less dependent on Goodreads, which I’ve used for some years to track my reading and get inspiration from my friends’ reading. I enjoy the social and discovery aspects of Goodreads, but I don’t love that it is owned by Amazon and only gives you partial access to downloading your data. So I’ve been getting more consistent in posting my reading notes as blog posts to this site, and linking from my Goodreads reviews to those posts.

In order to keep collecting structured data about my reading , I’ve started adding it as metadata to the frontmatter of my reading notes entries. In the frontmatter of each post, I include a book section which contains the metadata I’m interested in (title, author, dates read, ratings, etc). This serves as a simple database for my reading, and I can autogenerate some of the content of reading posts from this data.

For example, the frontmatter for my recent notes on Are Prisons Obsolete? looks like this (in toml format):

+++
title = "Book Notes: Are Prisons Obsolete?"
date = 2020-08-15T15:26:53.454775
tags = ["books"]

[book]
title = "Are Prisons Obsolete?"
author = "Angela Davis"
url = "https://bookshop.org/a/6402/9781583225813"
start = 2020-08-11
end = 2020-08-14
rating = "5"
image = "/img/book-are-prisons-obsolete.jpg"
+++

In the Hugo template for a post, I use this metadata to generate a little card with the info for the book. I have a separate book.html partial template that I use for this, which gets invoked both by the standalone post template and the RSS feed template, if there is a book element in an entry. A simplified version of this Hugo template looks like:

{{- $title := index .Params.book "title" -}}
{{- $author := index .Params.book "author" -}}
{{- $rating := index .Params.book "rating" -}}
{{- $image := index .Params.book "image" -}}
{{- $url := index .Params.book "url" -}}
{{- $start := index .Params.book "start" -}}
{{- $end := index .Params.book "end" -}}

<div class="book-card">
  <a href="{{ $url }}"><img src="{{ .Site.BaseURL }}{{ $image }}"/></a>
  <br/>
  <a href="{{ $url }}">{{ $title }}</a> by {{ $author }}
  <br/>
  Read {{ $start.Format "Jan 2, 2006" }} - {{ $end.Format "Jan 2, 2006" }}
  <br/>
  {{ "⭐" | strings.Repeat $rating }}
</div>

I like how simple this is to understand and to maintain, and I’m excited about the possibilities it opens up. Now that I have reading data in a programmatically-accessible format, I can use it to compute reading stats, or to automatically build a standalone page listing books read. My next step will likely be importing all of my Goodreads data (or as much as I can get) into this format.

Top comments (0)