Micropub for Kirby — a design exercise unlocking countless possibilities

Sebastian Greger

When I set out to create a Micropub endpoint as flexible as the Kirby CMS itself, this turned out to be a rather complex task. The result, however, opens up opportunities that frankly surprised myself. Once the initial setup is done, publishing content is more flexible than ever.


tl;drI created a Kirby 3 plugin, providing a Micropub endpoint for easier publishing of content.kirby3-micropublisherMicropub, an open API standard, enables the creation and editing of website content regardless of the underlying CMS. Any Micropub client software can — in theory at least — talk to any Micropub-enabled CMS, freeing users from lock-in to the editor interfaces that come with their CMS.

For Kirby, this would mean that users are no longer bound to using the standard “Panel” (not that there is anything wrong with it, quite the contrary), to interface with the built-in API, or to edit content files manually, but they may download a Micropub client of their choice and use it to create and publish new content.

Why Micropub?

Micropub, today a W3C Recommendation, is a living standard developed bottom-up by Indieweb activists (through experimentation and so-called “selfdogfooding”). Its core value proposition is that end users have free choice of their content creation tool. For instance, even content for various websites running on different CMS could be created using a single mobile app.

At the same time, the Micropub protocol comes with technical features that increase safety (e.g. no transmission of passwords, since the authentication is based on the more secure OAuth protocol) and it relies on an interoperable standard rather than generic API specifications. The use of a unified posting interface also provides opportunities for (semi-)automation.

Exemplary use cases could be, for instance:

  • using a mobile app to upload posts and pictures to a blog
  • automation of content publishing, e.g. from a shell script on Linux, or by IoT devices
  • deep integration of location-based services etc.

A translator to be trained

As a metaphor, it helps to consider a Micropub endpoint server to be a “translator” of sorts: it is a piece of software that listens to incoming content (spoken by a Micropub client in the language of Micropub) and translates it into instructions the CMS understands (the language of Kirby, to stay on metaphor). A website owner may prefer application X over their CMS’s editor interface (e.g. the web app Quill over Kirby’s own Panel), and as that application “speaks Micropub”, the translator takes care of “explaining” incoming messages to the backend.

Flowchart of Microformat data being translated into Kirby fields. class=wide
The Micropub endpoint “translates” the Microformat-encoded content from the client app into a page creation command in the Kirby CMS.

This really is pretty much how any API works, and understanding an incoming Micropub message is not difficult for such translator (alas not trivial, mind you). Vocabulary and grammar are rather simple and straightfoward; they are based on the grammar of HTML Microformats and certain community-developed conventions.

The challenging part, however, is not so much for the translator to understand what the sender is saying, but to correctly translate it into commands for creating a new page/post on the backend system. With some CMS, websites share fixed structures by design: post titles, text bodies, categories, tags, etc. are all stored in the same database structure in pretty much every Wordpress site in existence, for example. Hence, a Micropub plugin for Wordpress may make certain assumptions on how a site is (expected to be) set up. In other words: the translator comes readily “trained” with a rule set of what to tell the backend to do.

In addition, websites may feature a variety of different content types (longform articles, brief notes, bookmarks, location updates, etc.), which means that not every incoming Micropub content is to be treated the same way. The “official” Micropub Wordpress plugin aims to harmonize these by defining preset “post kinds”; I prefer the term “post types”.

Flowchart of four different post types from their Microformat representation to final post. class=wide
A flexible Micropub endpoint accommodates a wide — or even unlimited — range of post types; this can be based on analyzing incoming posts for the presence of certain fields and applying different rendering rules as they are translated into content pages.

Given the flexibility of Kirby — where even the page title won’t necessarily have the same field name on every Kirby site, nor is there a fixed location for “posts” as everything is built from “pages” in a folder structure — the design goal had to be maximum flexibility: a “translator” that understands the language and has the capabilities to quickly learn a yet-to-be-taught set of interpretation rules. Ideally, our “translator” would work for any Kirby site, regardless of its setup.

The Micropublisher plugin for Kirby

The intended flexibility inevitably comes at the expense of complexity for set-up; compared to a Wordpress plugin that ideally works more or less plug-and-play, a Kirby Micropub endpoint has to be extremely configurable, hence likely won’t work out of the box. In addition to some critical authentication features, the two key tasks are to detect the type of content submitted (Micropub does not have a built-in “post type” variable, to keep it flexible) and to transpose the submitted fields into their Kirby counterparts.

As a pet project (the side product of streamlining some of my knowledge management flows) I decided to dive into yet another Indieweb technology. The result of these explorations is the kirby3-micropublisher plugin: an installable Micropub endpoint for any Kirby 3 website.

In addition to installing the plugin, it is crucial to set up IndieAuth: the protocol required by Micropub for authentication (it is built on top of the OAuth standard). This can be done in two ways: either by relying on a third-party service (the most straightforward way; the Kirby Cookbook has a recipe) or by self-hosting an authentication endpoint using the kirby3-selfauth plugin.

Flowchart with the multi-stage communication between IndieAuth and Micropub infrastructure.
This flowchart illustrates how IndieAuth and Micropub are tied together; when following the installation instructions, the Micropublisher plugin includes a token endpoint and takes care of all of this. Diagram by Aaron Parecki under CC0 license.

Once IndieAuth is set up and the Micropub plugin installed, Micropub should work for posting basic notes to any website using a vanilla Kirby Starterkit (the recommended setup for first steps and experimentations), as the plugin’s defaults are tailored to that sample setup. For all other sites, or for anything beyond the basics, there are plenty of configuration options.

Micropublisher in action

The technical documentation describes the setup in detail, but revisiting the “translator” metaphor one more time it can be inspiring to look at a few examples.

Advanced blog writing

The Quill webapp by Aaron Parecki provides an editor mode for writing longform articles (not just quick “microblog” notes, that Micropub is often associated with).

The Quill webapp detects the range of supported posts from the Micropub endpoint and, if supported, provides an editor interface for full-grown blog posts.

The Micropublisher plugin translates the incoming HTML into Kirby’s Markdown syntax and also takes care of attaching the included images to the final page.

Easy bookmarking

Indigenous for Android by Kristof de Jaeger (a - no longer actively maintained - iOS clone also exists), shows up as a sharing target in the Android context menu, allowing to instantly post a bookmark to a website.

The Indigenous app allows easy creation of bookmarks from the smartphone.

The Micropublisher plugin could either be set up to detect the unique bookmark-of property of the incoming post to translate it into a blog post or — even more advanced (and as a feature still under development) — could be told to instead hand the bookmark on to an internal function, e.g. to store bookmarks in a non-public database system.

Finally: some command line magic?

Using Christian Weiske’s shpub — a Micropub client for the command line — one could set up an automated script, that monitors a folder on the Linux file system and sends any JPG files copied into that folder to a website instantly. The shpub command needed is as simple as:

shpub note -f photo.jpg "The latest photo"

Posting to a Kirby website from the command line feels truly magical. This, if anything, illustrates the power that rests in Micropub: opening up endless opportunities for integration with various applications, systems and workflows. Ideally, the flexible design of the plugin can enable that in a reasonably useful way.


In addition to bottomless documentation and considerations on indieweb.org and discussions at past IndieWebCamps, this work was greatly sped up by inspiration from “minimum implementation” samples by rhiaro and Christian Weiske, as well as by initially peeking into the former Kirby 2 plugin by Sebastiaan Andeweg.

Screenshot from the testing suite at micropub.rocks
Apart from some out-of-scope features like updating and deleting posts, the plugin currently passes most of the applicable tests on the test suite at micropub.rocks.

The kirby3-micropublisher plugin is a personal pet project and comes without warranties, promises or live support. Any feedback on the current Beta version is most welcome — as are any stories on how you ended up using Micropub for your Kirby site. Comments are open below, or report issues on Github.

I'm Sebastian, Sociologist and Interaction Designer. This journal is mostly about bringing toge­ther social science and design for inclusive, privacy-focused, and sustainable "human-first" digital strategies. I also tend to a "digital garden" with carefully curated resources.

My monthly email newsletter has all of the above, and there are of course also an RSS feed and Twitter.