A Static Site Generator Written in Janet
ca25d620 — Zach Smith 14 days ago
Threads test
fb138c64 — Zach Smith 15 days ago
unit tests for generators
1e5023fe — Zach Smith 15 days ago
Refactor tests to support from-spec



You can also use your local clone with git send-email.


Il Mago

#A transparent, extensible static site generator

Bagatto is a static site generator written in Janet.

It is inspired most directly by Garrett Smith's LambdaPad, a SSG in Erlang. LambdaPad falls more to code side of the config--code spectrum, and Bagatto follows that philosophy. Thus, it's designed to expose the full expressive power and extensiblity of the language it's written in. Janet is a lisp that's designed for simplicity and ease of embedding, and thus it's a very good fit for this model.

To create a Bagatto website, you should create a single Janet source file. Because you're writing normal source code, you have the full power of the Janet language at your disposal. Bagatto tries to keep the "magic" to a minimum; in all cases, it tries to make the process of loading source files and of generating new files completely transparent, inspectable and extensible.

#The Model

In Bagatto, a website consists of two things: a data specification, and a site specification.

A data specification describes all the inputs into the site generator. These are of two main types: either Janet values or references to other source files, eg., JSON configuration files or Markdown articles. When Bagatto evaluates a data specification, it loads all of the files and parses them for arbitrary attributes. It includes some baseline attributes, like path and contents, but allows the site author to specify or implement other attribute parsers. For instance, it comes with a parser function that will read the YAML frontmatter from a Markdown file and include those as additional attributes.

Here's an example data specification:

(def data {:config {:attrs {:title "A Demo Bagatto Config"}}
           :posts {:src (bagatto/slurp-* "posts/*.md")
                   :attrs parse-post}
           :static {:src (bagatto/* "static/*")
                    :attrs bagatto/parse-base}
           :config-json {:src "config.json"
                         :attrs bagatto/parse-json}
           :config-file {:src "config.jdn"}})

A site specification describes all of the outputs of the site generator: the paths and contents of all the files that the generator should create. For static files like CSS and images, this might be as simple as copying the original file to a new path. For the generated content of the website, this will include rendering templates by using the attributes in the input step.

Here's an example site specification:

(def site {:post-index {:path index-path
                        :contents render-post-index}
           :posts {:each :posts
                   :path make-post-path
                   :contents render-post}
           :static {:each :static
                    :path make-static-path}})


A demo project can be seen in this repository. This consists of a simple module which includes some source files and some rendered pages.

To run it, navigate to the demo directory and then run bag:

code-src/bagatto/demo [master !] ⊕ bag index.janet 

Bagatto outputs the path of each file it copies or creates.

We can then open up site/index.html in a web browser and click around. Beware: it's pretty ugly. Both index.janet and the template files it references are very thoroughly commented; hopefully they can provide a whirlwind introduction.


See the Manual for a deep dive.