mokubune - a static site generator

mokubune

A static site generating program (or you can think it as a batch processor) written in Common Lisp, try to be as intuitive as possible:

  • Try to be intuitive when selecting template file to apply. I found some other similar programs have very confusing template selecting logic.
  • Don't regenerate pages that has no change on its dependencies. This is one of the reasons I write this program - the tool I previously used regenerates everything each time, which is inconvenience when for example publishing site via rsync.

What mokubune does

mokubune will:

  • Read files from a source directory
  • For each file, base on a configurable rule set:

    • if file should be applied to template, then apply it, and write to a output directory
    • if file should be copied, then copy it to a output directory
  • Generate index page for the source directory and sub directories of it

mobubune will NOT:

mokubune does not convert files between different formats, like Markdown to HTML.

It's designed mainly for my personal use case: contents are written in gemtext markup language, and are published as both a Gemini capsule and a web site. mokubune is used for the Gemini capsule part. For the web site part, I wrote a simple tool gem2site which converts the Gemini capsule generated by mokubune to HTML static pages. Thanks to the simplicity of gemtext, it's easy to write such a tool.

Gemtext is the first citizen format of Gemini Protocol as HTML to the web, so there is no need to perform format converting.

Installation

mokubune has been tested only on SBCL and Linux.

Dependencies

  • A working Quicklisp installation.
  • cl-template-trim - it's currently not on Quicklisp, so you need to download it from here and put to somewhere your ASDF can locate.
  • Other libraries are all on Quicklisp already, you don't need to install them manually.

Install

  1. Clone this repository to somewhere your ASDF can locate.
  2. Enter to the cloned repository and run make, or make install if you want to install to system location.

Usage

mokubune --help:

Usage: mokubune
  Process current directory.

Usage: mokubune <flag>
  -init             Create default templates and directory layout in current directoy.
  -version          Print version information and exit.

Configuration

Configuring mokubune by creating a config.lisp in your site's root directory. It's just lisp, and will be loaded into the same package of mokubune's code.

So there is really no limitation what you can do in it - you can even re defun mokubune's function if you want, although normally you don't want to do that. There are some variables you may actually want to configure, and helper functions are provided:

  (config site-title "cranej's personal site")
  (config site-base-url "https://your-site-url")

  ;;; if you have non default directory layout
  ;; (config site-content-dir "my-contents/")
  ;; (config site-template-dir "my-templates/")
  ;; (config site-output-dir "my-outputs/")
  
  ;;; uncomment if you want to apply templates to markdown files other than copying
  ;; (add-rule "*.md" :apply-template)

  ;;; you can even also templates to certain text files
  ;; (add-rule "*post*.txt" :apply-template)

  ;; tell mokubune to print more messages
  (be-verbose)

Template Syntax

mokubune use a modified version of cl-template, please refer to its document.

Variables available in templates

Templates are run inside the same package of mokubune code, so again there is no limitation of what you can access. The below variables are provided for conveniences:

  • page is an instance of:

      (defclass page ()
         ((title :accessor page-title :initarg :title)
          (url :accessor page-url :initarg :url)
          (date :accessor page-date :initarg :date)
          (body :accessor page-body :initarg :body)))
    
    • title is from the first heading - line starts with one or more "#"
    • url is the path of the generated file relative to site-output-dir, for example "en/posts/post-2023-12-01.gmi"
    • date is from then end of file path, or the first heading with YYYY-mm-dd if cannot be found in file path (for example from heading "## 2023-08-12 new segment…").
    • body is the content of corresponding source file.
  • page-parent directory path of the page, for example, page-parent of "en/posts/post-2023-12-01.gmi" is "en/posts".
  • children if current page is an index page, it's a list of file objects of the index page's siblings. Otherwise it's nil.
  • site is an instance of:

      (defstruct site
        (title "My brilliant writes" :type string)
        (content-dir "contents/" :type string)
        (template-dir "templates/" :type string)
        (output-dir "public/" :type string)
        (base-url "" :type string)
        (data (make-hash-table :test 'equal)))
    

Template Selection

The general rule is, mokubune firstly try to use the specific template for the content, and if it does not exist, fallback to the one at the root of templates directory. This provides a possibility to use different templates for some contents.

Regular page

All files under contents directory other than index files (all "index.*" files) are treated as regular pages. The first exists template file at the following locations will be used:

  • templates/<corresponding sub directories>/page.clt
  • templates/page.clt

For example, for page contents/sub1/post-123.gmi, if templates/sub1/page.clt exists, it will be used. Otherwise use templates/page.clt.

Index pages

Index pages are special. The usual workflow for static site generating program is something more or less like translating contents wrote by users to destnation directory. But for index pages, it's not unusual that there is no user wrote content at all. Some other similar program requires there is at least a empty file inside contents directory, only then index pages will be generated. Mokubune takes a different approach that if it's able to find applicable template files, index pages are generated even there is no corresponding pages in contents directory.

Root index page

Root index page is the index page at your site's root.

  • Always use template file "templates/index.clt".
  • If there is no such file, root index page will not be generated.
Index page of sub directories

Index page will be generated for sub directoies if there is a template file which is "applicable".

If there is a content file index.gmi under the corresponding contents sub directory, the first exists template at the following locations will be used:

  • templates/<sub directory>/index.clt
  • templates/sub-index.clt
  • templates/index.clt

If there is no content file exists, index page will be generated only when the following template file exists:

  • templates/<sub directory>/index.clt