djcev.com // article


Receiving Webmentions with Blogofile and a little scripting

Posted by Cameron Vanderzanden on . Tagged meta, python, software, website. 3 responses.

A common downside to static websites (like this one) is that there's no easy way to handle user interaction. Comments, likes, trackback / pingback / mention, etc. . A bunch of third-party systems exist that solve this problem, the most popular probably being Disqus. Disqus relies on browser javascript (which I strongly dislike) and has a rocky history with user privacy, so it's not something I'm willing to use. Most of the other comment systems available also require javascript so, again, not willing to use.

But I still kind of want a way for visitors to leave comments and, more broadly, for my site to interact with other websites. Enter the IndieWeb community of web developers and their associated standards and projects, notably Webmentions.

Microformats, IndieAuth, and Webmentions

So from this point forward we're getting into web developer word soup. I'm going to be skipping over some details for the sake of brevity and because there's a more interesting technical problem up ahead.

Microformats are an extension to HTML markup used to simplify machine processing of webpages. IndieWeb services like IndieAuth, webmention.io, and brid.gy rely on microformats. I followed the documentation on h-card and h-entry as well as Daniel Goldsmith's Embracing The Indieweb article to implement microformats in my blog templates. To see what I've done I suggest taking a look at the class="" attributes in the source of this page.

IndieAuth is a (quoting the IndieAuth wiki page) federated login protocol for Web sign-in, enabling users to use their own domain to sign in to other sites and services. It's used to authenticate to IndieWeb services and makes use of the RelMeAuth microformat to verify identity. To support it I host a copy of SelfAuth as my authorization endpoint. (That's now the one not-static part of this website).

Webmentions are an inter-website notification mechanism commonly used for a website to let a target website know it has a webpage with content that references the target. A "mention" is a typical social media interaction like a "like", a "reply", and so on. I spent some time looking for a small webmention endpoint I could host and didn't find one, so I'm using the third-party service webmention.io.

Receiving, Storing, and Displaying Mentions

At this point I have webmention.io receiving mentions on behalf of my site. Now the problem is: how do I hook that into my static site compiler? Fortunately that turns out to be a frequently asked question with many well-documented answers. I found this post by Deluvi particularly helpful, it outlines the basic process I ended up using.

The idea here is to write a script that downloads mentions from webmention.io and then stores them locally. This script can be run on a schedule (say once a day) to retrieve new mentions. Then when I rebuild my website the site compiler (Blogofile in my case) will look for stored mentions and render them with their associated pages.

Webmention-tools by Ryuno-Ki got me started (I used their WebmentionIO class) and webmention.io's README took me the rest of the way. My script mentions.py queries webmention.io and then stores the resulting JSON data in individual files named after the "wm-target" or "in-reply-to" URL (after a little text processing). A mention file might be called "2021-06-receiving-webmentions.json" for example. My script is a mess and not very well thought out; I present it here as an example, a proof-of-concept.

The next step was to make some additions to the part of my static site compiler that handles posts, _controllers/blog/post.py. I copied over the file naming function from mentions.py, added a "Mentions" class to represent individual mentions, then wrote a few functions to read mentions stored on disk into a list associated with the post, and hooked that all into the Post constructor method.

Now mentions are available to the blog post template as "post.mentions". The final step was to add the necessary logic and markup to the post template to display the mentions. This is all currently implemented and working. You may see some test mentions counted in the header of this post and see the mentions themselves rendered in the single-post view of this article.

Closing

There are quite a few things I still need to do. It would be good to make my changes to blogofile available, for one. I should also probably write a commenting guide and privacy policy. And the reliance on webmention.io is concerning, I'd like to write a replacement for it suitable for self-hosting. I also haven't written an automated way to send webmentions; I suspect that may be a more difficult problem to solve.

But this is enough for now, I think. A good first pass.

Responses

Anonymous replied on :

This is an anonymous test message sent through quill.p3k.io with commentpara.de for authentication using the "write comment" button below.

Anthony Kepler replied on :

All very interesting. Thank you for the summary of these many different indie things and for making yourself an effective test bed. I will probably make use of some of these ion future projects.

If you've written a response to this post then please let me know the URL:

You can also submit a "comment" webmention by pressing the button below. It may take a day or two for your comment to appear here and a copy of your comment will be stored at commentpara.de.