What powers this site?

I would like to do a tiny bit more development before I release the source code, but this is a homebrew static site generator.

Sources, dependencies and inspiration

I owe a debt to the following, in no particular order:

Abhinav Sarkar wrote a blogpost, and Chris Penner a site generator package Slick (also discussed in a blogpost), whose general approaches I followed.

I inherited from both of these the idea of using the Haskell build system Shake (also on hackage) together with the document converter Pandoc (also on hackage). Pandoc is a good general-purpose markdown-to-HTML engine (with mathematics support), and Shake is good for tracking dependencies and making site rebuilds rapid.

They both use Mustache for templating, however, whereas I use my own library Tophat which compiles templates to Haskell.

Anecdotally, having a templating language which is fully integrated with Haskell has been extremely pleasant.

My site generator provides an Atom feed; people wanting to make a static site by any other Haskell-based method might want to reuse my code for the purpose.

A difficult design decision: representing publication

One question that I found myself facing when designing it: how does one deal with the concept of draft posts and published posts within a version control system?

Ideally, a version control system should automatically keep track of publication dates, and also of dates last edited: these are both desirable things to keep track of (particularly if one is to supplement one’s blog with a feed), and are difficult to keep track of by hand.

Nonsolution 1: a directory for drafts

A natural solution is to maintain two directories, one for draft posts and one for published posts.

This is certainly workable. To publish a post one just moves it from one directory to the other. The date of publication and date of last edit can both be readily extracted from the log.

The problem with this is that it runs contrary to the workflow of modern version control systems, which are intended to explore possible futures. One will have draft posts which are in early states where you don’t want to see them clogging up a draft version of your site (“Note to self - write something about such-and-such”), but one may also wish to have speculative branches in which you can see what some more polished draft posts look like in a local build.

Using such branches, however, means that publication dates can no longer be extracted from the record: the only thing you can get is the date that a post was first moved to the “published” folder to be inspected in draft form, which is very different.

Nonsolution 2: two separate repositories

One could have two different repositories, one merely storing publication and one doing the normal job of version control in development.

I can’t persuade myself that this is a completely daft way of doing things (it’s the sort of thing I can imagine being done commercially) but it sounds miserable, and is clearly inappropriate for a tiny static site generator.

Commit metadata

The approach I’ve taken is to have commits identify their publication status.

No VCS I know has inbuilt support for user-defineda commit metadata, but you can roll your own: in both git and jujutsu (and many others) a commit message is an arbitrary string, and the user is welcome to invent and enforce their own conventions on the meanings of that string.

In this case, I’ve kept it simple. A commit message that ends (published) indicates that it has been. The workflow is that the following steps should happen in turn to publish a commit (aborting on failure):

Additionally, a commit message that contains (minor) indicates that it should be ignored for the purpose of finding the last edit date. Indeed, the draft Atom standard says that “not all modifications necessarily result in a changed atom:updated value”.

Advantages of jj over git

There are some small advantages to using jujutsu rather than git as a version control system.

Also, not unimportantly, I wanted to use it.

Name

I’ve decided to call it “tails”. This is a bit grandiose: it makes it sound like full batteries-included web frameworks like rails and grails. However, the combination of “tophat and tails” is too good to miss out on.

Published 14th May, 2025.

Tags: programming, haskell