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.
Workarounds for relative links#
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:
- Run Pelican twice, with a separate run with Markdown toc disabled for the feeds.
- Try to somehow modify Pelican and Markdown toc to generate those links with absolute URLs.
- 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.