This blog site

  • 9th Nov 2024

I used to have two websites built with Jekyll - one for writing up project ideas, started and abandoned in 2018, and another one started which was hosted on https://neverix.github.io which had my resume at the time. I used it every few months in 2020 and 2021 but abandoned it.

This was for a few reasons. Firstly, I had trouble setting up Ruby and Jekyll on my new laptop. Additionally, and I'm ashamed to admit it, using it did not feel exciting enough. I wanted to feel that I owned the website, and I didn't want to try to figure out how to customize Jekyll with many plugins because with its popularity someone had to have done it before, so it was likely I was wasting my time.

I didn't think long and settled on Zola as the basic engine for the site. I liked that it was simple to set up and was unlikely break. I looked at a few themes and picked Tabi by welpo because I liked the way it looked and the abundance of features.

This would have been the end of the story, but I also wanted something else for my site: support for Quarto. Quarto is a way to include code inside markdown files and have it run automatically and show outputs. It takes the idea of Jupyter notebooks further and makes it possible to perform more styling. I also really like the tooling for VSCode, which makes setting up and using Quarto as easy as spinning up a notebook.

Then why didn't I use Quarto for the website? I didn't like the themes Quarto had to offer and I didn't want to spend time customizing them. I also thought it would be wasteful to have Quarto run on every page, even if they had no code and were hypertext with images. I wanted to have the best of both worlds: a static site generator for the website and Quarto for the posts with code.

I wrote a Makefile that used Quarto's CLI to render files individually into Markdown without a config:

QMD_FILES = $(shell find content/ -type f -name '*.qmd')
QMD_OUT_FILES := $(QMD_FILES:.qmd=.quarto.md)


# /tmp/quarto/bin is where the Netlify Quarto extension installs the binary
export PATH := /tmp/quarto/bin:$(PATH)

netlify: all

all: quartos

quartos: $(QMD_OUT_FILES)

# Renders Quarto markdown files to Zola markdown files
# We need to replace links to use absolute paths for static files (Quarto strips this away)
# Quarto also escapes square brackets, and the square brackets are necessary for the frontmatter
%.quarto.md: %.qmd Makefile
	quarto render $< --to hugo
	mv $*.md $*.quarto.md
	static_name=$(shell basename $*)_files; \
	static_path=static/$$static_name; \
	rm -rf $$static_path; \
	cp -rf $*_files $$static_path; \
	if [ "$(shell uname)" = "Darwin" ]; then \
		sed -i "" -e "s/$$static_name/\/$$static_name/g" $@; \
		sed -i "" -e 's/\\\[/\[/g' $@; \
		sed -i "" -e 's/\\\]/\]/g' $@; \
	else \
		sed -i -e "s/$$static_name/\/$$static_name/g" $@; \
		sed -i -e 's/\\\[/\[/g' $@; \
		sed -i -e 's/\\\]/\]/g' $@; \
	fi
# ^- macOS and GNU sed have different syntax for in-place editing


clean:
	rm -f $(QMD_OUT_FILES)

# Interval between checks (in seconds)
INTERVAL := 0.1
TARGET := all

# Makes it possible to rebuild the Quarto files when they change
watch:
	@while true; do \
		make $(TARGET) -s all; \
		sleep $(INTERVAL); \
	done
# usage:
# $ make watch &
# $ zola serve --drafts  # shows draft (hidden) pages

.PHONY: quartos clean all netlify

I spent a few hours debugging all of the commands and making sure it runs on both macOS and Linux. I hosted the website on Netlify and used the Quarto Netlify plugin to install Quarto on the build machine. A brief look at the source code told me where the Quarto binary was being installed.

In the end, the Netlify configuration looked like this:

# netlify.toml
[build]
publish = "public"
command = "make netlify && zola build"

[context.deploy-preview]
command = "make netlify && zola build --base-url $DEPLOY_PRIME_URL"

[[plugins]]
package = "@quarto/netlify-plugin-quarto"

An example of how I used Quarto can be seen in the next token distribution post (notice the -quarto suffix!)

This will not be the last post on this site, I promise! I already wrote a post on a concrete topic so that will not be the case.