I like to use my personal projects as opportunities to learn about new things. Sometimes I explicitly try to reinvent the wheel — after all, this is my time to learn how to make a useful round object. I dedicate a certain amount of time every week to this type of tinkering, and the tool chain used to build this website is a result of such activity.
One day I’ll spend some time explaining why I think tinkering is so important, but to summarize it quickly, tinkering is about becoming and staying a well rounded programmer by gaining different perspectives on technology not encountered in your typical professional life.
My goal for the FITNR website is simple: I want to build a place on the web that I can share some of my thoughts, but I want to do it my way — more on this later. The very reason why I don’t use tools like WordPress is because launching this website is an opportunity for me to learn — consistent with the philosophy described above.
The manner in which I edit, build, and publish Fixed in the Next Release is partly an experiment in building a publishing system around my favorite tools and partly an exploration of how interesting a website one can build without relying on a server side component. Quite simply, can I make the mashup-potatoes taste good enough — is it possible, without all that lovely server side butter? This is just one big opportunity to tinker.
To summarize, here are my requirements:
- No dynamic, server-side content generation
- Must have some way of engaging in public discussion
- Must support searching
- Must support tagging
- Must generate a feed of some type, probably RSS
First, let’s talk about the tool chain. I love programming languages. When I’m tinkering, I like to use languages that don’t always make it into my professional life. For this website, I wanted to use Python for everything and that naturally lead me to Jinja2 for a templating system as the basis for my HTML generation.
Jinja2 is neat. The template syntax follows that of Django’s lovely syntax, in fact the original hack of this site was written using Django’s template system by itself and I was able to switch to Jinja2 with only one or two minor modifications. Template inheritance, filters, and blocks make putting together something like FITNR a piece of cake.
When it comes to authoring the content I really only need (or want) one thing: vim. Jinja2 continued to fulfill it’s promise of sweetness by already having a vim syntax definition for their templating.
- Launch vim
… sweet colors, niceset ft=htmljinja
Of course, the actual articles are written using Markdown and there is vim a syntax definition for it as well. Finally, I integrated SmartyPants to add a bit of flare to my web typography. Luckily, for both of these bits there are nice Python libraries that do the heavy lifting.
Revision control was simple: everything lives in Subversion.
It turns out, what I really wanted was to be true to the Unix philosophy, partially shown below (courtesy of Wikipedia):
Write programs that do one thing and do it well. Write programs to work together. Write programs to handle text streams.
This was my primary requirement, and I had to be able to wire it all up with Python easily. No monolithic tools here, thank you very much!
How it Works
It all turned out quite nice, actually. I have a basic site structure as follows:
The directory structure provides a nice segmentation of the various inputs required to make the site happen:
- content — articles that will be published, many of which currently sit in an unfinished state
- pages — the actual site structure, built with static html and Jinja2 templates, including my feed
- templates — common layouts and designs written in Jinja2’s template language
When I want to start working on a new article I create a file in the
directory. This file has a simplistic structure: a series of faux email-style headers that define meta-data, followed by an empty line, followed by the actual content written in Markdown syntax.
The files in the
directory use the data from the
directory to render the site. Each page can be a Jinja2 template and can generate any content I wish. For example, I have a page that actually generates my feed for me.
I have two simple Python programs. One is called
that 111 lines of code, including comments, that does the following:
- Recurse into the
directory and parse each of the posts.content
- Recurse into the
directory and pass each page to Jinja2 for template processing.pages
- Jinja2 processes the template, and loads any required parent templates from the
directory as they are needed.templates
- Copies the files from the
folder into a build directory.assets
- Saves each of the rendered pages into the build directory.
The other Python script is a simple web server that uses
from Python’s standard library. It’s all of 21 lines of code and allows me to preview the site before publishing.
So how did I do against my original goals?
- No dynamic, server-side content generation — ✔ No problems here, everything is static
- Must have some way of engaging in public discussion — ✔ I sort of cheated on this, but only sort of. I created a Google Group called fitnr-discuss (NO LONGER ACTIVE) that you can join if you’d like to discuss what you see on this site.
- Must support searching — Not yet
- Must support tagging — Not yet
- Must generate a feed of some type, probably RSS — ✔ I generate an RSS v2 feed here
There are quite a few things I’d like to add to the site in the future, but first I need to complete the tagging and searching functionality. For tagging I just need to code up the views that I’d like to expose, and for searching it’s a matter of reading some Google API documentation.
There are some other obvious things that need to be done sooner rather than later, most notable I need to finish the archive functionality so that each post gets a permanent link.