Academic site of Carl Ellis

/content/articles/jimhi

Jimhi - Motivation and Architecture

After having gone through many iterations of personal websites over the years, I noticed that a lot of my time spent maintaining them was not devoted to producing content. Instead, I found myself striving to make them seem technically impressive, or fixing a bug which was the result of said technical impression.

Fed up with my own failings, I analysed what a personal website actually should be. A collection of documents one wishes to share with the internet, and some form of website glue holding them together (a menu of some sort). Obviously some documents will be related to each other, and so a tree structure forms quite quickly. What keeps documents loosely related in a tree structure? File systems do. The folder/file construct has existed for years. So, what I personally wanted was a website which was file browser, with my documents being the files.

Building one of these sites manually is trivial. You make your documents and put them in the proper structure; then make your menu, which depending on your site's size can be a massive task. To keep the menu separate you can use frames (eww), or some server-scripting which puts the menu in a div. It is still a pain changing anything, never mind rearranging your files.

For my website, I still wanted a bit of technical fanciness, but one which I could write once and leave forever, bugs willing. So something generic, stable, and damn easy to debug. Coming from a rails background, I chose Ruby to develop with. I have developed with PHP before but found Ruby to be a little more elegant.

The Architecture

The little engine behind this website is simple. Almost small lawnmower engine simple. Two classes are used a Page and a Manifest. Page contains all the info you need about a page, namely its name and location. Manifest simply houses all the pages of a given directory, and then calculates each pages parent, siblings, and children.

To clarify:

A parent is the page describing the folder a file is in, e.g. Articles.
A sibling is any page in the same folder.
A child is opposite of parent, any page in the directory being described by the page in question.

Another class PageMarshaller provides a simple API to access and group some of these properties into useful formats, e.g. sibs = getSiblings(page). With the content engine done, all that was needed was something to tie it all together.

Lets break down what happens when you access a site. You go to an address of the following: "http://domain/path/to/document". With that model, many files can be accessed and so many files must have a menu knowing its exact place in the hierarchy. So, using mod_rw the URL is rewritten to the form "http://domain/index.rb?path=path/to/document". This puts all user queries into one route, allowing me to build a context aware menu based upon supposed location in the hierarchy.

General Architecture

This approach also allows me to catch access to pages which don't exist, ensure JavaScript libraries which are needed are loaded, and to control CSS so some tired mistake whilst working on a document doesn't cascade up and break something important. CSS is rolled out so the deeper document's CSS is put at the top of the declaration, and important stuff put at the end, so it always overwrites.

To conclude, this site is a generic document viewer which will monitor a given directory and build a dynamic menu and hierarchical CSS system around it. Each document is designated a parent, siblings, and children. To modify the website, more documents need only be placed in to the monitored folder. Using mod_rw sitemap.txt points to another ruby script which uses the manifest to its advantage, ensuring the correct URLs are within Google's index.