Migrate From Ikiwiki to Hugo

I recently decided to migrate this blog from IkiWiki to Hugo. I was expecting an ardous ordeal, but the entire task turned out to be fairly short painless.

I’ve been somewhat disillusioned with posting to my (ikiwiki) blog lately:

  • It looks like web 1.0 (not that that is bad, but I’d like it to be snazzier)
  • Google told me it’s demoting my site due to being mobile-hostile
  • It’s using tools I don’t completely understand anymore (or really did in the first place)
  • One of the git hooks wasn’t working somewhere

As if to emphasize my procrastination in fixing those issues, I’ve actually written five blog posts since the last one I published over a year ago. I’ll be re-editing those for posting shortly.

Ultimately, I looked around and decided my needs would be better served by switching to Hugo.

  • Much easier theme support
  • Documentation is decent
  • While it fills a similar niche (markdown to static site generator), the tools are more comprehensible
  • Mainly, Less dependent on git internals
  • Live-view mode with a local server, so I can preview posts before I publish them.

Additionally, there are a few other things I plan to support in the future:

  • Integration with gitlab’s CI infrastructure to auto-build pages when commits are pushed
  • Hosting on gitlab pages

Now, could I have hunkered down and figured out how to get ikiwiki working again? Sure. I could eventually get it to look pretty, too.

However, I managed to migrate my entire site (which admittedly is only about ~50 posts) to Hugo in about 3 hours. Additionally, I was able to preserve all original permaurls for the articles. This was simplified by both supporting the same hierarchy I was using ("/posts/filename/").

As both engines use the same markdown syntax, the actual migration of the posts was very minimally invasive, dealing mainly with the post metadata and inline images.

I used the following script to perform the bulk convert:


for mdwn in *mdwn
    echo "Converting $mdwn"
    base=$(basename $mdwn .mdwn)

    # Get the title, date, and tags in the new formats
    title=$(grep '\[\[\!meta title' $mdwn | sed -e 's/\[\[!meta title=\(.*\)\]\]/title: \1/;')
    date=$(grep '\[\[\!meta date' $mdwn | sed -e 's/\[\[!meta date=\(.*\)\]\]/date: \1/;')
    tags=$(grep '\[\[\!tag' $mdwn | sed -e 's/\[\[!tag \(.*\)\]\]/\1/; s/ /", "/g; s/^/tags: ["/; s/$/"]/')

    # If tags are blank, mark them as "untagged".
    if [[ -z "$tags" ]]; then
        tags='tags: ["untagged"]'

    # Insert the new tags into the new .md files
    echo -e "---\n$title\n$date\n$tags\n---" > $md

    # Strip the old tags from the mdwn sources, adding the result to the md files
    # Also rewrite images while we're at it.
    sed -e "/^\[\[!meta title.*$/d" \
        -e "/^\[\[!meta date.*$/d" \
        -e "/^\[\[!meta guid.*$/d" \
        -e "/^\[\[!tag.*$/d" \
        -e s'/\[\[\!img \+\(\S*\) .* alt=\(".*"\)]]/![\2](\1)/g' \
        $mdwn \
      >> $md