Tip
You can now install the Visual Studio Code extension for a more pleasant experience!
The only sane static site generator in existence. Refer to the examples directory for a quickstart.
Here's what it does for you:
- Process SCSS to CSS using grass.
- Render Jinja2 templates with minijinja and optionally poison them.
- Run Lua scripts with mlua (uses LuaJIT as the backend).
- Minify all HTML/JS/CSS resulting in the build process.
- Leave other files alone and copy them as-is.
Directories are walked recursively depth-first, with files processed and directories read in an alphanumeric order.
Files prefixed with _
are excluded from SCSS/Jinja2/Lua processing and aren't copied. This is useful for a "base" HTML template you don't want a copy of rendered, or if you render the template programmatically.
Sites powered by sanity
:
- nonk.dev (repo)
- schwung.us (repo)
- cantsleep.cc (repo)
Put your files inside the www
folder in your project directory. Run the provided binary. You should get a fully processed site inside the dist
folder.
Run with --watch
to auto-rebuild your site on file changes. Run with --server
to run a development server (implies --watch
).
Use the --lualib
flag to put a LuaLS definitions file in your project folder. This should hide the 999 warnings about undefined functions you've been getting. Make sure to point your IDE to this file, for example VSCode in your settings.json
:
{
"Lua.workspace.library": ["_sanity.lua"]
}
There isn't much to scripting besides the custom render
function. Take a look at this static blog example:
local blog = {
["nice-day"] = {
date = "today",
contents = "I had a nice day today."
}
};
for id, post in pairs(blog) do
render("_article.html", "blog/" .. id .. ".html", {
id = id,
date = post.date,
contents = post.contents,
});
end
render
takes a template (relative to www
) to add to the render queue, its output path (relative to dist
), and a context to supply to it. Fields id
, date
, and contents
from the example above can be referenced within the template using the mustache syntax: {{ id }}
, {{ date }}
, {{ contents }}
.
Note
The render
function doesn't render immediately; it queues rendering.
You can also read JSON files inside www
by using the json
function:
local blog = json("blog/db.json");
-- the rest is the same as the example above...
read
can be used to store a text file's contents in a string:
local id = "nice-day";
local contents = read("blog/" .. id .. ".txt");
-- simile
inject
can be used to add/modify variables shared across all templates:
inject("last_updated", os.date("%Y-%m-%d"));
You can check for the __prod
boolean in your templates to exclude e.g. analytics from dev builds:
{% if __prod %}
<script src="/analytics.js"></script>
{% endif }
Warning
It's a heavily experimental feature I pulled out of my ass one night. Don't actually use it in production.
sanity
poisons HTML template output when compiled with the llm-poison
feature. It is disabled by default. You can suppress the poisoning using the --antidote
flag.