tinygen.py
Here's the script that I use to generate this site from jinja2 templates! It has a couple of direct dependencies, namely jinja2 (obviously), frontmatter, and optionally html5print. I'll run over the code, getting set up, and a little documentation later on.
Setup
First off, you'll need to install two python dependencies: the Jinja2 API for the templates, and Python Frontmatter for the site content. These can be installed with your systems pip tool, for example:
There is also an optional dependency: html5print , which is used for making the HTML output more readable. I'd recommend installing it because the output is pretty horrible otherwise.
After that, just copy and paste the following code into a python file (preferably named tinygen.py, for brand visibility) and put it in a blank directory where your site will go.
The Code
import os import sys import shutil import frontmatter import jinja2 try: import html5print # optional html prettification, requires html5print except ImportError: print("html5print module not found. Rendering site without beautification.") # set up the jinja2 environment env = jinja2.Environment( loader = jinja2.FileSystemLoader("templates") ) # render a content file def render(path): print("Rendering " + path) f = frontmatter.load(path) # parse YAML frontmatter # check for metadata if f.metadata == {}: print("Warning: " + path + " has no YAML frontmatter.") print("Raw HTML and non-HTML files should be put in the 'static' directory") return open(path).read() # retrieve template try: t = env.get_template(f.metadata.pop("template")) except KeyError: print("Error: " + path + " has no valid template key! Using raw content.") return f.content o = t.render(f.metadata, content = f.content) # render # optional html prettyfication, requires html5print if 'html5print' in sys.modules and "nobeautify" not in f.metadata: o = html5print.HTMLBeautifier.beautify(o, 4) return o def main(): # check that all the correct directories are in place nodir = False if not os.path.exists("content"): print("Error: 'content' directory required!") nodir = True if not os.path.exists("static"): print("Error: 'static' directory required!") nodir = True if not os.path.exists("templates"): print("Error: 'content' directory required!") nodir = True if nodir: sys.exit() # remove _site folder if it exists already if os.path.exists("_site"): shutil.rmtree("_site") # copy static folder as _site shutil.copytree("static", "_site") # step through the content directory for (root, dirs, files) in os.walk("content"): # remake each subdirectory in the _site directory if it doesnt already exist for d in dirs: if not os.path.exists(os.path.join("_site", root[8:], d)): os.mkdir(os.path.join("_site", root[8:], d)) for f in files: # render file r = render(os.path.join(root, f)) # write the rendered file to the _site directory n = open(os.path.join("_site", root[8:], f), "w") n.write(r) n.close main()
How to use??????
In the directory containing tinygen.py, you'll want to make three more directories named "templates" , "content" and "static" . The "templates" directory will contain all of your jinja2 templates, the "content" directory will contain all of the content you'll be rendering, and the "static" folder will contain all of the content that you won't be rendering, such as images, scripts or stylesheets.
Those content files should be written in HTML appended with YAML Frontmatter (with the usual three hyphens before and after). The HTML content will be passed to the jinja2 renderer as under the "content" key. There is only one key that is required, which is "template" . This tells the renderer which template to use; just put in the filename. There's only one other key that is interpreted: "nobeautify" . If this key is present, the output HTML file will not be beautified by html5print, even if you have it installed.
The folder structure is fery flexible: when you run the script, it will render the whole filetree in "content" and merge it with "static" , outputting it into a new directory called "_site" while preserving both directory structures.
You can find further jinja2 template documentation here , and YAML documentation here .