brainbaking/content/post/2022/01/generating-a-blogroll-with-...

5.5 KiB

title date categories tags
Generating a Blogroll With OPML in Hugo 2022-01-20T20:16:00+01:00
webdesign
hugo

Blogrolls have been on my mind lately. It's a rather fancy word for a more common but far from mundane corner of your website, called a links section. Ever since my first website in 1998---you can marvel at my old junk at the Brain Baking Museum---I've had a links section. But for some reason, on the latest revision of this site, it's been gone for years.

A links page is fun for a couple of reasons:

  • It shows what the website owner is interested in;
  • It's a chance to give a shout-out to fellow websiters (if I'd type blogger here, I'd be too limiting);
  • It can be used to play the im-bored-lets-click-through-stuff game (isn't that the purpose of those webrings?).

Especially since I've been encountering my own site in the midst of the links of others (thank you!), I felt a bit bad for not returning the favor. Enter the /links page!

After getting nostalgic (again...), I rummaged through my digital archive to dig up my 2007 browser bookmarks. It's a lot of fun to scroll through and instantly gives an impression of what I was up to back then (Infinity engine game modding, Nintendo DS programming, Wizardry 8 guide writing, retro gaming, BSD and Linux kernel programming, Magic the Gathering, hip-hop).

So much yet so little has changed! It's a bit embarrassing. Or should I be proud? I'm not sure. I feel a bit conflicted when looking back at it. Like Brit Butler wrote in "Deliberate Action":

A tremendous amount has happened, but I feel like I've lost the boy I remember from college a little. He was excited about things: video games, music, common lisp, poetry.

Anyway. As Ruben would write: I digress.

Hugo and XML parsing

Since nowadays I manage my digital intake via my RSS reader, which already contains an XML-based list of links in an .opml file, I took a stab at automating this process.

Recently, Hugo implemented XML Data support (part of the 0.92.0 release). This means chucking an XML file in /data automatically exposes it in the template engine, making iterating over entries using {{ range $.Site.Data.blogroll.body.outline }} trivial. Or so I thought.

The supplied example in the commit message of the patch is very brief and only covers retrieving contents of XML tags: <title>sup</title> can be accessed via the not-so-special {{ .title }} shortcode, as it becomes a Go property. But OPML outline XML is something like this:

<outline text="Brain Baking" title="Brain Baking" description="" type="rss" version="RSS" htmlUrl="https://brainbaking.com/" xmlUrl="http://brainbaking.com/index.xml"/>

All attributes, no content: the outline tag is auto-closed (/>). I had no clue how to fetch that data, as dumping the entire variable printed a map of keys prepended with a dash. Why? It seems that someone else submitted an issue to the hugoDocs repository, so I took the effort to summarize changes into a pull request. Accessing properties, apparently, is done via {{ index $body.outline "-title" }}.

I've never used Hugo's index function before. Having to prepend attribute names with - feels awkward. I presume the changes are still young and a bit untested. Hopefully it'll evolve and stabilize over time. The problem right now is a total lack of documentation. Hopefully this blog post helps alleviate the problem a bit.

NetNewsWire OPML exports

Where does the OPML file come from? NetNewsWire keeps track of local subscriptions ("On My Mac") in a file somewhere (/Users/me/Library/Containers/com.ranchero.NetNewsWire-Evergreen/Data/Library/Application\ Support/NetNewsWire/Accounts/OnMyMac/Subscriptions.opml). Copying over suffices, but of course does not auto-update when I add more feeds in the reader. Other options I've considered:

  • Softlinks. Nothing but trouble while committing into git, tried a lot of different approaches;
  • Hardlinks. Borked in MacOS. As soon as NetNewsWire makes a change, the hardlink is severed;
  • Third party hardlink cmd-based solutions. Didn't work;
  • Write a script that parses it into JSON and add to the CI. Too complicated;
  • Add a stupid copy command into the user's crontab.

The last option is currently in use, although not ideal. Oh well.

Another problem is the lack of metadata, or description information. The /links page contains little information of the link itself that way, especially if the blogger's <title/> tag is a bit... woozy. Like, "Articles", for instance. Any RSS feed, such as mine, contains a (proper) title and description:

<channel>
    <title>Brain Baking</title>
    <link>http://localhost:1313/</link>
    <description>Freshly Baked Thoughts by Wouter Groeneveld </description>
    ...
</channel>

It somehow doesn't get saved into the OPML, although there's a description tag---it's hardcoded to the empty string. Why? I'd love to hack away in the Swift code but could use some help.

Bonus material

Hey, this site also supports dark mode from now on! It seems to be a thing and after discovering MacOS Montery's "Auto" Appearance switch setting, I couldn't resist. Enjoy!