Guide to writing for this web site

Hakyll is a static site generator written in Haskell. The rules for generating a site are written in Haskell, and they can be customized with code.

The upshot is that Hakyll can be very flexible in the things it can be made to do, which I have done with this site. However, there are an increasing number of knobs that I have added for generating the site, so I need them written down somewhere. That somewhere is here.


Hakyll metadata included for individual resources.


The fields title, description, published, and updated are standard Hakyll metadata fields with their usual meaning. They should be included in page metadata when possible.

I use the sane and sensibly lexicographically sorted date format. I.e., dates such as 2023-03-28.


Custom metadata fields which can be defined for any page.

A URL for an extra stylesheet to load for the page. For loading stylesheets only loaded by a few pages; other stylesheets will usually have dedicated metadata fields.
Extra content to include in the head HTML element.
If defined, load KaTeX resources necessary for rendering math.
If defined, load stylesheet responsible for bibliographic references.
If defined, load stylesheet responsible for syntax highlighting.
Content for a robots meta tag.
A URL for an RSS feed.

Front page

The front page will define the front metadata field.

The front page can also define a include-latest-update metadata field. If defined, it will include the latest update on the front page.


These are particular CSS elements I may need to use manually.

CSS class used with SVG images, for those whose colors should never invert on dark mode. The class should be associated with the img element inside a figure element; this is what the conversion to HTML from Markdown does.



Generic pages which are not related to updates about me or the site.
Links of interest. These are basically public bookmarks.
List of publications by yours truly.
Updates about me or the site.


Contains files related to generating stylesheets. They may be Haskell code for generating the stylesheets, or be CSS stylesheets themselves that are copied verbatim.
Haskell code for generating diagrams.
Generic files to be included as is on the site.
Images to be included as is on the site.
Files related to the server infrastructure. E.g., Apache configuration.
Hakyll templates used by the site.


Custom context

This site uses a custom siteContext instead of defaultContext. It includes customizations to the default context specific to this site. In particular, it strips index.html from directory URLs.

Generation from Haskell

haskellCompiler compiles items by running its input argument as Haskell code. The output will be taken from the standard output of the executed Haskell code.

For example:

compile $ haskellCompiler []

The code can be either Haskell or literate Haskell.

Math support

Use mathReaderOptions and mathWriterOptions to make Pandoc render math.

For example,

compile $ pandocCompilerWith mathReaderOptions mathWriterOptions

Table of contents

Use getTocOptionsWith to make Pandoc render a table of contents if the toc metadata field is defined. It is passed another Pandoc writer option as an input argument so that it can be combined with other writer options.


The dropExtensions function strips all extensions from a route. It is used for making URLs clean.


The modules under Web.Site.Rules define the rules for each portion of the web site. I have a convention of exporting rules and items functions from such modules.

The rules function should be obvious. It allows the central Web.Site.Rules module to call the rules in its sub-modules.

The items function returns the pattern which maps to resources which should be included in the sitemap. The Web.Site.Rules.Sitemap module uses them to collect the URLs to include in the sitemap for the web site.

See also