Grimoire Manual

Clone me from GitHub!

Grimoire is a minuscule static site generator written in Python. It focuses on generating content from simple data to be integrated in layouts. The root directory of a site should contain a site.json descriptor file and a layouts/ directory containing all of the layouts to be used. Layouts can be any type of text files, including but not limited to HTML, CSS or SVG. The site descriptor file gives global variable and site categories to be loaded. It ressemble the following example :

{
	"site": "My Blog",
	"rootDirectory": "blog/",
	"categories":[
	{
		"category": "Posts",
		"reader": "postReader",
		"files": "true",
		"directories": "false"
	},
	{
		"category": "Gallery",
		"reader": "imageReader",
		"files": "true",
		"directories": "true"
	}],
	"description": "My Blog, built by Grimoire",
	"title": "My Blog",
	"githubUsername": "myUsername",
	"someOtherVariable": "someValue"
}
  • site : Code name of the site.
  • rootDirectory : Root directory of the site.
  • description : Description of the site.
  • title : Title of the site.
  • categories : List of the categories in the site (an array).
  • category : Category name and directory name from which the resource will be loaded.
  • reader : Name of the function to be used to read each resource file. Directories will not be read.
  • files : List the files in the category (true or false). The listing is recursive.
  • directories : List the directories in the category (true or false). The listing is recursive.

Grimoire will start by listing all the files in layouts/ and then, all the files and directories (if enabled) in the categories (here Posts/ and Gallery/). For each file found it will attempt to read it with the specified eader functions. Readers are located in the Modules/ directory. Each contains a python function def apply(filename): which returns a tupple made of two elements, the first is a dictionnary of the data (key and value pairs) the other is the content of the resource. Both can be left empty if needed.

Each layout file can either be a raw text file or a text file with JSON header to declare variables separated from the text by a delimitation : -----. To generate HTML pages the header must contain one of the two following variable : "generate" : "path/filename.html" or "foreach" : "var in site.variableList". The first will generate a single page and the second will generate one page per resource, each page will be saved to the same path as the resource with a standard HTML extension.

{
	"generate": "index.html",
	"someVariable": "someValue"
}
-----
<!-- Some header -->
This is the index page.
<!-- Some footer -->

And for each of the posts :

{
	"foreach": "post in site.categories.Posts.data",
	"someVariable": "someValue"
}
-----
<!-- Some header -->
<h1>{{post.title}}</h1>
{{post.content}}
<!-- Some footer -->

Variables are surrounded by {{ and }}. They are given as a standard object to member notation, with dots as separator : {{ rootObject.obj1.obj2.value }} and can support spaces with double quotes : {{ rootObject."another object".value }}. The following variables are set by default :

Variable Description
site Main site variable.
site.site Name of the site.
site.rootDirectory Root directory of the site on the server.
site.dirname Local root directory.
side.outputDirname Local output directory name.
site.someVariable Any variable someVariable defined in site.json.
site.layouts All the listed layouts, by name.
site.layouts.myLayout Layout variable corresponding to the file layouts/myLayout.ext (all the files there must have a different name).
site.layouts.myLayout.content Content of the previous file.
site.layouts.myLayout.someVariable Any variable someVariable defined in the header of the previous file.
site.categories Contains all the categories listed in alphabetical order.
site.categories.myCategory Object containing the category myCategory.
site.categories.myCategories.someVariable Any variable someVariable defined in the category descriptor in site.json.
site.categories.myCategories.data List of the resource loaded for this category (to be iterated), in alphabetical order.
site.categories.myCategories.data."CategoryName/filename.ext" Particular resource file content.
site.categories.myCategories.data."CategoryName/filename.ext".content Content of a particular resource.
site.categories.myCategories.data."CategoryName/filename.ext".someVariable Any variable someVariable defined in the header of the resource.

For each resource we also have the following additional variables (resource is an arbitrary name here) :

Variable Description
resource.name Name of the resource (filename without path nor extension).
resource.isFile Defined if this is a file.
resource.filename Filename of the resource.
resource.basename Basename of the resource.
resource.dirname Directory name of the resource
resource.localFilename Filename from the site root.
resource.localDirname Dirname from the site root.
resource.directoryName Name of the containing directory (without path).
resource.parentDirname Directory name of the parent (or None if it does not exist).
resource.localParentDirname Parent directory name from the site root.
resource.outputDirname Directory name for the output file.
resource.urlDirname Directory url for the output file.
resource.outputFilename Output filename.
resource.url Url of the page associated with resource.
resource.urlRaw Url of the resource.
resource.firstFilename Filename of the first file in the current directory.
resource.firstFile First file in the current directory.
resource.firstDirname Directory name of the first directory in the current directory.
resource.firstDirectory First directory in the current directory
resource.previousFilename Filename of the previous file in the current directory.
resource.previousFile Previous file in the current directory.
resource.previousDirname Previous directory name in the current directory.
resource.previousDirectory Previous directory in the current directory.
resource.previousName Name of the previous item in the current directory.
resource.previous Previous item in the current directory.
resource.nextFilename Filename of the next file in the current directory.
resource.nextFile Next file in the current directory.
resource.nextDirname Next directory name in the current directory.
resource.nextDirectory Next directory in the cyrrent directory.
resource.nextName Next item name in the current directory.
resource.next Next item in the current directory.
resource.lastFilename Filename of the last file in the current directory.
resource.lastFile Last file in the current directory.
resource.lastDirname Directory name of the last directory in the current directory.
resource.lastDirectory Last directory in the current directory.
resource.lastName Name of the last item in the current directory.
resource.last Last item in the current directory.
resource.parentDirname Directory name of the parent directory.
resource.parent Parent directory.
resource.subFilenames Filenames of the children files.
resource.subFiles Children files.
resource.subDirnames Directory names of the children directories.
resource.subDirectories Children directories.
resource.subNames Names of the children items.
resource.sub Children items.

It is also possible to process information from the layouts with three constructs :

{% if object.variable %%
This text will be present in the final page if object.variable exists.
%}
{% ifnot object.variable %%
This text will be present in the final page if object.variable does not exist.
%}
Elements list :
{% foreach element in object.list %%
	Here is another value : {{element.someValue}}
%}
Calling a function from the Modules/ folder :
{% call myFunction arg1 arg2 %%
	Some relevant body.
%}

Finally, we can generate the site from the resources with the command : python /path/to/grimoire.py from within the site directory. You can also start a local server with : python /path/to/grimoire.py --serve --port 8000