I've been feeling like the Webmention page on the IndieWeb wiki doesn't do a very good job of explaining what Webmention does for users, and jumps too quickly into spec details. I would like to be able to direct people at this page when I am talking to them online about what Webmention can do, which often means what I am trying to show them is how Webmention can be used to display comments and other interactions on a website. Today I started to make some incremental improvements.
I rephrased the introduction section to start with user-facing features, rather than be a description of the protocol. Starting by updating the first sentence to describe the end result rather than a summary of the of the spec. Previously, the first sentence was:
Webmention is a simple way to notify any URL when you link to it on your site.
The problem with the original definition was it only describes one side of what Webmentions do (sending) and doesn't talk about receiving. Most importantly, it doesn't actually tell you why you would want to use it.
I changed that to:
Webmention is a protocol that enables conversations across the web.
I'm no expert at writing or branding, but I think this is an improvement because it starts off by describing the end result. Feel free to offer suggestions for alternatives though!
Interestingly, the second sentence was already great, and now flows nicely after this high-level description.
This powerful building block is used for federated comments, likes, reposts, and other rich interactions across the decentralized social web.
I then went through a bunch of the IndieWeb Examples of sites that support Webmention, found illustrative examples of their sites displaying comments, and uploaded a bunch of screenshots to the wiki. My hope is that this will help people understand the end result of supporting Webmention, which is that discussions can take place across websites.
I cleaned up the bottom section of the page a bit, consolidated the "Resources" section which had previously been split out into new pages, and I found two quotes from some of the linked articles I liked which I pulled snippets of into the page.
My ultimate goal with this is to improve the webmention.net page to be something I feel good about sending people to to get an idea of what Webmention is. Now that we are starting to expand greater into generation 2, we need to improve the documentation of the various IndieWeb components to focus less on code and protocols, and more on the end goals.
I want to start by cleaning up the Webmention page on the wiki, and I would love more help with that part of it. Feel free to continue editing the copy, improving the information hierarchy, and anything else you can think of to make it more approachable to newcomers!
Once we get to the point where the wiki page is relatively well written, I want to copy some of the content over to webmention.net, and give it a facelift. I'm always hesitant to share in-progress mockups, but hopefully doing so will spur some discussion. I'm thinking something along the lines of the mockup below, but maybe with a less stock-photo-y image, and some nicer typography.
Doing incremental improvements to the wiki page rather than jumping into a whole new design will ensure that we are focusing on getting the copy right. So please won't you help me continue to improve the wiki! 😊
Following up on yesterday's update of adding a Webmention form on IndieNews' Webmention endpoint, today I finished building out the UI for submitting to IndieNews from a browser.
Now the "Submit" link includes a form where you can paste in your post's URL, in case your website doesn't send Webmentions automatically.
If you use this form to send the Webmention, then the response will be an HTML page instead of a JSON response. If the submission is successful, then it will actually return a 302 redirect to the IndieNews permalink of the post! This is a slight deviation from the Webmention spec, but it's fine because we don't really care if the browser is a spec-compliant Webmention client.
Also thanks to Chris Aldrich for the suggestion of using a dropdown for the target URL selection on the generic Webmention form.
This is the form you see when you visit the Webmention endpoint, which is not specific to the language you're on.
"Webmention works much like @mention on Twitter, Medium, Facebook, and others, but is platform independent, which means you can use it to ping any website on the internet that supports it. Imagine if you could reply to someone on Twitter from your WordPress site? Or if you could use Facebook to reply to a post on Medium?"
This was a tricky one, spawned from when sebsel failed to discover the Webmention endpoint for one of Zegnat's posts. In that case, the Webmention endpoint was a relative URL and sebsel was sending a Webmention to a URL that was also an HTTP redirect.
The new test, webmention.rocks #23, instructs you to send a Webmention to a URL that is a redirect, and that page advertises a relative URL endpoint. You'll need to make sure that the URL you pass to your relative URL resolver is the final URL after following the redirect, rather than the one you start with.
So give it a shot! Test if your relative URL resolution code works properly!
Thanks to @Zegnat and @sebsel for finding some new new edges case in Webmention discovery that deserve new tests!
The new test, #22, advertises its Webmention endpoint with a URL that is relative to the page (e.g.
<link rel="webmention" href="22/webmention">). The existing relative URL tests were absolute paths (e.g.
<link rel="webmention" href="/test/22/webmention">).
If you already handle relative URL resolution with a library then chances are you will pass this test without any new code.
Yesterday I added a Webmention form at the bottom of my posts. If you used this form, it would show you a "check status" link after accepting the Webmention request. My Webmentions are all handled by webmention.io, and its status URLs return a JSON response. This isn't particularly friendly when someone views one of these URLs in a browser, since they just see a raw JSON blob.
Today I updated webmention.io to return all responses in HTML if they're made from a browser. It checks to see if there is text/html in the Accept header, and returns HTML if so, otherwise returns JSON as normal. Now when you view one of these status links, you'll see something like this.
Since the Webmention spec doesn't define the body of the response, doing this is still considered conformant to the spec. The one non-standard thing I had to do was to return an HTTP 303 response when accepting the Webmention instead of 201, in order to get the browser to redirect to the status URL immediately. I still return 201 to non-browser clients so they won't see any change.
I finally brought back the Webmention form on my website! At the bottom of my posts, you'll see a Webmention form now!
Hopefully soon I'll have realtime comments appearing, so that your comment will appear inline automatically after it's done processing!
Whenever my website receives a comment, like, repost, or other mention, I display those responses on the post's permalink, along with author information if available. For likes and reposts, I show the profile photo in a list, so there are sometimes lots of photos there.
For a while now, I've been archiving these profile photos myself in order to avoid various issues caused by hotlinking these images (mixed-content warnings, potential security issues by including remote images, and having avatars disappear when people change their URLs). It's been great because it speeds up the loading of the images since everything is coming from one domain, and I no longer have broken avatars on old posts. However, there was one problem with this plan, which was sometimes peoples' avatars would be huge! Like over 1000 pixels tall, and I was showing it in a 48px square space.
Today, I updated the code that archives these avatars to resize them to a max of 256 pixels tall.
This code was written in node.js and running on Amazon Lambda. It was the first (and last) project I've run on Lambda, and I did it as a sort of experiment when Lambda first launched. It wasn't too difficult to figure out the ImageMagick commands in Node.js to do the resizing. But... then I went to go and update the code on Lambda, and that was a nightmare. For starters, they're running a new Node.js version now, so I had to update my system to that to ensure I was bundling the right versions of libraries. Then there were some other changes around permissions and things too, which I didn't totally understand. Then I started getting intermittent errors after I tried launching the new version. Ultimately I got fed up and decided to rewrite the project in Ruby and run it on my own server.
It turns out I ended up spending about as much time rewriting the app in Ruby as it took to launch and debug the updated version on Lambda. On the plus side, the code is also way easier to understand now, since it's normal synchronous Ruby instead of async Node code that always turns into a mess. It's also only 100 lines now instead of the previous 150 in Node. Here's the new app.
I didn't change the external facing API, and images are still stored on S3, so my apps that use this project don't have to change at all except for which endpoint they talk to.
Ultimately, this change is only very slightly visible. The end result is now my posts won't be potentially embedding super large images shrunk down to 48px. This code is also used by webmention.io, so if you're using that to receive Webmentions, then you also have this change now!
This is a description of all the pieces and tools that I use to post to my website and handle comments and responses. Many of the pieces are open source and/or based on open protocols that you can implement yourself.
I write posts using an app called Quill. It's an open source application that I wrote. I run a hosted version at quill.p3k.io, and you can run it on your own server if you want as well. Quill provides an interface for posting longer blog posts with embedded images like this, as well as short text notes, and a handful of other kinds of posts like bookmarks.
Quill doesn't actually store any posts itself. It is just an interface for writing posts.
When I click the "post" button in Quill, it sends a Micropub request to my own website, which then creates the post and displays it on my website. Micropub is an API standard for creating short notes and posts, and it supports photos and videos too!
You can start using Quill if your website supports Micropub. There are some Micropub plugins for various CMSs, and it's also not too hard to write an endpoint yourself if you're into that sort of thing.
I never write posts directly on Twitter or Facebook. Instead, I write a post in Quill, and then check the boxes for where I want to syndicate the post.
Providing the text for the buttons is a feature of Micropub, but the actual posting to Twitter and Facebook is done through a tool called silo.pub. Silo.pub exposes a Micropub endpoint for many services, as a way to avoid writing silo-specific code. My server can simply make a Micropub request to the silo.pub endpoint and silo.pub creates the post using the Twitter API. Silo.pub is open source, and is written by Kyle Mahan. I run a copy of it on my server for my own use.
My website CMS is called p3k. It's not open source as a whole, although I have open sourced many of the components that are used to create it. At some point I might open source the whole thing, but when I do, I want to make sure I've built an easy installer for it, as well as a clear path for rolling out updates.
When Quill makes the API request to my website to make the post, it's handled by the Micropub endpoint that is built into p3k. The Micropub endpoint receives the Micropub request, writes the post to the storage file, which is then rendered on my website.
On many of my posts, you'll see comments and other responses. However there is no comment form on my site! Every comment or "like" is actually posted by someone else on their own website, and they sent a Webmention to my site letting me know about it.
Sending a Webmention is just a simple POST request to my Webmention endpoint, with the two URLs in question: the page that links to me, and which of my pages it links to.
My Webmention endpoint is actually a separate service that is open source, and you can use it too! It's at webmention.io or you can install your own copy. Once you sign in, it will give you instructions for adding the endpoint to your site. Basically you just paste an HTML tag into your website header, and that tells Webmention senders where to send the Webmention.
When the endpoint receives a Webmention, it first verifies that the link exists, and then it extracts some data from the web page. It looks for a Microformats 2 h-entry on the page, which tells it where to find the author data, comment text, date, and other properties. This part of the process is also broken out as a separate service I wrote, called X-Ray. You can use the test tool at xray.p3k.io to check what it finds at your own blog's URLs, in order to see what will show up when you send me a Webmention. X-Ray is open source and you're also welcome to use the service or install it yourself.
Since I copy my posts to Twitter and Facebook, I also want to know when people comment or "like" my posts there. There is a fantastic tool called Bridgy, written by Ryan Barrett that helps with this. Once you connect Bridgy to your silo accounts, it will watch when people respond to your posts, and create "proxy" web pages with Microformats markup for each response, and then send you Webmentions.
This means you don't have to write any special code for handling responses from Twitter/Facebook/etc, as long as you've written code that handles Webmentions and the various kinds of h-entry Microformats posts!
If you've made it this far and want more, here are some more links to get you going!