Skip to content →

Finally, blog software that doesn’t suck

I followed up on my previous post and wrote some blog software that doesn’t suck. I’m surprised how little time it took me. It was less than 12 hours from start to finish. I saved a ton of time by not rewriting the whole plethora of individual services that go with a blog.


The back-end is written on top of Django. I actually didn’t write a single form handler in the entire application, which gives me a happy feeling! The admin was generated for me (possibly Django’s best feature.) Django also quickly afforded me a lot of other features I’ll discuss later.


I was able to avoid writing yet another commenting system by just using Disqus, which worked out pretty well. I’ve heard mixed reviews of Disqus, but my experience was pretty nice. Everything was surprisingly skinnable, I’d expected that portion to be locked down somehow, but it wasn’t. The only downside to this is that I lost my existing comment data. I’m checking if I can write a program to import my old comments into Disqus.


For search, I of course used Google Custom Search. This is a given, I think 😀 It’s already 100% better than the search of my previous blog software.


I implemented Markdown support, with Pygments integration and syntax highlighting for code samples I post. The syntax highlighting support is now so much better, because Markdown automatically escapes HTML entities in code samples, which saves me a ton of < > crap that makes things unreadable on my end.


Full page caching (assuming I’m ever popular enough to need such a thing, heh.) Along with this, there are full sets of cache headers sent, so that subsequent requests only happen if needed.

Layout, templates

HTML5 & CSS3 for everything UI related. This was one of the easiest parts. I have to thank my colleague, Paul Irish for creating the HTML5 Boilerplate. He made it drop dead easy to start a new set of UI templates. He saved me hours. If you’re not using the boilerplate, you should be.

Along with the HTML5 came a new site layout and design, which appeals to my minimalist tastes. Everything scales much better now, with percentage sizes used everywhere with the exception of the fixed width center column.


You’ll always see the same font, because I used the Google Fonts API to ensure everyone gets Droid Sans and Droid Mono. It’s nice to know that everyone will now see the same fonts, which I think is really the first time this has been able to happen on the web.

Content license

I relicensed my content from all rights reserved to Creative Commons Attribution-ShareAlike 3.0 Unported License which is an effort on my part to ensure people realize the stuff I post here is for common use.

Files and images

File uploads suck. I wasn’t really willing to deal with image uploads, while concurrently editing an article. Instead, I’ve decided to just use a Picasa Web Album for photo uploads. This is actually spectacular for one little known reason: thumbnail generation. See, when you click Link to this photo from an image in Picasa, you can get an embed code that looks like this:

<a href="">
  <img src="" height="144" width="101" />

But in the img tag, notice the s144 in the URL. If you modify that 144, you actually change the width of the generated image on the fly. This allows you to have instant, dynamically sized thumbnails for your needs. That’s not a documented feature or guaranteed to stick around, but it’s really useful.


Migrating my old posts out of Typo was kind of a pain. I had posts in mixed formats (Textile, Markdown, raw HTML.) I had to rewrite some things, but everything is Markdown now. Also, I use DreamHost, and setting up a Python application on Passenger is a pretty poor experience. There was a 500 in my application, but it took me an hour to find it, because if your application dies, there’s no simple way to get a stack trace out of Passenger. Things seem to be fine now, but if something goes wrong I’ll have a hell of a time figuring out what’s going on.

Django also needs to fix their interface surrounding get_absolute_url() in models. Seriously. The URL that you must return from that method is not absolute, meaning you’re left to add the scheme and hostname yourself to all of your URLs. That leads to another problem with very poor Django sites integration, it’s just a huge mess. Luckily, long ago, I wrote a Django snippet that I think solves this problem quite elegantly. I’d forgotten about it, until I ran into this exact problem again.


If you’re interested in the source code, let me know. I’m debating whether or not to release the code for this, simply because I don’t want to add to the graveyard of dead blog code bodies in the world. Plus, the application here isn’t as advanced. I’ve pushed Django to its limits and extended it before to serve high traffic media sites, and by no means is this blog nearly as advanced.

Published in Uncategorized