WordPress to Hugo
I originally moved to WordPress while I was actively working on PyMOTW because I wanted the ability to schedule posts in the future so I could write more than one article at a time. I was motivated to change this time because I want more flexibility when choosing a hosting provider and I want to simplify managing archives of content in a more neutral format. I have moved into and out of WordPress a few times now, and I think this time I’m going to stay with a static generator.
I took a quick look at Jekyll, Hyde, and one or two other static site generators, but settled on Hugo for a few reasons. I’ve never had a good experience installing a Ruby app or keeping it up to date. That’s probably just because I’m not really a Ruby developer, so I’m not familiar with the tools. I have plenty of experience managing dependencies for Python apps, but as I’ve been working a lot in Go lately I find the way it deals with dependencies much nicer. I don’t have to worry about keeping a virtualenv updated or resolving incompatibilities with newer versions of shared libraries. Hugo is also available through Homebrew, so installing it is trivial. It doesn’t hurt that Hugo is also incredibly fast.
Hugo uses Markdown as an input format, and while it is not as powerful as reStructuredText the partials feature and the advanced page metadata management possible with Hugo’s templates and build environment make it especially nice for building websites.
For now I’m sticking with Dreamhost to serve the content. I have a few sites hosted there, including https://pymotw.com, and the builds for some of them rely on hand-crafting content or tools that are now out of date, like python 2.7. I have the tools I need locally, and changing the build processes to move them to another hosting provider would be a lot of effort. Since I need a traditional hosting provider for those sites anyway, publishing Hugo’s output there as well makes sense. There are instructions for publishing to Netlify as well as other providers that specialize in static sites, so if I change my mind I can at least migrate my personal site relatively easily.
The one-click wordpress-to-hugo-exporter plugin for WordPress did a pretty good job of turning my HTML posts into Markdown and zipping them up for me to download. The default output organized the files in more or less the right directory structure to preserve existing URLs, but I decided I wasn’t very concerned with that so I renamed all of the files to remove the dates from the paths. I did have to clean up a lot of the output, but I blame the fact that I have previously used Blogger, Tinkerer, and a different WordPress instance, so the content was a bit of a mess to begin with.
As I was cleaning up all of the old posts, I realized that one of the
most common types is a release announcement for some package I have
been working on. I took advantage of Hugo’s support for cascading
page metadata and
templates to simplify the
process for creating those release announcements. I already had a
shell script for producing Markdown release notes from
git logs and
reno release notes. I updated it to generate minimal
input files for Hugo instead of pushing to WordPress with
wphelper. Most of the metadata for the
announcements is applied when Hugo builds the site, based on the
I use https://feedburner.google.com as a proxy for all of my RSS feeds, so after updating the site itself I reconfigured the feeds to find the original sources at the new locations. Because I rearranged all of the content, I was worried about the various consumers of the feed re-publishing everything. I configured Hugo to limit the number of items in each feed, but it seems that sites like https://planetpython.org and http://planet.openstack.org are smart enough about dealing with old posts that it doesn’t matter.
I haven’t bothered with configuring redirect rules, since I assume google will work out the changes. I’m sure that will cause a hit to my PageRank score for a while, but since I’m not changing https://pymotw.com I’m not that concerned.