Caltech Library logo

Project Status: Active – The project has reached a stable, usable state and is being actively developed.


mkpage is a deconstructed, post modern, content management system for generating static websites. It is suited to building sites hosted on services like GitHub Pages or Amazon’s S3. It is comprised of a set of command line utilities that augment the standard suite of Unix/POSIX commands available on most POSIX based operating systems (e.g. Linux, Mac OS X, Raspberry Pi and Windows systems that have a port of Bash).

mkpage can run on machines as small as a Raspberry Pi. Its small foot print and minimal dependencies means installation usually boils down to copying the precompiled binaries to a bin directory in your path. Precompiled binaries are available for Linux, Windows and Mac OS X running on Intel as well as for the ARM7 versions of Raspbian running on Raspberry Pi. mkpage is built on Go’s text templates. The template markup is similar to the Mustache and Handlebars. It is also similar to Hugo’s template markup. mkpage has been easier for us to support when compared with more established static site generators like Jekyll Hugo and Assemble.

mkpage’s minimalism turns into an advantage when you combine mkpage with the standard suite of text processing tools available under your typical Unix/POSIX like operating systems. This makes scripting a mkpage project using languages like Bash and Python relatively straight forward. Each mkpage utility is independent. You can use as few or as many as you like when you script your website creation process. You wind up with a workflow and build process that best fits your needs.

The following command line tools come with mkpage

A quick tour

mkpage command accepts key value pairs and applies them to a Golang text/template.
The key side of a pair corresponds to the template element names that will be replaced in the render version of the document. If a key was called “Content” the template element would look like {{ .Content }}. The value of “Content” would replace {{ .Content }}. Go text/templates elements can do more than that but the is the core idea. On the value side of the key/value pair you have strings of one of four formats - plain text, markdown, fountain and JSON. These four formatted strings can be explicit strings, data from a file or content retrieved via a URL. Here’s a basic demonstration of sampling of capabilities and integrating data from the NOAA weather website.

a basic template

    {{ define "weather.tmpl" }}
    Date: {{- .now}}
    Hello {{.name -}},
    The current weather is
    {{index 0}}
    Thank you
    {{ end }}

To render the template above (i.e. weather.tmpl) is expecting values from various data sources. This break down is as follows.

the mkpage command

Here is how we would express the key/value pairs on the command line.

    mkpage "now=text:$(date)" \
        "name=text:Little Frieda" \
        "weather=" \
        signature=examples/signature.txt \

Notice the two explicit strings are prefixed with “text:” (other possible formats are “markdown:”, “json:”). Values without a prefix are assumed to be file paths. We see that in testdata/signature.txt. Likewise the weather data is coming from a URL. mkpage distinguishes that by the prefixes “http://” and “https://”. Since a HTTP response contains headers describing the content type (e.g. “Content-Type: text/markdown”) we do not require any other prefix. Likewise a filename’s extension can give us an inference of the data format it contains. “.json” is a JSON document, “.md” is a Markdown document and everything else is just plain text.

Since we are leveraging Go’s text/template the template itself can be more than a simple substitution. It can contain conditional expressions, ranges for data and even include blocks from other templates.

About Go text/template

mkpage template engine is the Go text/template package. You can get a feel for working with Go templates and mkpage by exploring mkpage’s How To. A good place to start is how to/the basics and then proceed to How To/One element.

companion utilities


mkpage comes with some helper utilities that make scripting a deconstructed content management system from Bash easier.


mkslides generates a set of HTML5 slides from a single Markdown file. It uses the same template engine as mkpage


mkrss will scan a directory tree for Markdown files and add each markdown file with a corresponding HTML file to the RSS feed generated.


frontmatter will extract a Markdown files’ front matter so you can process it with another tool. When you used in conjunction with mkpage you can render the same file into metadata about the file and HTML output. This is handy if you’re using the front matter to build up metadata in an HTML template or building a corpus JSON document for use with browser side search engines like Lunrjs.


byline will look inside a markdown file and return the first byline it finds or an empty string if it finds none. The byline is identified with a regular expression. This regular expression can be overridden with a command line option.


titleline will look inside a markdown file and return the first h1 equivalent title it finds or an empty string if it finds none.


reldocpath is intended to simplify the calculation of relative asset paths (e.g. common CSS files, images, feeds) when working from a common project directory.


You know the path from the source document to target document from the project root folder.

In Bash this would look like–

    # We know the paths relative to the project directory
    echo $(reldocpath $DOC_PATH $CSS_PATH)

the output would look like



ws is a simple static file web server. It is suitable for viewing your local copy of your static website on your machine. It runs with minimal resources and by default will serve content out to the URL http://localhost:8000. It can also be used to host a static website and has run well on small Amazon virtual machines as well as Raspberry Pi computers acting as local private network web servers.

    ws Sites/

This would start the web server up listen for browser requests on http://localhost:8000. The content viewable by your web browser would be the files inside the Sites/ directory.

    ws -url Sites/

Assume the machine where you are running ws has the name then your could point your web browser at and see the web content you have in Site/ directory.