Once I got my YAML book list set up, I couldn’t stop thinking of different uses for it. Although I’m mainly using it to generate reading lists for specific workshops, I thought it would be useful to also generate a full reading list or bibliography.
In this tutorial, I’ll extend the code from Part 1 and Part 2 to retrieve and display all the books, arranged by subject. To follow along, you’ll need the following files from those earlier tutorials:
books.yaml
book-link.html
Step 1 - Create a Bibliography shortcode
First create layouts/shortcodes/bibliography.html
, then copy and paste the following code:
{{ $subjects := slice }}
{{ range $key, $book := .Site.Data.books }}
{{ range $book.subject }}
{{ $subjects = $subjects | append . }}
{{ end }}
{{ end }}
{{ $subjects = $subjects | uniq | sort }}
{{ range $subjects }}
{{ $currentSubject := . }}
<h2>{{ . }}</h2>
<ul class="book-list">
{{ range $key, $book := $.Site.Data.books }}
{{ if in $book.subject $currentSubject }}
<li>{{ partial "book-link.html" $book }}</li>
{{ end }}
{{ end }}
</ul>
{{ end }}
Here’s a breakdown of what’s happening in this code:
Lines 1-7: Collect and prepare all subjects
{{ $subjects := slice }}
Creates an empty array to hold all the subject values.
{{ range $key, $book := .Site.Data.books }}
Loops through every book in books.yaml
.
{{ range $book.subject }}
For each book, loops through its subject array (since books can have multiple subjects like ["Project Management", "Productivity"]
).
{{ $subjects = $subjects | append . }}
Adds each subject to the $subjects
array. At this stage, you’ll have duplicates - if there are 5 books about “Productivity”, you’ll have “Productivity” listed 5 times.
{{ $subjects = $subjects | uniq | sort }}
uniq
removes duplicates (5 instances of “Productivity” become just 1)sort
alphabetises them
Lines 9-20: Display books organized by subject
{{ range $subjects }}
Loops through each unique subject.
{{ $currentSubject := . }}
Stores the current subject in a variable so we can reference it in the nested loop below.
<h2>{{ . }}</h2>
Creates a heading with the subject name.
<ul class="book-list">
Opens an unordered list for this subject’s books with a class
that you can style.
{{ range $key, $book := $.Site.Data.books }}
Loops through all books again. The $
ensures we’re accessing the full site context, not just the current loop’s context.
{{ if in $book.subject $currentSubject }}
Checks whether the current book’s subject array contains the subject we’re currently displaying.
<li>{{ partial "book-link.html" $book }}</li>
If the book has this subject, displays it using the DRY partial from Part 2.
In summary: Collects all unique subjects from your books, sorts them alphabetically, then creates a section for each subject with all matching books listed underneath.
Step 2 - Insert the Bibliography shortcode
Create a page where you want your bibliography to appear (e.g., content/bibliography.md
), then add your shortcode:
{{< bibliography >}}
When Hugo builds your site, it generates a complete bibliography with all your books organised by subject 🎉
Conclusion
This approach is a simple way of generating a reading list that you can update in one place, then display in different formats. For a slightly more sophisticated version, take a look at my kit list, where I’ve added descriptions and slightly fancier styling. This example exemplifies the flexibility of Hugo. I hope you enjoy yourself with it as much as I did.