A few days ago, I remarked that I have not added webmentions to this blog because they would add too much overhead to the build time. When I wrote this post, I was thinking about only one way to add webmentions to my Jekyll site. I was thinking about a Jekyll plugin that retrieves all of my webmentions, sorts them, and then adds them to all of my posts. I thought it could maybe function with a front matter integration. I did not do too much research.
I’ve been thinking about webmentions more over the last few days. I like sending webmentions. If I am ever bored, sending a webmention keeps me occupied. I send my webmentions manually. I like the ritual of creating a markdown file, writing a webmention, and sending it using Telegraph. Many of the sites to which I have sent webmentions display them on their sites. I like seeing what other people have said about a post.
Rethinking My Approach
I considered using the Jekyll webmention plugin built by Aaron Gustafson. I decided against using it because it supports way more features than I need. I decided that building my own webmention extension would be both entertaining and a good way to pass the time.
My new approach relies on a Python script. I did not create a Jekyll plugin because I don’t really need to collect my webmentions every time I build my site. I spend quite a bit of time running my site locally. The shorter I can keep each build, the better. This Python script must be run independently from my Jekyll build but that’s not a problem.
My Python script retrieves all of my webmentions from the webmention.io service. I do this using the following URL:
I found this endpoint while viewing the [webmention.io documentation](https://github.com/aaronpk/webmention.io#find-all-links-to-your-domain). It's important that I collect all the webmentions in one request. I already have upwards of 100 posts on my site and I don't want to make 100 separate requests to retrieve webmentions for my site.
In my Python script, I filter through these webmentions and retrieve a list of all URLs that are posts. I do this by looking for "2020" in the slug of each webmention target. Next, I create a dictionary with these webmentions. I iterate through the original list of webmentions and add each webmention to its respective page.
When I am done, I have a dictionary that looks like this:
“/2020_09_24_post-title”: [ webmentions… ],
“/2020_09_25_post-title”: [ webmentions… ],
I write each entry to its own file. These files are stored in a directory called `_data` in Jekyll. I'll come back to this in a minute. Once the data files have been written, my script is completed. I have added the Python script to my `sh` script that builds my site and uploads its contents to my server. Whenever I build my site for the server, the following steps are followed:
1. Retrieve my webmentions and create the data files containing my webmentions
2. Build by site with the `jekyll build` command
3. The resultant `_site` directory generated by Jekyll is uploaded via FTP
You can view my full Python script [on GitHub](https://github.com/capjamesg/blog/blob/master/get_webmentions.py).
## Jekyll Data Files
Jekyll lets me store data in JSON in a directory called `_data`. This is facilitated through a feature called [Jekyll data files](https://jekyllrb.com/docs/datafiles/). I can access this data using `site.data` throughout my website. On my post template page, I have a tag that calculates the name of the file with my webmentions data for a particular post:
This tag creates a variable called
page_view_url . This variable contains a slugified version of my post URL. The format of the value that this variable has correlates to how I store data in my data files.
To retrieve my webmentions, I use
site.data[page_view_url]. This finds the file with the name that I have calculated and retrieves its contents. I can now access all of my webmentions on each post page so that I can render them.
My motivation behind adding webmentions is that I want to facilitate a bit more conversation on my site. It was not clear that my site supports webmentions. Most of the webmentions I have received are likes or bookmarks. When I go to send a webmention, I like to make sure that the website to which I’ll send the mention supports the webmention protocol. That is unclear on my site. I probably wouldn’t send a webmention to my own site until I made these changes.
On each post page, there is a section for webmentions. This section appears after the post and before the “About this site” section. I added in a title for the final section to make my markup more accessible. If I didn’t add this title, the final webmention would lead on to narrate the permalink and categories for the post if a visitor uses a screenreader. The title helps divide my content up.
I am confident that I’ll stick with this approach. Because my Python script is programmed to run whenever I upload my site to my web server using my build script, I don’t have to think about generating webmentions. If I receive a lot of mentions, I may run into some performance issues. My setup works for now and that is all that matters. Off the top of my head, I’d probably filter out all “likes” and “bookmarks” if I had those issues and only display comments. I’m getting ahead of myself.
My site is now fully webmention compliant. Send me a webmention to say hello! I recommend reading Aaron Parecki’s guide on how to send a webmention if you have not already done so. I found myself referring to this guide when deciding how my webmentions should appear on my website.