Up until yesterday I was using a system called tahchee to generate my website. Tahchee is a website compiler. You give it templates and content and it generates static website pages. In my case, I had a single template that models a page with a header, navigation bar, content, footer. Each actual page on my website, e.g., http://bp.io/s/sds is generated by applying this template to a simple file that contains the content. The content was written in a wiki-style markup called kiwi, which then gets converted to HTML. An example of the syntax is:
I said farewell to tahchee yesterday. It’s a great system but it hasn’t been updated in a while, and now it seems a few bugs have creeped in — let’s call it old age. Tahchee operates by gluing together some other technologies, like Cheetah templates and Kiwi markup, and adds a build system to simplify combining them all together. I decided to manufacture my own glue, and it only took a day.
First, I looked around the net at the myriad templating engines. I enumerated them all and rolled a 47 sided die. It came up with Jinja2. Jinja is a general templating engine, you can use it to generate HTML, tex, txt, css, cpp, or whatever you want that is ascii/unicode based. It is available as a python library, and its syntax is similar to cheetah and all the other engines out there. A simple html template could be:
In your python program, you then execute something like:
And you get:
That’s the gist of templating engines and Jinja. The bulk of the work I had to do was to write the build system. I designed the directory structure of the source for my site as follows, this is pretty much exactly how tahchee has it.
The makeit.py script first loads all the templates from the templates directory. It then walks through the pages/ directory looking for files that are appended with an underscore (this is my way of distinguishing between files that need to be processed with Jinja.) It then runs the files through Jinja, creating a processed file without the underscore. For example _index.html will be processed and then saved as index.html. The directory structure of pages/ is mirrored in the build directory, and any files tht don’t need to be processed are copied as is. My pages/_index.html looks like the following.
{% set title=”bp.io” %}
{% block main_content_md %}
This is the project site of Ben Porter. Currently, I’m working on my PhD project: [SDS]({{ base_url }}/s/sds). Other things you’ll find here are my blog, my public code repositority, and various programs and games I’ve written over the years.
{% endblock %}
The content is written in Markdown, which is very similar to Kiwi. To add support for Markdown was trivial using Jinja2’s support for filters. You can also see that you can mix in regular html and markdown will ignore it. I also pass all the generated html through HTLMTidy in order to fix any bad markup and to also lay the html out nicely (useful for debugging the engine.) If you view the source of my website, you can see it all nicely laid out. :) (Is someone screaming nerd right now? If so, I’m happy you’ve made it this far, but now is the time to rage quit!)
The layout of my site is now done using the Blueprint CSS Framework, which offers helpful grid-based layout support, some nice typography, and some cross-platform neutralisation. I will eventually incorporate some css into my site generator, in order to make it easier to maintain and change the palette and style.
The last piece of glue is the build system. I have been using scons for a little while now, including in my main project (courtesy of BV), and so it was an obvious choice. I have a simple scons script which makes sure the makeit.py template runner is executed, and then it copies over the remaining pieces, such as assets/ which stores all the static content such as the css and images. Oh, and lastly, it’s all versioned using hg.
I have moved my website hosting over to a VPS (linode). This is so I can do some more complex server-side thingymajigs, which my last shared website host did not really support.