From Django to Hugo

I migrated my blog from a Django system I wrote 12 years ago, to a static site generated via Hugo.

The move wasn’t just about getting out of an old codebase — it also was the result of seeing how static generation is a very reasonable fit for most blog sites (including mine). Dynamically generating the pages is really just one way to get the raw content rendered into my preferred form and interface. Static generation does that too.

There’s literally nothing I can think of wanting to do with my blog that will be made impossible by using static generation. I really don’t need the ability to do arbitrary relational queries against my blog content.

After trying out many good-looking themes from I selected one called “Mainroad”. There were many others I liked the look of, but they lacked things I needed like pagination. (In retrospect, I realize I wanted a feature grid to compare themes.)

I wrote a Python script to convert the old blog database into Markdown files with the requisite metadata (title, timestamp, tags). Here’s the meat of it:

title = "{title}"
date = "{timestamp}"
tags = {tags}
aliases = {aliases}
    cursor.execute("SELECT * FROM posts")
    rows = cursor.fetchall()
    for row in rows:
        context = {'tags': get_tags(cursor, row), 'aliases': [row['id']]}
        context['title'] = context['title'].replace('"', r'\"')
        markdown = TEMPLATE.format(**context)
        output = open(os.path.join(args.mdpath, slug(row) + ".md"), "w")

Obviously the fact that my posts were already in Markdown increased the appeal of Hugo. Converting markup for 400+ posts would have hit more edge cases than I want to deal with.

I also had the happy experience of wishing for a feature and finding it in the docs. (That feature was the aliases frontmatter option. It lets me redirect requests for my old PK-based URLs, to the new slug-based URLs.)

I’m very impressed with Hugo.

  • It’s capable of a great deal, but also lets you ignore the stuff you’re not using (giving it the more focused and direct feel of a smaller tool)
  • It’s super-fast; combined with the auto-reloading of hugo server, this makes local development a breeze
  • A lot of nice web design work is being made available as Hugo themes

My only significant wish-list item thus far (and it’s pretty minor) is: I wish hugo deploy supported rsync by default, so that e.g. I could set an rsync_target parameter in my config.toml that would be automatically used by hugo deploy.

I’m using Hugo to generate my portfolio site now too.

Cats all over the internet are excited about it.