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
- Clone this repository to somewhere your ASDF can locate.
- Enter to the cloned repository and run
make
, ormake 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 tosite-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