Caught in the Indie Web

Hi! You might want to know that this post continues ideas from the following.
Hi! It looks like I have since continued, updated, or rethought this post in some ways, so you may want to look at this after you're done reading here.

When I left off in last week’s Indie Web exploration, I had added h-cards everywhere, mostly confirmed that I could receive Webmentions, attempted to send myself a Webmention, and jumped for some low-hanging optimizations. In the intervening week, I’ve gotten some additional information on the outbound Webmentions.

A spider web with dew, in front of presumed concrete blocks

In this post, I’ll talk about where that stands.

Small Bugs

Sadly, I haven’t had the ability to send out Webmentions, yet. When rebuilding the blog, I get an odd error about URL formats. To get some insight, I filed a bug report in hopes of getting some insight into the problems.

If you read through—not really worth the energy unless you have the same problem—then you’ll see that the regular expression in the Webmentions gem tripped over a handful of items not actually meant as valid URIs. For example, in the post on programming languages that I created, the example code for Thue contains something that looks enough like a URI that it causes code to recognize it, but then fail unexpectedly when trying to process it. In other cases, regular expressions cause similar problems.

The gem’s maintainer has fixed that problem, though it won’t roll out for a couple of weeks. Still, I’d call that a success. However, if you wonder why I haven’t legitimately sent any Webmentions, that should probably explain why.

Meanwhile, it may work, if I set the Webmentions cache of the offending non-URIs to act like someone had already sent them. However, that raises another concept of interest.

Core Concepts

After looking at examples of Webmentions, and seeing how the Jekyll plugin does its job, it occurs to me that I seem to have misunderstood the conceptual model of Webmentions.

I saw them as HTML blobs in larger bodies. If I want to “like” three articles, RSVP to an event, reply to two more, quote something else, and bookmark a dozen others, the descriptions that I saw suggested that should work. Create nineteen HTML elements with the h-entry class and a u-in-reply-to link to the relevant page, and I imagined that each should receive the bespoke responses that I wrote.

However, I see instead that—and you can see this reflected in the developers’ description of the protocol as opposed to the more general page—they intend Webmentions to come from individual pages. In my example, the nineteen recipients should receive Webmentions, but they will all receive the same Webmention, telling them that my blog post mentions their URL.

In other words, they built the concept as a distributed social media protocol would, seeing the “first-class citizens” of the ecosystem as comparable to Twitter’s tweets—this all happened before the change in management, remember—or Mastodon’s toots. By contrast, I envisioned the first-class citizens as entries that a page could contain. They see the “timeline” as a collection of pages, where I saw a nested timeline of posts containing mentions.

At that point, lacking the ability to send out those replies doesn’t seem so bad, right? It gives me time to set things up correctly.


To make Webmentions that work as I expect and the way that the protocol expects, I need to separate the mentions themselves from the main body of the post. That requires two parts.


First, I need to separate posts that show the mention from the normal posts. I mean that separation in a few ways. These mini-posts should…

  • Have separate Markdown/source files, with no repetition between files;
  • Can’t show up in the index or RSS feed, otherwise I flood readers with useless posts1;
  • Shouldn’t have a full header or post layout, since I won’t write or publish them as full posts; and
  • Shouldn’t require outside information to function as the intended message.

To that end, I created a sub-folder in my posts—called social—where I have extracted the Webmentions intended from previous and upcoming posts. Going with Jekyll’s convention, the files get names that start with the date. Departing from Jekyll’s convention, since I don’t really care about which post contains what, after the date, they get numbers instead of names. Therefore, you’ll see social/2024-03-27-1 for today’s example that you’ll see later.

I went through the recent and upcoming posts to pull out the Webmentions that I created, and give them each their own “social” posts. These posts have less, but more important, metadata attached. For example, a typical post’s header looks something like the following, for me.

layout: post
title: The Title
date: 1838-07-04 12:30:57-0000
tags: [davy, example, history, telegraph]
summary: The subtitle that shows in the index.
thumbnail: image-to-show-in-the-index.png
offset: -11%
update: [ ]
teaser: The blurb for the post that goes out to social media.
spell: words for the spellchecker to ignore
The actual post starts here.

For these posts, I don’t need nearly this much information, but I want some of the information to carry information about the mention. That gives me something more like this.

layout: reply
date: 1838-07-04 12:30:57-0000
hidden: true
reply: https://site.example/that-this-responds-to.html
title: The Title of the Responded-to Post
Post contents, if necessary.

We should see a few big differences.

First, this uses a different layout than a normal post. I don’t want a full post, here, only a reply to someone else’s post, in this case. The reply layout creates a post that looks like a Webmention reply. Eventually, I’ll do the same for likes and whatever other responses that I need to support for myself.

Next, I set the hidden property of the post. This tells Jekyll to not show the post in the blog index, which I need. I believe that they also won’t show up in the RSS feed, but preemptively apologize if they do, and will scramble to fix that.

Then, instead of information about how to display the post, the rest of the metadata goes to identifying, by title and URL, the source that I want this post to reply to.

Now, when I can send Webmentions out, each explicit mention will have its own little post, as the protocol seems to intend.

Bringing the Mentions Back

Even though I’ve separated the mentions into their mini-posts for better processing, I still probably usually want to show them in pages that people read. Right now, a lot of them intend to work as part of the social media roundup posts, so it doesn’t make too much sense to leave them off in their own “silo” completely.

That means writing a plugin to embed one post inside another. I’ll spare you the boring trial-and-error development process to make this work, and skip to the render function that does the important work, minus the error-checks.

def render(_context)
  site = _context.registers[:site]
  post = { |p| p.basename_without_ext == @post_id }
  converter = site.find_converter_instance ::Jekyll::Converters::Markdown
  layout = site.layouts[['layout']]

  content = converter.convert post.content
  _context.stack do
    _context['page'] = post
    _context['content'] = content
    Liquid::Template.parse(layout.content).render _context

This looks for the post with a particular name, such as the aforementioned 2024-03-27-1. When it finds that, it gets the proper layout, and renders the post’s contents in that layout. For example, I can include this gem, replying—when replies finally work—to last week’s post, using my new nest tag.

in reply to: Deeper in the Indie Web

This exploration continues in Caught in the Indie Web, for those who want to see how these experiments panned out and where to go from here.

I call it nest, because I use embed for an image thing.

Anyway, that text doesn’t actually appear in this post’s source. Instead, it has its own post—the same as the link from the reply’s time stamp, by the way—with much-less-interesting styling, at the moment, because I don’t want to work from the default page layout with all the links in the header and footer. And rather than comment forms, I suspect that I’ll only give these pages Webmentions.

I like this, or at least, I think that I do. While the overhead of rebuilding and re-publishing the blog makes it unlikely that I’ll do so moment to moment, this now gives me the flexibility of writing one-off posts that might look more akin to social media posts without “polluting” the main blog, but I can include them in the Friday posts as they stand. Eventually, I could even publish non-response side-posts on to Mastodon and whatever other social media networks start to support a decent public API.

Two Weeks Down

While not yet running at full steam, it seems like I have the blog closer to “social,” and I know when the outbound mentions should start working without my manual intervention.

I expect that these posts will become less regular, from here. I have work to do on styling those side-posts, and figuring out how to give them a side-index and RSS feed for anybody who wants to follow them, for example, and I believe that I can do some of that with “collections.” But that doesn’t warrant a full Indie Web post, or probably much beyond mentions in my Monday developer diary posts.

Once I have the current situation settled, though, I should look at the other Indie Web protocols to see what would benefit me. At a quick glance, Micropub looks like it would take a lot of work to implement it for Jekyll, probably break how I use Jekyll, and probably wouldn’t pay off any time soon, given how little I post to social media in general. As mentioned last time, Microsub failed, because it needed a different authentication system, which makes it seem like too much work for now.

That leaves WebSub, which looks like a fancier version of RSS, and that sounds interesting. At some point when at least some of the rest of this dust settles, I’ll look at what it would take for me to implement it on the blog, and talk about it here.

Oh, and I’ll want to finish Earburn soon, too.

Credits: The header image is Web by Martyn Wright, made available under the terms of the Creative Commons Attribution 2.0 Generic license.

  1. No comments from the peanut gallery, please. I’ve already made those exact jokes about the quality of ordinary posts… 

No webmentions were found.

By commenting, you agree to follow the blog's Code of Conduct and that your comment is released under the same license as the rest of the blog. Or do you not like comments sections? Continue the conversation in the #entropy-arbitrage chatroom on Matrix…

 Tags:   blog   indieweb   programming   techtips

Sign up for My Newsletter!

Get monthly * updates on Entropy Arbitrage posts, additional reading of interest, thoughts that are too short/personal/trivial for a full post, and previews of upcoming projects, delivered right to your inbox. I won’t share your information or use it for anything else. But you might get an occasional discount on upcoming services.
Or… Mailchimp 🐒 seems less trustworthy every month, so you might prefer to head to my Buy Me a Coffee ☕ page and follow me there, which will get you the newsletter three days after Mailchimp, for now. Members receive previews, if you feel so inclined.
Email Format
* Each issue of the newsletter is released on the Saturday of the Sunday-to-Saturday week including the last day of the month.
Can’t decide? You can read previous issues to see what you’ll get.