static site generator

tl;dr it's written with lisp and runs on babashka using selmer and hiccup.


I didn't want to pay much to host this website, so a static site generator was pretty much a given. I'd never really used a static site generator for real before, though, just tinkered. I spent some time looking around and just couldn't really settle on any of the existing offerings. They're all great, I was just very unmotivated to learn any of them deeply enough to make them do what I wanted.

So as is true for all programmer mid-life crises, Lisp comes to the rescue.

Lisp is Lisp, mostly, sorta, but I only really know Clojure. One thing I knew I didn't want is a bunch of extra stuff like node_modules/ and multiple project files and all that. That meant no ShadowCLJS. I also didn't want to use the JRE, so Clojure itself was not ideal. The choice was clear, and so I went with Babashka.

But why?

Because I wanted to?

Originally, the website used Javascript to load pages into the main window, and if I had stuck with that, I'd now be using HTMX to do it. Specifically, that hx-boost feature, that thing is neato. Have you seen it? Fuckin' neato, dude.

But I use Lynx on my workbench laptop because I'm slightly cooler than your dad, and sites that rely heavily on Javascript just suck shit to use in Lynx. You can't even browse Github with it. Ridiculous. I wasn't going to have that, and it only took a minute or two to realize I didn't need Javascript at all. Not even a little.

Maybe a little, eventually. As a treat. (And for interactive things.) Also, hosting a bunch of text files is, like, really cheap.

I started looking through static site generators and frankly hated all of them. It felt like mostly a waste of time to try and learn one well enough to bend it how I needed it to bend, or to not be bent by it the way so many want to bend you. Bend. So I just figured I'd write my own.

This is the part where people usually say something funny like, "that might have been a mistake" but fuck that, it was a great idea. Writing stuff like this with Lisp is fucking awesome, you should totally do it.

Basic Generation Process beep boop

Each major section of my site has its own custom generator. I wrote a macro for defining new ones cleanly because it felt cool to do it that way. Each one is exposed as a command using a Babashka project config, so I can run any or all of them however I need. But I usually just run them all every time.

Each generator has a define set of input pages and a directory of static files if needed, and from there it's exactly what you think it is: the templates are enumerated and processed, spit out into a directory, and then the static files are copied. What else would it be, c'mon.

Fancy Stuff

Really, most of the fun is in the custom tags. That sidebar nav over there uses a couple to build the menus, and my wishlist and manga collection pages make heavy use of them. Those would be incredibly tedious to manage otherwise.

Syntax highlighting for code is the one silly piece of this whole thing. I didn't want to write my own syntax highlighter, and there wasn't really anything readily available for Clojure that I could use in Babashka (that I could find, anyway). So I just used Deno and Shikiji, since the former lets me just have a bare Typescript file without all that package.json and node_modules/ nonsense, and the latter has an output mode intended for Markdown. Ergo, statically colored code.

So I just threw that together and wrote a function to invoke it and feed it code through stdin. Works like a charm, and I can even use any VS Code syntax theme that I want.


	(defn highlight-code
	  "Executes a Deno utility to output statically-highlighted code in HTML."
	  [lang code]
	  (let [deno (or (fs/which "deno") "/root/.deno/bin/deno")
	        cmd [deno "run" "tools/lighter.ts"
	             "--lang" (name lang)
	             "--theme" (:code-theme c/config)]
	        proc (p/process {:in code :out :string :cmd cmd})]
	    (:out (deref proc))))
	

Anyway

That's about it. I just wanted to say something about it. You can check it out here if you want.