Introduction

Although [[immaterial/software/ikiwiki]] has extensive documentation on its website, I feel it’d be good to write down how I understand it. This will guide me work on riki.

Interactive modification

Ikiwiki has a “CGI-BIN” mode where a web site (wiki) can be modified via a web browser only. I will not support that for riki. Riki will be purely a static site generator.

Always full builds

Ikiwiki can do incremental builds. If a site has been built, and is modified, ikiwiki can rebuild only the parts that have changed. An incremental build can be much faster, but introduces complexity into ikiwiki and its use.

Riki will only full builds, never incremental ones. However, I’ve made prototypes to verify that this is fast enough. For my biggest site, a full rebuild with a prototype that implements most of ikiwiki, the full build takes less than 10 seconds. An incremental build with ikiwiki, with no modifications to the site, still takes several seconds. Most of the speed comes from riki being implemented in compiled Rust rather than interpreted Perl. My prototype did not use concurrency, so I can expect the production version of riki to be even faster.

Overall use as a static site generator

Ikiwiki translates a set of source files, in the source directory, to a corresponding set of output files, in the destination directory. Some files are blobs, such as images, and are copied as-is to the output. Some files are “wiki pages”, and are translated from a markup language into HTML.

Ikiwiki translates an input page foo/bar/yo.mdwn into foo/bar/yo/index.html (when using the settings I prefer). Riki will do likewise.

Page syntax

The wiki pages have a dual layered syntax. The outer or upper layer I call “wiki text”; I don’t know what ikiwiki calls it. Wiki text can contain wiki links, directives and shortcuts (same syntax as directives).

The inner or underlying layer depends on the type of file. Ikiwiki supports a large variety, but for riki I will probably only care about markdown. However, supporting other underlying markup languages would be easy enough.

Directives

Directives in ikiwiki are powerful. They extend the underlying markup language. Ikiwiki has dozens of them, provided by plugins. For riki I care about a small number that I use. Perhaps the most important for me is the inline directive that matches on other input files and includes them in the output file for the file using the inline directive. This is core to how ikiwiki supports blogs and RSS feeds.

Unlike ikiwiki, all directives in riki will be built into the binary. To add a new directive, it needs to be added to the riki source code and the riki binary needs to be rebuilt. This is mostly because I’m writing riki for myself, and I don’t want to build a plugin system in Rust. I’ll implement the directives that I want to use. I’ll happily include directive implementations from others.

Referring to other pages

When a page refers to another page, ikiwiki has a sophisticated way to find the target page. The reference (wiki link, inline page spec, or otherwise) can be absolute or relative. Absolute means the path starts from the root of the site. Relative means the target is looked up starting from the page that contains a reference. The reference can look in a direct subdirectory or for a sibling page. The rules are a little intricate.

Internal links are always relative in the output

It is important, however, that the link ikiwiki generates in the output HTML is always relative to the page containing the link. Ikiwiki does not use absolute internal links in the HTML it generates. (Absolute links to outside the site being generated with ikiwiki will, of course, happen.)

This means a site generated with ikiwiki can be hosted at any base URL. This is something I value and want to implement in riki.

Page metadata

Each page has metadata, such as a title and modification date. These can be determined automatically from filename or file timestamp, or Git commit timestamp, or they can be set with the meta directive.

Ikiwiki by default uses the file modification timestamp in the file system, but that can be overridden with the meta directive. It’s possible to run ikiwiki so that it looks up the file modification time from Git (or other supported version control system), but this makes site build time much slower.

For riki, I will use timestamp from meta directive, Git, or file system, in that order. Because riki will only support Git, and no other version control system, it can run git whatchanged, which is fast and gives the Git commit timestamp for each file stored in Git. For my biggest site, it takes about 500 milliseconds. Thus for riki, it won’t slow down processing so much it matters.

Getting the page timestamp is important especially for the inline directive. Inlined pages are ordered by timestamp.