5.8 KiB
title | date | categories | tags | |||||
---|---|---|---|---|---|---|---|---|
Generating a Blogroll With OPML in Hugo | 2022-01-20T20:16:00+01:00 |
|
|
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.
Addendum, 31th March 2022: Auto-generating decent links proved to be too difficult. The addition of a self-hosted RSS-Bridge, which allows me to generate RSS feeds based off Instagram/Twitter feeds, proved to be too much. The resulting list of links is a nondescript mess. In the end, I decided to curate the /links
page manually.
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!