Shukry Zablah

Hi, this site is running in Coleslaw

4 min read

This site is running on something called Coleslaw. Because in a world in which AI can figure out the messy bits, it only makes sense to grasp at the fun bits.

This is my personal site. From time to time I plan to write down snippets of my own experiences online across a variety of topics. I'm a Catholic born in El Salvador, and a software engineer. As a result, some of the snippets will be less understandable, you can always reach out to me over one of the socials linked to this site.

Static site generators

I wanted to give a brief overview of the technology that I chose to generate this site. As you might know, a site is just a bunch of html, css, and javascript (although nowadays it feels like they're mostly JS). To run this site I chose a static site generator, which simply put is a site that knows all its content in advance, so can be packaged up in a very simple and straightforward way and served in probably the fastest manner a site can be served over the network.

A pagespeed insight screenshot showing 100% performance

There are many static site generators. I have used many tools before, the previous version of this site was written in Hugo. For this project I decided to take a page from one of my old interests, Common Lisp's Coleslaw. It had been a while since I used Common Lisp and it was looking like this could be an easy way to get some exposure again. To that end, I wanted to write up here what I know about Coleslaw, to force myself to look at the internals.

Coleslaw

Coleslaw is many years old, and is relatively stable. It is comprised of a small core, and a patchable system for plugins. It's meant to be used by an individual for their own site.

I think that the best place to start is to understand the main function of the program.

(defun main (repo-dir &key oldrev (deploy t))
  "Load the user's config file, compile the blog in REPO-DIR into STAGING-DIR,
 and optionally deploy the blog to DEPLOY-DIR.
  OLDREV -- the git revision prior to the last push.
  DEPLOY -- when non-nil, perform the deploy. (default: t)"
  (load-config repo-dir)
  (setf *last-revision* oldrev)
  (load-content)
  (compile-theme (theme *config*))
  (let ((dir (staging-dir *config*)))
    (compile-blog dir)
    (when deploy
      (deploy dir))))

The function effectively describes the high level pipeline that is comprised of five steps:

  1. load-config: Config in coleslaw will determine how the site behaves. It is read into memory, and stored in code. It is responsible for also loading the plugin system.
  2. load-content: Content is stored as text, and this step is responsible for searching and identifying the content that will be ultimately displayed in the site.
  3. compile-theme: Theming is what allows a site to look different while having the same structured content.
  4. compile-blog: This is what takes the config, the theme, and the content, and processes it to create the output that will eventually be loaded directly by the browsers.
  5. deploy: An optional step, takes the files that we have created, and puts it in what is going to be responsible of serving our site.

I think that rather captures all of Coleslaw. If I were to explain the magic that makes the whole project worthwile, I'd probably point to the interesting use of the protocol and object system that makes all of it tick.

The document protocol is extended with posts and indexes, and allow for the possibility of creating new types as well. Additionally, clever use of the object system also allows for coleslaw to discover automatically through code.

(defun load-content ()
  "Load all content stored in the blog's repo."
  (do-subclasses (ctype content)
    (discover ctype))
  (update-content-metadata)
  (do-subclasses (itype index)
    (discover itype)))

In all, I think that it is pretty impressive to have an extensible static site generator with a plugin system described so succintly.