spoonful is a static site generator written in Nix.
Features #
- RSS feed generation
- Allows working directly with HTML, exposing extra information via Nix
- Easily hackable
- Fast, cached compilation
Usage #
Using mkSite #
mkSite provides the core functionality of spoonful, creating and combining
the post, index, and RSS derivations. It expects the following arguments:
metadata ? {}an attribute set with your website's title, description, and link.posts ? []a list of posts to be generated.generateRSS ? trueif an RSS feed should be generated.static ? nullan optional folder to be included in your website as-is.libjustspoonful.lib, you can inherit this or use it to override functionstemplates ? {}the HTML templates used to generate posts.
Example #
spoonful.lib.mkSite (lib: {
inherit lib;
static = ./static;
posts = builtins.sort lib.sorting.byDate (lib.importPosts ./content);
templates = lib.importTemplates ./templates;
metadata = {
title = "My Blog";
description = "A blog.";
link = "http://127.0.0.1:9999";
};
});
Creating a post #
Posts are Nix functions which take all the arguments passed to mksite and
return an attribute set with the following parameters:
title ? "Title"the post's title.description ? "Description"a description of the post.content ? ""the markdown of the post either as a file path or a string.datean attribute set with theday,month, andyearthe post was uploaded.slug ? <slug>the post's slug, optionally generated from the post's title.templatethe HTML template used to generate the post.url ? "/posts/<slug>"the URL the post is generated at.rss ? truewhether the post is included in the RSS feed.
When exposed in a template, posts have the following additional attributes:
slugthe post's slug.urlthe URL of the post.contentthe HTML representation of your post's markdown.nextthe next post in the list.prevthe previous post in the list.
Example #
{templates, ...}: {
title = "Post Title";
description = "Post description";
content = ./content.md;
template = templates.post;
date = {
day = 26;
month = 02;
year = 2026;
};
}
Writing Templates #
Templates are functions that take all the attributes passed to spoonful.mkSite
as arguments and the current post, then return the HTML for the page as a string.
The only required template is index which defines how index.html should be
generated.
Helper Functions #
spoonful also provides various helper functions to make your life easier.
lib.sorting.byDate #
Provides a condition for builtins.sort which sorts posts by date.
lib.importPosts #
Recursively imports all posts in a directory.
lib.importTemplates #
Recursively imports all templates in a directory.
lib.toKebabCase #
Converts any string to one in kebab-case. Used internally for slug generation.
Examples #
The following websites use spoonful:
If you would like your website added here then please open an issue or PR.
Credits #
Many thanks to Llakala for her work on the recursive import functions and the toKebabCase.