A Weird Imagination

Relative links in feeds

The problem#

In an RSS/Atom feed, relative links are a bad idea because it's unclear what they're relative to. There are ways to specify a base for them to be relative to, but since feed readers do not consistently respect those mechanisms, it's safer to just always use absolute URLs in feeds. And Pelican recommends setting RELATIVE_URLS = False to always generate absolute URLs. But that setting does not apply to the anchor links generated by the Markdown toc extension to link to headers.

The solution#

I wrote a Pelican plugin, absolute_anchors which rewrites all link destinations starting with # in every article to add the absolute URL of the article at the beginning of the link.

The details#

Markdown toc#

I recently enabled the Markdown toc extension option to add a link next to every header that links back to that header, since I wrote a blog post where I wanted to link to a section of another blog post and I figured it would be nice to make those links easily accessible for anyone. But the fact that those links are relative links caused problems.

Initially, as I noticed that the links didn't work right on the main page of the blog (or any other page showing multiple posts), I modified the theme to use CSS to hide the links on those pages. But then I noticed that they appeared in the feed as well. As feeds don't have CSS, there was no way to hide them. And, at least in my feed reader, they didn't properly jump within the document.

I considered multiple options:

  1. Run Pelican twice, with a separate run with Markdown toc disabled for the feeds.
  2. Try to somehow modify Pelican and Markdown toc to generate those links with absolute URLs.
  3. Write a Pelican plugin to rewrite the URLs.

The third option seemed the simplest.

Writing the plugin#

I had previously written a similar plugin, summary_footnotes, so I copied it and modified it to just always prepend the article URL to links starting with #.

My first version successfully rewrote the pages on the website and the summary section of the feed, but surprisingly not the content section. It turned out that the issue was that I had copied the code to intercept the summary property and intercepted the content property in the same way. Looking at Pelican's source, I figured out that content is implemented via calling get_content() and when generating feeds, Pelican calls get_content() instead of using the content property. The fix was to instead intercept the _update_content() method which is used to implement get_content().

Breaks fancy footnotes?#

Apparently, Feedbin detects footnotes and renders them differently. By making the URLs for footnotes absolute, that feature will presumably no longer work.

Comments

Have something to add? Post a comment by sending an email to comments@aweirdimagination.net. You may use Markdown for formatting.

There are no comments yet.