Porting my website to Swift

One downside of using a static site generator is that many of them are not consumer-friendly, prepackaged apps but rather glorified scripts that require an entire developer environment to be set up and configured correctly.

This may not seem like a big problem to a full time web developer, but as someone who does backend work once in a blue moon, maintaining a working Ruby/Python/Node stack is asking a lot, especially now that macOS Catalina deprecated its scripting language runtimes.

Personally, I dreaded touching this site since a quick 3-minute patch could always turn into a multi-hour yak shave trying to get my Ruby environment up to date just to keep my Jekyll installation in working order.

Additionally, I was using the AWS command-line interface to sync my website to S3, another Python dependency that I'd rather get rid of.

Inspired in part by the Point-Free website, I decided to port this website to a bespoke static site generator. That required, roughly, the following steps:

  1. Build a templating language for HTML & port the existing layouts over.

  2. Parse the existing Jekyll posts & style them using the new layouts.

  3. Sync everything to S3.

An HTML templating language

There are multiple different HTML templating DSLs out there already but in order to minimize the number of dependencies and to get a chance to play around with Swift's new function builders, I built my own.

I do like how templating in Swift can integrate with some of the more functional programming patterns already in use. For example, this is how to generate an unordered list of links to a collection of blog posts:

ul {
    posts
        .sorted { a, b in
            a.date < b.date
        }
        .map { post in
            li {
                a(href: post.path) {
                    post.title
                }
            }
        }
}

Parsing Jekyll posts

I didn't feel like updating all the Markdown files I had accumulated over the years, instead I decided to hack together a simple parser for the frontmatter and use Apple's cmark fork to traverse the Markdown body and convert it to HTML nodes.

Syncing to S3

Uploading to S3 using URLSession is relatively straightforward. The only non-trivial aspect is correctly signing the URLRequests according to the specification. I wrote an extension to do that.

Wrapping up

Of course, I'm glossing over a lot of details here when it comes to setting up redirects to get the URLs to look like I want them or how I massage the HTML before rendering it. Feel free to check out the repo for this site if you care about the specifics.

All in all, porting this website over wasn't very complicated and I'm excited by the future possibilities running against the macOS Framework will offer me for imagine manipulation and the like.

Lastly, while I don't think I'll be able to offer much technical support, do get in touch if you'd like to compare notes should you decide to build your own static Swift site.

Posted in working-on