Jacob Kaplan-Moss

Today I Learned…

How to make a TIL section in Hugo

I want to add a TIL section to my blog, like Simon’s, for rough, unpolished, mostly technical stuff. It should be separate from the main blog post and feeds – only show up at /til.

I sort of already know this but documenting the steps as a way of reminding myself and testing out a TIL section.

Conceptually, creating new sections in a Hugo blog is easy: Hugo mirrors the output structure from the input structure. So to create jacobian.org/til, I just need to make a content/til directory and put stuff in there. But there ended up being a few other steps to get this looking the way I wanted:

  1. Created content/til/how-to-make-a-til-section.md (this document) to test this out.

  2. Note that it shows up on the home page, not what I want.

  3. The Hugo way of doing this is to set up main sections and filter in layouts/index.html. So in config.toml, I added:

    mainSections = ["posts"]

    And in layouts/index.html, changed {{ range first 5 .Site.RegularPages }} to {{ range first 5 (where .Site.RegularPages "Type" "in" .Site.Params.mainSections) }}

    đŸ‘Œ, this TIL no longer shows up on the home page.

    TILs already don’t show up on /posts because of how Hugo organizes content.

  4. /til already exists – since it picks up layouts/_default/list.html. It looks bare-bones, but it works. Right now I just want to change the page title (from “Tils”, which is Hugo’s attempt to humanize the til directory name). So I made a layouts/til/list.html which Hugo will pick up instead of the default (by matching the content directory name, til). I copied that template from layouts/_default/list.html, and changed the title. Later I’ll do more work on the template – I think I want to sort by tag, like Simon does.

  5. The HTML head <title> is also wrong. So I added a html-title block to baseof.html, and overrode it in layouts/_default/list.html. (I thought maybe I could override the title in the section via a content/til/_index.md or index.md, but that doesn’t work, see this forum post.)

  6. Similarly I want to make some light changes to the detail template: mostly just adding a “Today I Learned…” header for now, but also to give myself a space to mess with the design of TIL pages later on. So I made layouts/til/single.html, copied from layouts/_default/list.html, and made some tweaks. This ends up with a fair amount of code duplicated from layouts/_default/list.html, which I don’t love, and since Hugo’s template inheritance isn’t as sophisticated as Django’s I can’t fix it they way I would with Django. For now I’m going to leave it alone; in the future, if I need to refactor, I could reduce duplication with partials.

  7. I don’t want TILs to show up in my main RSS feed. So I edited rss.xml to add a where clause, as in Step 3 above. This involved a bit of a re-write of that template since the default code, which I think I cribbed from Hugo’s built-in default template, was confusing and hard to read.