Building
To be more flexible with how I handle things, and for the fun of building things from scratch, my blog doesn't use any standard SSG but is instead built with a custom Lua script built from scratch and a couple of small modules, the only noteworthy of which is the post module, which handles searching and reading posts using external YAML and Markdown libraries for parsing.
Images get handled directly in the main script, as they only get copied into the output directory.
The way the actual output directory is built is the most interesting part here: instead of assembling things in the file system, the build script first creates a tree structure of what the output directory should look like and inserts output files as strings. In the final step, this tree is then exported into the actual file system as a recursive directory.
Images get special treatment here, as they aren't read as binary data only to be written as is again, but are instead inserted as references to their original files so they can be copied during export.
The benefit of this approach is that the code looks much cleaner, as all that happens are manipulations of native data structures, where a library takes care of writing the data to the disk at the end in a single function call.
Outputting HTML
Of course markdown alone doesn't make for a blog, and I also need a way to generate arbitrary HTML. This could be done with reasonable ease using an established templating library, but again, where'd be the fun in that.
I use a combination of yuescript and skooma for my templates: one provides a much cleaner syntax that compiles to plain Lua, the other builds a virtual DOM in a functional way so it remains easy to track the flow of data. The functional nature of the templating is then broken by the slotting mechanism, that relies on mutating objects in the already generated DOM to hoist elements out of the current template, like adding extra meta tags into the head
of the document from a template that primarily renders a section of its body
.
What's noteworthy about those templates is how much the yuescript+skooma combination makes it look like a dedicated templating language for HTML, when in reality it is all just a general purpose scripting language with a functional library.
Styling
For styling, I shamelessly abused my blog as a guinea pig for my own css library. I'm still working on adding more stuff to that as well, but all the features that a blog would need are relatively finished already so there isn't much to worry about in that regard.
It's a class-light library, so it works out of the box just by importing the CSS-file into the document, but also provides a series of utility components for things like column layouts, footers, boxes, etc.
What's interesting here is that not every custom utility is a class; wherever appropriate, utility elements are implemented as actual custom elements, that just don't have any associated javascript definition (with the option of adding one separately if that ever becomes necessary).
Hosting
To keep things easy and free, the blog itself is hosted on Github Pages at the moment, where it exists in the same repository as the ssg except on a different branch.
The posts themselves were originally also part of this repository, but this came with the downside of unpublished posts still being public in the repository and a degree of revision tracking that made no sense for a plain list of blog posts. So nowadays the posts are kept in a subdirectory on nextcloud, allowing me to write or edit posts in the browser with a better editor than github had, while keeping them private but still having the option of sharing drafts with individual people for feedback or proofreading.
Currently nextcloud only allows sharing with read-only or full write permissions, but if at some point an option to allow for change suggestions was added, I'd benefit from that too. Github would technically allow this in the form of pull requests, but that would be too much of a hassle for anyone proof-reading to deal with for a single typo regardless.
Build & Deploy
To pull all of the above together, I currently still need to manually trigger the build and push process from my personal PC. Technically it would be nice if modifying a post would immediately re-build the entire blog (or even just the affected pages, if I wanted to over-engineer it even more), but in practice, immediate updates aren't a priority.
Being able to work on a post anywhere I have a browser is worth a lot, but being able to then publish immediately without having to get home first wouldn't really help in any substantial way. A tech post that is good now will be good tomorrow.
As for how the process works; I am, of course, using a tool I built myself: a Lua task runner called spooder. It reads a task definition file in the repository and runs individual tasks.
Tuescript files are first transpiled into Lua using tup, then the build.lua
script is executed and writes its output into the blog
directory. This directory is a git worktree tracking the page
branch of the repo, which is set up as the github pages source. That just gets committed and force-pushed for the new version of the blog to go live.
And that's the whole process of getting from typing some text into the beep-boop machine to having it accessible on the www for anyone foolish enough to read it. No magic, just a bunch of small tools working together.
Moving Forward
My big next planned feature is to replace markdown. I don't enjoy how restricted it is in what it can express, and writing plain HTML as an escape hatch also feels like a total hack. I am already sketching out my own idea for a replacement, but taking my time to make sure I don't build a mediocre system that I'll only end up replacing again.
Most likely I would operate both systems in parallel, to keep writing most of my posts in markdown when they are nothing but text, but give me the freedom to build more elaborate things as well if I ever wanted a specific post to really shine.