December 2011 — Los Angeles, CA
Writing down my thoughts allows me to crystallize my thoughts more clearly and allows me to refine my thought processes in more depth. The simple act of writing also forgoes any chance of “forgetting” what I previously thought. Furthermore, sharing these thoughts with others forces me to organize them in a way that is palatable to those who don’t think as haphazardly as I do.
As much as I enjoy art and utility of writing, my previous attempts have been thwarted by inefficient tools. This article describes the set of tools and the workflow I use to run this site. The simplicity of these tools allows me to focus on the content without tinkering with the software.
The Content. There are several CMS systems available for setting up a personal website, e.g., Wordpress. I have used Wordpress to setup other sites and it is a great tool to setup something quickly. However, I wanted something more light-weight for this site. When I write, I do many revisions over a single article. I go back and forth. I stop and I start. When inspiration strikes, I don’t have the patience to wait for a web-based CMS to load. This becomes a hindrance. I would rather write in a simple vim buffer, where I can quickly run, write, save, and exit.
I used to have a personal site back in Graduate school that I used to maintain with a series of manually written HTML files and a set of Python scripts. That was an elegant solution as it created a site with static content with minimal intervention on my part. There were no DB delays, data corruption issues, migration issues, etc. It was all very simple, easy to manage, easy to maintain, and easy to use. Focusing on these four qualities, I decided to use Tom-Preston Werner’s static-site generator, Jekyll.
Jekyll is written in Ruby and the source is clean and easy to work with, allowing one to extend it to fill voids that one might need. There are also a series of plugins here. I organize all my writings in categorical directories under the _posts directory, setting up YAML tags on each post as I need them and then letting Jekyll handle of the rest.
Edit (January, 2012): I’ve switched from Jekyll and decided to start using Jasper Van der Jeugt’s static-site generator, Hakyll. Hakyll is inspired by Jekyll and is written in Haskell. I mostly switched because I wanted to learn Haskell and the best way to do so is to start using existing projects. I also find it a bit easier to extend and configure since you can add your own custom Haskell code in the main site.hs. It offers more flexibility at the price of a steeper learning curve.
I have also stolen the site design shamelessly from Tom-Preston Werner’s personal blog. I may get around to changing the css, but for the time being I would rather focus on the content.
Finally, I track analytics for the site by embedding Google Analytics JavaScript code in each of my pages. This is easily achieved by embedding the code in a base Liquid template that Jekyll(Hakyll) can use as a basis for all other pages throughout the site.
The Backend. The entire site is served from a personal Linode instance. At the time of writing, the site is small enough to use the smallest Linode instance available, Linode 512. The pricing is also fairly reasonable for your very own virtual dedicated host. Since I am somewhat of a masochist, I chose to run Slackware on my Linode instance instead of an easier to use Ubuntu or Redhat instance. Slackware offers me the flexibility to control exactly how I want to configure my virtual host. I use that same Linode instance for example for hosting private git repositories, documents, source code, testing/staging servers, etc. I have also created the partition tables such that the system/boot partition can be replaced with with another kernel version without affecting installed applications, libraries, and data.
Once Slackware is setup, I chose nginx to serve the static webpages instead of Apache. nginx is light-weight, flexible, easy to setup (see nginx documentation) and is extremely fast for serving static content. Setting up NS servers, A records, CNAME records, etc is also easy to do using Linode’s DNS Manager.
The Workflow. The combination of Jekyll(Hakyll) and a virtual dedicated host simplifies the entire authorship workflow. I use my favorite text-editor, vim, to write an article in plain text. I prefer to use the Markdown syntax over Textile; Jekyll(Hakyll) supports both, but I find Markdown to be more readable and writable in plain text. While writing, Jekyll(Hakyll) runs in the background, auto-generating the site when the markdown file changes. This allows me to make changes and quickly test out how they will look by browsing to “localhost:4000”. Once I am happy with my changes, I commit my writing and any changed files into git and push the changes up to github. Yes, the source for this site is hosted on github, here.
Once the changes have been pushed upstream, a POST-RECEIVE hook triggers a simple script on my Linode instance that will build the website using Jekyll(Hakyll) and copy it to the to nginx service directory. All fully automated from a single git-push! Another fringe benefit of using github besides having a history-tracked backup of my site is that I can virtually write and update my site from anywhere. All I need is a terminal and vim. My good friend, Benedikt Terhechte setup his blog using a similar process and is also using the Cloud9 IDE with a vim plugin so that he can edit and update his site from anywhere that has an internet connection. I personally prefer ssh’ing into my Linode instance and using vim for remote editing and publishing.
Dynamic Content. Client-side JavaScript has redefined what it means to have dynamic content on websites. It used to be that most dynamic content was generated in the backend and then served as static HTML pages. However, there are several services now that can make use of client-side JavaScript to achieve sophisticated dynamic functionality. A good example is the use of Google Analytics on this site to track the site’s accessibility patterns. Dynamic comments, trackbacks, and social media discussions can also be used easily with a few lines of JavaScript by using a service like Disqus, livefyre, or Facebook.
| Tweet |