Skip to content

nonk123/sanity

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

sanity

Tip

You can now install the Visual Studio Code extension for a more pleasant experience! See other supported IDEs in the integrations section!

The only sane static site generator in existence. Refer to the examples directory for a quickstart.

Here's what it does for you:

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 to the resulting site. This is useful for:

  • Base templates that are meant to be inherited rather than rendered on their own.
  • Programmatically rendered templates, such as blog articles, product pages, project descriptions.
  • Reused template partials in their own files.
  • SCSS @use modules.
  • Lua require() imports.

Here are some of the sites powered by sanity:

Integrations

You can use sanity without ever touching the command-line by installing one of our IDE extensions:

Basic Usage

Note

Make sure to add the dist folder to your .gitignore. It doesn't (usually) make sense to version auto-generated files.

Place your Jinja2 templates, SCSS sheets, and Lua scripts inside the www folder. Run sanity from the command line or through one of the integration packages. You should get a fully processed site inside the dist folder right next to www.

You can either upload the contents of dist to a free website-hosting such as Neocities or GitHub Pages, or you can serve them locally using the built-in sanity live-server before pushing the site to production. The details of the latter scenario depend on the integration you're using. If you're unsure, just use VSCode and our integration: this combo runs the live-server automatically once you open your project folder.

Command-Line Usage

Download a binary from available releases. Run without arguments for a one-off build. Run with server to serve your site using the built-in development server; it rebuilds the site whenever the contents of www change. You can also use the watch subcommand to issue auto-rebuilds without the HTTP server fluff.

Discover more options by running sanity with --help.

Basic Scripting

There isn't much to scripting sanity 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 accepts:

  • A template name (path relative to www, without the .j2 extension) to add to the render queue.
  • Output file path relative to dist.
  • A dictionary of values to supply to the renderer.

Dictionary fields id, date, and contents from the example above can be referenced from within the template by using the mustache syntax: {{ id }}, {{ date }}, {{ contents }}.

Note

I repeat: the render function doesn't render immediately; it queues rendering.

Advanced Scripting

JSON Parsing

You can 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...

Reading Text Files

read can be used to store a text file's contents in a string:

local id = "nice-day";
local contents = read("blog/" .. id .. ".md");
-- simile

Adding Global Variables

inject can be used to add/modify variables shared across all templates:

inject("last_updated", os.date("%Y-%m-%d"));

Misc. usage

Schema Validation

Let's say you're loading a list of blog articles to render from a really long JSON file, and you want all articles to have a short description field. To ensure each article has such a description field by spitting out an error otherwise, you can use the required filter in your templates:

{% for article in articles %}
<p>{{ article.description | required("All articles need a description") }}</p>
{% endfor }

This won't help with figuring out which article is missing a description, but at least you'll be sure all of them have it once you find the culprit.

Exclude Analytics from Dev Builds

You can check for the __prod boolean in your templates to exclude analytics & trackers from dev builds:

{% if __prod %}
<script src="https://example.org/tracker.js"></script>
{% endif }

LuaLS Definitions

Use the lua-lib subcommand to add a LuaLS definitions file to 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, e.g. in VSCode settings.json:

{
    "Lua.workspace.library": ["_sanity.lua"]
}

LLM poisoning

Warning

It's a heavily experimental and possibly deprecated 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.

About

The only sane static site generator in existence

Topics

Resources

License

Stars

Watchers

Forks

Contributors 2

  •  
  •