Site Updates – September 2018

As you may have noticed, I recently ran a number of updates to my website. Most noticeäble is the new front page look, which takes advantage of the CSS grid to create an unconventional newspaper‐clipping inspired æsthetic. However, there are a number of underlying structural changes that I've made alongside this redesign, and I thought I would take some time to get into the details of those here.

A frame from the TV Show Elementary. A cis white techbro says: “Uh,
grid‐based design, it's gone the way of the dinosaur.
This man is wrong (from Elementary)

Atom Blog

Of probably most note to people following this blog: There is now an Atom feed! I have done my best to implement RFC 5005 subscription/archive documents, but—like everything on this website—it was all hand‐written, so there's a chance I made an error. Let me know if something isn't working for you!

The Atom feed is the "official" index page for this blog—there isn't an HTML index where you can browse all of my posts. However, excerpts from the latest posts are presented as links, blackout‐poëtry style, on my homepage.

Static Mastodon Support (Or Not)

I experimented with implementing static WebFinger + ActivityStreams + OStatus support (through GitHub Pages, it takes all three) such that my blogposts would be legible to Mastodon servers, and managed to actually get it working. If you're curious, you can browse the source that make it happen. I'll spell out the basics here:

Once you have the above implemented correctly, you can simply paste the link to the Atom representation of your post into Mastodon's search bar and it will fetch it just fine.

One thing I did notice is that (potentially due to a bug?) boosts of these posts don't federate properly to other Mastodon instances, and will fail to show up if the other instance isn't already aware of the toot. Since you also can't accept follows or respond to notifications on a static GitHub Pages site, being legible to Mastodon servers is mostly not useful, and so I ripped it out.

Nevertheless, is a recognized account on many a Mastodon server thanks to this experimentation.


Of more personal interest than Mastodon support, my site is now a sample implementation of a PressPost server. Those who have been following me for some time have probably heard me talking about ActivityPress, which is a federated publishing protocol that I'm currently in the process of building on top of ActivityPub. PressPost is file format that ActivityPress is built upon, akin to ActivityStreams for ActivityPub.

It will still be a while before I finalize the documentation for these protocols and formats, but having a sample PressPost implementation means that I can start work on non‐social clients and publication tools for browsing and consuming PressPost content. Look forward to more from me on this subject in the future.

If you're curious what PressPost looks like right now, /About/ is a good place to begin.

Working With GitHub Pages

In implementing the design above, I've had to make some compromises in order to work within the capabilities of GitHub Pages. For example, although GitHub Pages will correctly serve .jsonld files as application/ld+json, it does not have content negotiation and will not serve index.jsonld files when the parent directory is accessed. However, index.json is supported for directory indices, so all JSON-LD files are currently being served under the plain application/json media type instead.

Because there is no content negotiation, if a directory has both a index.html and a index.json file, the first will always be served regardless of the nature of the request. (The same is also true for index.xhtml.) Thankfully, my blogposts have already been using extensioned, non‐directory names—like /Jun/2018/mermaid.xhtml. I've used the directory's index.json file to provide the post metadata; for example, /Jun/2018/#mermaid provides the metadata for the corresponding post. The (X)HTML version of the post is then provided through a Link.

This limitation is the reason why my Author object is located at /About/#me and not just /#me.

Future Plans

Right now, everything on my website is coded by hand. This is doäble, since it consists of nothing more than a homepage and a blog, but is lacking when it comes to some of the features I would like to offer. For example, I would like to be able to host annotated versions of my fanfics, which are easily accommodated by the PressPost format but difficult and time‐consuming to generate by hand.

I've brainstormed a couple of command‐line programs which will ease this process greatly. The first is titled TurtBurgler, and will scan a directory for Turtle files (with optional HTML/XML imports) and compile them into one massive Turtle file containing all the associated relations. This will be essentially just a slightly more sophisticated version of the BNS YAML GENERATOR I wrote several months ago, operating in Turtle instead of YAML, and allowing for any manner of directory configuration.

We came here to burgle your turts! (from Over the Garden Wall)

Once the Turtle file containing the website RDF graph has been composed, the next step will be to turn that graph into an actual website. It is easy enough to determine which pages to build given a base URL—you'll need a page for every resource ID which is a subpath. By checking for ActivityStreams Links with a rel of alternate and an XML or HTML mediaType, we can generate non‐RDF files too. The hard part is figuring out how to generate these files—the templating—right now, applying XSLT to the RDF/XML serialization of the appropriate relationships seems like the most straightforward approach, although naturally a templating system which could interact with the RDF graph directly would be preferable.

The name for this library will be Plastromancy, and combining the two will result in something like the following:

TurtBurgler | Plastromancy --template template.rdf

Naturally, both of these tools will depend on the completion of my XSD, and later, RDF, libraries for Swift, so it will probably be a few months yet before they are ready to use.