Indieweb and webmentions for my static site
16 May 2022 | 10:47 am

My method to implement Indieweb principles and add webmentions support to my Jekyll site is probably the laziest of all. It enabled a decentralized reply system, as well as allowing reposts and likes.

The first time I’ve found about webmentions was when Silvia suggested an article by Chris Aldrich on A List Apart1. His article also brought the discovery of Indieweb and the concept of a small web, free from the corporate vision. It perfectly fit with the way I see the internet and communication in general.

A couple of years later, after I’d decided to leave social media2 and turn my WordPress blog into a static website, I chose not to implement a third-party commenting system. Instead, I went back to consider webmentions. A W3C standard, it’s a decentralized way to interact with other websites’ posts enabling replies, likes, reposts and more.

A Webmention is a notification that one URL links to another. For example, Alice writes an interesting post on her blog. Bob then writes a response to her post on his own site, linking back to Alice’s original post. Bob’s publishing software sends a Webmention to Alice notifying that her article was replied to, and Alice’s software can show that reply as a comment on the original post.

A list of tools and people who are using webmentions can be found on the IndieWeb wiki.

Implementing webmentions

I tried implementing webmentions through a once popular plug-in, but it never worked properly — probably because since the author has stopped using Jekyll it hasn’t been maintained. I had decided to do it manually and the process was not straightforward. Now that it’s been successfully implemented, I see where I was doing things the wrong way, but still this got me thinking. I guess it’s because I have problems with how sometimes hardcore developers document their code: I was totally in love with the concept, yet the information was not clear and scattered all over the place, which I found confusing and off-putting.

For transparency, I’m not criticizing the people who made this possible. Yet, I believe that many people, and not just the less tech-savvy, would be excluded by using webmentions because of the technical barrier3 — unless they use WordPress and can therefore install a plug-in.

It might be time for IndieWeb to rethink principles and priorities. The current list might appeal to developers, or people deeply emerged in utilizing social media silos, looking to ease their workflow, or their fears of losing their content, but it doesn’t necessarily talk to the ones looking to satisfy the call of creativity, or those disillusioned of social media itself. — Peter Molnar

The following step-by-step process works on a Jekyll-based website. For Hugo users check out this alternative.

Webmention.io and IndieAuth

Webmention.io is a free service software project created by Aaron Parecki. To log in I chose IndieAuth, which provides authentication for personal websites using existing social accounts.

IndieAuth.com is part of the IndieWeb movement to take back control of your online identity. Instead of logging in to websites as “you on Twitter” or “you on Facebook”, you should be able to log in as just “you”. We should not be relying on Twitter or Facebook to provide our authenticated identities, we should be able to use our own domain names to log in to sites everywhere.

IndieAuth required minutestomidnight.co.uk to have a link to providers such as GitHub:

<!-- Anywhere in the homepage <body> -->
<div class="h-entry">
  [...]
  <a rel="me" href="https://github.com/minutes2midnight/">Github</a>
  [...]
</div>

It’s possible to do the same with a <link> tag in the <head>, which would be invisible in the page. After checking that my GitHub account had a link back to my homepage in the profile settings, I entered the domain URL https://minutestomidnight.co.uk in webmention.io, which returned a confirmation screen. Note: the GPG method was added later.

IndieAuth screenshot after adding the GitHub link
IndieAuth screenshot after adding the GitHub link

After clicking the provider green button, I signed-in to GitHub to complete the authentication. This needed to be done once, or whenever I’m logged out from GitHub. Webmention.io dashboard was now up and running. Time to copy the code required to start accepting webmentions.

<link rel="webmention" href="https://webmention.io/minutestomidnight.co.uk/webmention" />
<link rel="pingback" href="https://webmention.io/minutestomidnight.co.uk/xmlrpc" />

I’ve added the above in an include file named site-head.html (source) which contains a block of code from the DOCTYPE declaration to </head>.

Microformats

To properly send and receive webmentions it’s necessary to markup the content using microformats2.

Other humans can already understand your profile information and the things you post on your site. By adding a few simple class names to your HTML, other people’s software can understand it and use it for things like reply contexts, cross-site comments, event RSVPs, and more.

h-card

An h-card is for marking up people and organizations, often used on home pages and individual blog posts. I have created two h-cards on my website, one for the homepage and a slightly different one for blog posts. As an example, here’s the one included in my homepage:

<!-- Anywhere in the <body> -->
<div class="h-entry">
  [...]
  <div class="visually-hidden">
    <div class="p-author h-card">
      <img class="u-photo" src="{{ site.url }}/assets/images/minutestomidnight-avatar-uphoto.png" alt="{{ site.title }}" width="48" height="48">
      <a class="p-name" href="{{ site.url }}" rel="author"><strong>{{ site.author.name }}</strong></a>
      <p class="p-note">{{ site.description }}</p>
      <p class="p-org">{{ site.title }}</p>
      <p class="u-email"><a href="mailto:{{ site.author.email }}">{{ site.author.email }}</a></p>
      <p class="p-locality">Milan</p>
      <p class="p-country-name">Italy</p>
    </div>
    <a class="u-url" href="{{ site.url }}{{ page.url }}">{{ site.url }}{{ page.url }}</a>
    <a rel="me" href="https://github.com/minutes2midnight/">Github</a>
    <a rel="me" href="https://www.linkedin.com/in/minutes2mid/">LinkedIn</a>
    <a rel="me" href="https://minutestomidnight.bandcamp.com/">Bandcamp</a>
    <a rel="me" href="https://soundcloud.com/minutes2mid">Soundcloud</a>
    <a rel="me" href="https://open.spotify.com/artist/250igOmtd9HCpGyXDWUcl9?si=d9t8bLC2QfG8iT1R3y9CAw">Spotify</a>
    <a rel="me" href="https://www.youtube.com/channel/UCXO3ZbalCLwCZwHk_UkDBHg/">YouTube</a>
    <a rel="me" href="https://www.flickr.com/photos/minutes2midnight/">Flickr</a>
    <a rel="me" href="https://indieweb.social/@m2m">Mastodon</a>
    <a rel="me" href="https://oreganodangereux.wordpress.com">WordPress (Italian)</a>
    <a rel="me" href="https://minutesto00.wordpress.com">WordPress</a>
    <a rel="me" href="https://minutestomidnight.medium.com/">Medium</a>
  </div>
  [...]
</div>

The h-card is wrapped in a div that’s hidden in the page but it’s machine-readable. Briefly:

  • The h-card contains all the author information, with data mostly populated from Jekyll’s config.yml.
    • p-author signals that’s me who’s writing the content.
    • p-name is the equivalent of a heading, in this case it’s also the name of the person or organization.
    • u-photo marks my avatar.
  • u-url is the current page’s permalink.
  • A bunch of rel="me" links, including the GitHub URL previously used to authenticate to IndieAuth.

Everything else is self-explanatory. The result of my h-card in a parser:

My homepage h-card as seen by Indiewebify
My homepage h-card as seen by Indiewebify

I had decided to have a modular h-card in pages and posts because I wanted to take care of all the authoral parts needed for machine readability, include it wherever needed and avoid cluttering the code. I also wanted to be able to show or hide these code bits on the page.

h-entry

The h-card, as well as all the other necessary microformats-tagged markup, must be enclosed in a block tagged4 as h-entry.

h-entry is the microformats2 vocabulary for marking up blog posts on web sites. It can also be used to mark-up any other episodic or time series based content. — Indieweb

Content sections that needed microformats tags:

  • dt-published for the date tag <time>.
  • p-category for categories and tags.
  • p-summary for the post/page excerpt.
  • e-content wraps the main content of the post/page.
  • u-syndication for links to other websites where I cross-post.
  • u-in-reply-to for reply types of webmentions.
  • u-like-of for like types of webmentions.
  • u-repost-of for repost types of webmentions.

There are other types of webmention — RSVP, bookmark, follow — but I don’t use them. Actually, I only use replies and likes.

Indiewebify.me

Indiewebify is a very well-done service that allows anyone to test IndieAuth implementations and validate h-card and h-entry before starting to send webmentions. It was pivotal to my successful implementation. Alas, I had discovered it late in the process: had it been more prominent in the documentation, it would have saved me a few hours of debugging.

Without indiewebify I don’t think I would have been able to even get started implementing any of this stuff. — David Yates

This is how I applied microformats classes to the post layout:

<!-- 1️⃣ Contains all the other microformats-enabled parts -->
<article class="h-entry">

  <!-- 2️⃣ Post category -->
  <span class="p-category">[...]</span>

  <!-- 3️⃣ Main heading -->
  <h1 class="p-name">[...]</h1>

  <!-- 4️⃣ Post excerpt -->
  <p class="p-summary">[...]</p>

  <!-- 5️⃣ At this point the post layout has a conditional block
  for webmentions, loaded if the post Front Matter has a `mention`
  value set to true. I'll go back to this in the next chapter. -->

  <!-- 6️⃣ Post date -->
  <time class="dt-published">[...]</time>
  
  <!-- 7️⃣ hcard, hidden -->
  <span class="visually-hidden">
    <span class="p-author h-card">
      <img class="u-photo" src="https://minutestomidnight.co.uk/assets/images/minutestomidnight-avatar-uphoto.png" alt="Minutes to Midnight's avatar" width="48" height="48">
      <a class="p-name" href="https://minutestomidnight.co.uk" rel="author"><strong>Simone Silvestroni</strong></a>
    </span>
    <a class="u-url u-uid" href="https://minutestomidnight.co.uk/blog/build-a-human-readable-rss-with-jekyll/" title="Permalink">Permalink: <em>A human-readable RSS feed with Jekyll</em></a>
    <time class="dt-published" datetime="2022-05-02T10:36:05+02:00" itemprop="dateCreated">2 May 2022</time>
    <data class="p-org" value="Minutes to Midnight"></data>
    <data class="u-email" rel="me" value="mailto:contact@minutestomidnight.co.uk"></data>
    <data rel="me" value="https://minutestomidnight.bandcamp.com/"></data>
    <data rel="me" value="https://github.com/minutes2midnight/"></data>
    <data rel="me" value="https://indieweb.social/@m2m"></data>
    [... other rel="me" URLs]    
  </span>
  
  <!-- 8️⃣ The written content of the post -->
  <div class="e-content">
    <p>[...]</p>
  </div>

  <!-- 9️⃣ In case of cross-posting, put here the external link(s) -->
  <a class="u-syndication" href="[...]">[...]</a>
  
  <!-- 🔟 Post tags -->
  <a class="p-category" href="[...]">[...]</a>
  
</article>

🚨 Note: the order in which these tags are added to the code — as long as they all are inside the h-entry — is irrelevant.

The following is a screenshot — cut to shorten the content — of a blog post parsed and validated by Indiewebify.

Indiewebify validation for a blog post
Indiewebify validation for a blog post

Comments as webmentions

As stated earlier, I’ve only been using webmentions in the form of replies and likes. The Indieweb doesn’t force anyone to adhere to a specific set of behaviors, so I chose to avoid turning my personal website into a social media feed. It’s okay for whomever does that: I initially wanted to achieve the same goal, only to realize later that’s too much noise for me. I left centralized silos for several reasons and the cluttered unreadable interface was one of them.

Notes

Even though I can use my blog posts to reply or like other people’s posts — as I’ve done here and here — I’ve recently decided to employ a second type of layout: notes. A common format in the Indieweb, this is how they’re defined:

A note is a post that is typically short unstructured plain text, written and posted quickly, that has its own permalink page.

My note layout is a shrinked version of the post layout. No Liquid logic, just an <article class="h-entry"> containing a subset of microformats: time, hcard and content. Advantages of using a note to send a reply webmention:

  • Fast to write.
  • Set as a Jekyll collection and excluded from both sitemap and navigation, it feels like a separate entity. Which is how I see comments on the web.
  • Short. Since the block tagged with e-content is what’s going to be fetched and printed on someone’s comment section, I like it to be straight to the point and as brief as possible. When I see webmentions that are basically complete long posts, I feel like they miss the point altogether.

When I start writing a note, I manually quote the person I’m replying to, link their name to their post and add u-in-reply-to. In case I’m responding to someone who mentioned me from their blog, I also quote my original post, so that my comment would also appear on my site as a reply to the previous mention. This is how I get a working comment thread.

A live example in my post about automation:

A comment thread made of webmentions
A comment thread made of webmentions

The permalink on my name leads to the single note, and although the URLs are stripped in the rendered webmention, they’re present in the source code:

[@wouter](https://brainbaking.com/notes/2022/05/11h17m44s06/){: .u-in-reply-to } I have now updated my [original post]({{ site.url }}/blog/automation-for-my-blog-publishing-workflow/) and printed the code from the shell [...]

Both mine and Wouter’s site will receive a webmention containing what I wrote in the e-content section of the note.

Send webmentions

I have two methods of sending webmentions:

  • Automatically after every deploy, using a Netlify plug-in. On each build, it checks the latest entry in my feed — posts and projects — and sends webmentions if detected.
  • Manually using Telegraph. Another free service built by Aaron Parecki, Telegraph does a great job.

Logging into Telegraph works the same as the other Indieweb services, it only needs my website to be correctly configured for IndieAuth. The dashboard has two tabs: one for finding links with potential webmention endpoints in a post, another for sending webmentions if I know both the source and the target URLs.

Telegraph dashboard showing the latest webmention I sent
Telegraph dashboard showing the latest webmention I sent

Pull webmentions

To receive webmentions I have simply implemented the popular webmentions.js by Fluffy. It pulls data from webmention.io, adding the results in a section of my website. The minified Javascript file is only loaded in posts where webmentions can be received.

I have an inclusion called pattern-responses.html where my comments code resides: the block of code <div id="webmentions"></div> at the bottom gets populated by the script in case webmentions are received.

To collect reactions from Mastodon, I connected my Fediverse account to Brid.gy. It backfeeds likes and comments to webmention.io. WordPress and Flickr accounts were also added to Brid.gy. I can post a photo in my website and syndicate to Flickr while also backfeeding likes and comments from Flickr back to my site.

Notifications

I monitor incoming webmentions using the RSS feed provided by webmention.io. The Mentions Feed section in the settings has two links. The bottom one, complete with my webmention.io token, is an Atom feed URL which I added to my RSS reeder.

I tried other venues to get webmention notifications, but I needed Max Glenister to show me the simplest solution.

Future improvements

  • I’d like to stop relying on a third-party service and especially Javascript, because it’s making comments not accessible if scripts are disabled and this makes me cringe. An alternative could be writing something in Ruby or trying Netlify functions.
  • Based on a fruitful debate on Mastodon, I think I’ll be removing avatars, likes and reposts from the comment section.
  • Since I started configuring micropub, I might want to use it for reply notes using one of the online clients. Not sure, not urgent.

Useful articles


  1. Webmentions: Enabling Better Communication on the Internet, published on A List Apart on July 19, 2018. 

  2. See my article Escape from social media and the follow-up Life after social networks

  3. See also: https://davidyat.es/2019/06/24/indieweb/#implementation-pain-points

  4. When I refer to tagged in this context I mean applying an HTML class. 


Reply via email


Automation for my static blog publishing workflow
9 May 2022 | 10:00 pm

How I’m currently managing writing new content in my Jekyll-based static blog, using Shortcuts on macOS.

Ever since I went live with a redesigned Jekyll-based website, I’ve been looking for ways to improve my publishing workflow. I prefer working with a static website rather than a CMS such as WordPress, yet there are methods to make this process more efficient. This is a work in progress, I’ll be adding new bits to this post in the future.

A few weeks ago I saw a few links posted on Mastodon about the frustrations of maintaining a static web site. Ru Singh argued about the complexity that takes away the pleasure of writing. A couple of follow-ups by Michael Harley, who uses Eleventy, and Luke Harris, who uses Hugo, showed different point of views while still aknowledging similar problems.

I can understand the issues, yet none of them particularly apply to me. However, it’s true that I’ve been honing my process more and more, looking for a way where ideally I would end up clicking an icon or dragging a file into a folder and a few seconds later the post would be ready. Read Taking Shortcuts by Robin Rendle to get what I’m talking about.

I thought about it and asked what are the most annoying parts of writing a new post? Arguably, the answer would be twofold: first, the Front Matter block, which is the top YAML-based section in a static site generator post; second, adding images.

My goals

  1. Streamline the process of writing new posts, where a sort of wizard would guide me throughout compiling all the repetitive bits until an editor appears and I just have to write the content.
  2. Improve the way I add images to a new post as much as I can. What I have in mind is to select one or more images, drag them onto an app and have them:
    • web-friendly renamed;
    • converted to WebP;
    • moved to _assets/images;
    • have a figure “shortcode” ready to be pasted in my post, complete with all the required info: width, height, alt text and caption.

Old method: Sublime Text and Alfred

Before, my automation involved two steps:

  • Creating a new post in Sublime Text using a Jekyll extension capable of creating simple templates.
  • Adding pre-compiled shortcodes using Alfred’s workflows.

It was a good starting point: I obtained a file already named after the post title and today’s date. I still had to manually fill in 6 empty fields in Front Matter. Same thing with Alfred’s shortcodes: handy yet missing vital bits, such as image width and height. After reading Robin’s post I thought I could vastly improve the method using macOS’ new Shortcuts app. I went as far as upgrading my OS to Monterey1.

New method: Shortcuts

I’ve been using Automator for years and I love it. After a couple of days fiddling with Shortcuts I noticed how it doesn’t always agree with me. It looks powerful, yet it sometimes feels buggy2 and convoluted, with a sub-par documentation. As usual with new things, it took me a while to understand how the new app thinks.

As of this writing, I have 3 automation processes that I’m happy about. They are exported as apps in ~/Applications and in my Quick actions contextual menu. A fourth one is still in its infancy and not yet ready.

Local applications folder with custom Shortcuts automation for Jekyll
Local applications folder with custom Shortcuts automation for Jekyll
Quick actions contextual menu showing Shortcuts
Quick actions contextual menu showing Shortcuts

New Jekyll post with Shortcuts

The following short video demonstrates the process in real time.

Note: when the Terminal is shown, there’s a Jekyll compile issue: that‘s my fault as I’ve done this video twice and forgot to delete the previous test post with the same title. 🙈

Here is the whole routine of the wizard:

Shortcuts app for creating a new Jekyll post
Shortcuts app for creating a new Jekyll post

Breakdown

  • 1️⃣ Asks for a post title and sets a variable using the input I provide in a pop-up.
  • 2️⃣ Same for the category.
  • 3️⃣ Same for a couple of tags (I can add more later if I need). It sets a variable containing an array of both my subsequent inputs.
  • 4️⃣ Asks for the description, which goes in my description field in Front Matter, used for SEO purposes.
  • 5️⃣ Same for the excerpt which gets printed below the main heading.
  • 6️⃣ Runs a bash script where the title variable is passed as an argument and does a few things quicker than using native Shortcuts elements:
    • Creates a file in the correct folder, named with today’s date followed by the title variable (in the script I convert spaces with dashes and turn everything lowercase).
    • Adds the Front Matter section and fills it with all the variables I previously created.
    • Launches my markdown editor Typora which opens the file with a compiled Front Matter section.
  • 7️⃣ Runs an AppleScript that opens a minimized session in the Terminal with my alias for running the npm task that holds both Jekyll build and SASS compile actions:
file=$(echo "$( date '+%Y-%m-%d-' )$1.md" | tr " " "-" | tr [:upper:] [:lower:])
touch ~/@ARCHIVE/2022/wwM2M/m2m-website/_posts/"$file" && echo -e "---\ntitle: 'title'\ndate: '$( date '+%Y-%m-%d %T' )'\nlast_modified_at: '$( date '+%Y-%m-%d %T' )'\ncategories:\n  - 'category' \ntags:\ntags \ndescription: 'description'\nexcerpt: 'excerpt'\n---" > ~/@ARCHIVE/2022/wwM2M/m2m-website/_posts/"$file" && open -a "Typora" ~/@ARCHIVE/2022/wwM2M/m2m-website/_posts/"$file"

Adding images to a post with Shortcuts

🚨 Opinionated sidenote — When I used a CMS, I could drag a huge photo to a media library because it would take care of resizing — and maybe optimization through a plug-in or two. Regardless of how much I could streamline that workflow on a CMS, it’s not my cup of tea. I always think about sustainability; the idea of having a website carrying a redundant amount of images is sub-optimal.

The process I follow for adding images to a blog post in Jekyll is made of 5 stages:

  • 1️⃣ Resize and compress so it’s web-safe and as light as possible, usually using GraphicConverter and ImageOptim on macOS.
  • 2️⃣ Rename to a web-friendly format.
  • 3️⃣ Make a .webp version.
  • 4️⃣ Move to the correct folder, in my case _assets/images.
  • 5️⃣ Add width and height to the figure tag.

So far, I’ve manually taken care of the first step. I have a Shortcuts automation in its infancy which is trying to deal with this. If I manage to reach the same level of compression/quality ratio as I do with GraphicConverter, I’ll make the switch.

Even though I tried to manage the whole process with Shortcuts, I have to split the process in two. That’s because I want to still apply steps 2-4 to multiple images, while I prefer to add one image at a time to my post.

Now, the images workflow is reduced to 2 steps:

  • Renaming and copying images to Jekyll’s assets:
    • Select image(s)
    • Right-click
    • Quick actions
    • M2M images
  • Inserting new images in a post:
    • Select the image I want to add to my post from _assets/images
    • Right-click
    • Quick actions
    • Jekyll insert figure

I can either right-click and use the quick actions or drag the image to the Dock, where I keep the app version of the same automations.

Video demo

Note: I clearly didn’t optimize the size. In fact, the images used in the video are from my collection of desktop wallpapers. 🙂

Breakdown

There are 3 pictures on my Desktop, all named incorrectly with wrong spaces and capitalizations:

  • evil CORP.png
  • FRIEND.jpg
  • fux socy.JPG

First, I drag them onto my M2M images app. The app transforms file names into web-friendly versions, replacing spaces and other characters with dashes and turning the file names lowercase. Then it performs a conversion to .webp with a 85% quality factor and finally moves everything to my assets folder.

This is the shell script added at the end:

for f in "$@"
do
/usr/local/bin/cwebp -q 85 "$f" -o "${f%.*}.webp" && mv "$f" /Users/m2m/@ARCHIVE/2022/wwM2M/m2m-website/assets/images && mv "${f%.*}.webp" /Users/m2m/@ARCHIVE/2022/wwM2M/m2m-website/assets/images
done

The final action takes the selected image, fetches width and height while asking for alt and caption in a pop-up text prompt:

Shortcut automation for inserting an image in a Jekyll post
Shortcut automation for inserting an image in a Jekyll post

The trick is to collect the required information, store it in variables which I then use to compile my figure Jekyll module in a text block. The output is simply sent to the clipboard, ready to be pasted in my post. From the video, this was the resulting code that I pasted in the editor:

{% include pattern-figure.html image="/assets/images/evil-corp.png" alt="this is the alt" caption="a caption here" width="2560" height="1440" %}

Dynamic content?

I didn’t mention forms and comments: that’s because I don’t need to automate any dynamic content. I have no forms and even if I’ve been planning to ditch Mailchimp and switch to Freelists or manual newsletters, I can easily add a form using Netlify’s functionality3, as Silvia did. I also didn’t want a comment system in the first place, preferring replies via email and W3C‘s webmentions.

Mobile?

In his analysis, Luke has a detailed chapter about how he writes on-the-go or on mobile devices. Again, I’m not elaborating because I never find myself in such a situation. Writing posts is not a urgent activity for me, therefore relying on my computer is enough. Had I been forced to, I’d consider two alternatives:

  • Using micropub with one of the online clients. I have an endpoint, unwisely untested though.
  • Accessing my Github repo and activate VS Code online.

Deployment

Since the deployment strategy is git-based I don’t think it’s wise to automate this step. I’ve been using either the terminal or Sublime Merge.

Future improvements

  • Polish the new post shell script, for example by switching from tr4 to sed5.
  • Add integration for responsive images.
  • I’d love to port the whole process outside macOS, since I’m planning to move dev work to Linux.
  • Handle the image resize and optimization within Shortcuts, maybe implementing scripts from https://css-tricks.com/converting-and-optimizing-images-from-the-command-line/. I’ve already started tinkering with this, see image below:
Shortcuts script for optimizing images
Initial Shortcuts script for optimizing images

I will update this post or create a Part 2 as a follow-up in case I manage to substantially improve the workflow.

Conclusions

So far this methodology has been serving me well. I didn’t mind the previous not-so-dynamic workflow, but I appreciate the value of being helped on repetitive tasks. Especially with images: I’m sure I’ll be tinkering with the scripts until the whole process is consolidated into one precise action.

One thing I really disliked was Apple forcing me to enable iCloud Drive in order to export Shortcuts’ backups on my machine. I don’t see the point other than them trying for the umpteenth time to drag me into their walled garden.


  1. I sorely miss the time when Apple simply released new apps that were available to download on several versions of OS X, but this is a rant for another day. The upgrade went well, unexpectedly fast with no issue whatsoever. I can honestly say it’s behaving better than all the previous OS updates that followed Mavericks. We’ll see. 

  2. Importing workflows from Automator to Shortcuts doesn’t always work, it’s still a hit-and-miss. 

  3. Netlify forms ↗︎ 

  4. tr is a Unix command: an abbreviation of translate or transliterate, indicates its operation of replacing or removing specific characters in its input data set. Read more ↗︎ 

  5. sed (“stream editor”) is a Unix utility that parses and transforms text, using a simple, compact programming language. Read more ↗︎ 


Reply via email


A human-readable RSS feed with Jekyll
2 May 2022 | 8:36 am

I love RSS. However, by using a third-party plugin to automatically generate the feed, I didn’t pay attention to how it could be improved. An occasional discussion on Mastodon prompted me to a change.

A few days ago, while reading my Mastodon timeline, I stumbled on an article by Wouter Groeneveld, titled Cool Things People Do With Their Blogs. Two things caught my eye:

I’d forgotten about XSLT and its potential applications and what I saw in the above examples were inspiring to me. Also, I kind of ignored how OPML, which I’ve been using as a format to backup and export/import my RSS feeds, can be styled and used as a human-readable experience on the web.

After a few more clicks, I landed on the OPML blogroll on Maya’s site. As I stated on Mastodon, probably the best and most useful blogroll I’ve ever seen. Not only they explain why each link might be interesting to anyone visiting, it’s also beautifully formatted and capable of being imported in my RSS reader.

This prompted me to apply styles to my RSS feed and give a human readable format to it. It was surprisingly easy, and I wonder why didn’t I do it sooner. I’ve been using the widespread feed plugin for Jekyll, though since my main motivation for leaving WordPress was to take full control over my code, I should have managed the feed myself rather than relying on a third party.

Using Jekyll functionality

Since I wanted to have both blog posts and projects — a Jekyll collection — I created a loop that would exploit the layout type rather than the content type, iterating 20 times (my configuration value for posts_limit) through the resulting variable:

{% assign projects = site.documents | where:"layout", "project" %}
{% assign blog = site.documents | where:"layout", "post" %}
{% assign posts = projects | concat: blog | sort: 'date' | reverse %}
  {% for post in posts limit:site.posts_limit %}
    <item>
      [code here]
    </item>

Finally, I created an XSL file to style the feed page into a human readable format, following the aforementioned example by Matt Webb. Since I rewrote the RSS feed from scratch, I also decided to add new features to the .xsl file:

  • an introduction to who I am at the top of the main feed;
  • useful author information directly in each post, for easy contact information;
  • a “reply via email” link at the end of each post, visible on any RSS reader.
Author contact info
Author contact info at the top of a post
A reply link at the bottom of each post
A reply link at the bottom of each post

The CSS file attached to the XSL presentation is so small that I didn’t bother to minify it. The sum of 3 files are less than 5 KB.

Before & after

Here’s a link to my new human-readable RSS feed. Below, a visual comparison of the before and after.

RSS feed before refactor
RSS feed before refactor
RSS feed after refactor
RSS feed after refactor

Source code


Reply via email



More News from this Feed See Full Web Site