Since the last time I was seriously considering writing my own static site generator, a whole bunch of people have actually written static site generators, and gee, it’d be nice if I could use one of them and save myself some effort. Trouble is, none of the generators I’ve seen solve my particular, somewhat unusual use case, or if they do, I can’t tell that they do.

I have a bunch of different projects, each of which lives in its own little VCS repository, and you can think of each as being a black box which, when you push the button on the side, spits out one or more HTML documents and resources required by those documents. The site generator needs to take all those black boxes, push all the buttons, gather up the results, apply overarching site style, and glue everything together into a coherent URL tree. So imagine a source tree that looks something like this:

index.md
robots.txt
foo.html
bar.gif
tblgen.py
[other stuff]
rngstats/
process.R
[other stuff]
...


and we want that to become a rendered document tree looking something like this:

index.html
robots.txt
foo.html
bar.gif
index.html
sprite.png
rngstats/
index.html
d3.js
aes.csv
arc4.csv
...
...


Notice that each “black box” is a program written in an arbitrary language, with an arbitrary name (tblgen.py, process.R). In practice I suspect most of them will be written in (Numeric) Python, especially as the real “rngstats” just hit a brick wall named “R doesn’t appear to support reading 64-bit integers out of an HDF file,” but I want the option of using something else if it’s convenient for that particular project. I’m prepared to write a certain amount of glue—but only once, not every time I add a new project. This rules out a whole swathe of existing site generators immediately: those with no extension mechanism and those which cannot be persuaded to invoke external programs. More traditional formatting plugins that are stored outside the source root and can do things like make a nice HTML page out of a LaTeX document or a gallery out of a pile of JPEGs are also desirable.

Also, the [other stuff] isn’t supposed to be scanned directly by the site generator. Some of it will be used by the black box (generate.py or generate.R here), some of it will be referenced by the output of the black box, and some of it is irrelevant to the process of packaging up the site and shouldn’t appear in the final result. In fact, I want the site generator to start with index.md and other designated root documents (such as robots.txt) and traverse the tree of links, generating only what is reachable. (With the option to generate a directory index for things like the existing /scratchpad.) I am not aware of anything that can do that.

Second tier requirements are: I want something that’s smart enough to not regenerate things that haven’t changed—some of these black boxes are quite expensive—and that integrates with my VCS of choice (which isn’t necessarily Git) to do so. It needs to understand nested repositories and trigger rebuilds when any of them updates. I also want it to apply minification and pre-compression to everything for which this makes sense, at site build time, so I don’t have to save minified JS or whatever into my source repo. Being able to pull library dependencies from a designated URL at build time might also be nice. Being able to inline a dependency used by a single page into that page would be super nice.

As a final wrinkle, I’m largely unimpressed by all the templating languages out there. Only Genshi that I’m aware of, actually understands HTML structure to the extent that you don’t have to manually specify the proper escaping on each and every substitution; and it seems to be dead upstream and moreover has the XML disease. (Which is how it manages to understand HTML structure to that extent, but surely someone can figure out a way to split the difference…?) I suppose I can live with manual escaping provided I don’t have to write very many templates.

So, what should I be looking at?

I intend Foliomatic primarily for personal web sites such as this one. It should also be useful for projects and organizations whose Web presence is mostly static content, updated from time to time. It is not going to be a general content management system, nor a framework for highly dynamic “Web 2.0” content, but it will support some dynamic features, such as comments on pages.

## Structure

Foliomatic is a site compiler. It reads a directory tree of source files and produces another tree of rendered, static HTML files, which you drop into your web server. Foliomatic is designed to take its input from a version control system, which handles access control and replication. It can, optionally, integrate history information from the VCS into its output.

Foliomatic is thus similar to existing systems such as Ikiwiki, Chronicle, and Jekyll. Foliomatic is more generic in some ways, and more restricted in others.

(more…)