My static site generator behind the scenes


This article describes some thoughts and design decisions I made during the change from a central posts database file to a file-based approach where metainformation resides next to its content. (work in progress)


Last month I came across Neil Prescots article [0] where he describes some ideas in writing his own site generator for fun. One of these ideas was to start each article with a title, date, and summary. In my previous article [1] I described my basic setup with make and a central posts.tsv where all the metainfo about my posts are stored. For departing that central posts.tsv in favour of storing these metainformation close to thair related content, I need to modify my current setup. This is its story.

The problem

Let's have a look on two regular rules in my makefile that generates pages and posts of my site.

public/%.html: content/%.html
    @cat $< > $@

public/blog/%.html: content/%.html public/title.tsv
    @cat public/title.tsv $< > $@

As you can see I'm using a title.tsv (a so called immediate) file that gets generated from the central posts.tsv. That solution has two problems. The given targets are very similar they just differ in one file (ie. title for blog). Both targets using stem in their path for catching all folders including subfolders.

Let's focus on the stem part first and why it is an issue. According to GNU makefiles handbook.

The stem rules in make claims that in the above case the first rule will always be taken to produce the output because all pre-requistes are already there.

Basically, that means to produce public/blog/last-word-in-ssg/index.html, make will always use the first target. That is because our immediate file target.tsv is created on-the-fly (and also deleted), thus always outdated. Make takes here the 'easy' path. So, it got my thinking "How can we harmonize the pre-requisites?" to 'force' make also recognizing the second target. I found a solution in one of [2] olowe articles about his blog setup. Instead of creating a 'artifical' intermediate file (pre-requisite) to feed into cat, I moved the creation of the tile to the rule itself. The open question was, "how to cat at the beginning of the file?". It turned out to be really straingthforward:

public/blog/%.html: content/blog/%.html
    ./ | cat /dev/stdin $< > $@

With that target in place, make need to use public/blog/%.html, because there is no other (ie. 'easiere') way to produce these files. My first problem was solved, I now could include my metainfo at the head of each blog post. This solution, however, has some further issues where we need to have a look on how the title is actually provided in a first step.

The problem: Searching