Migrating Blogs (Again) from Pelican to Hugo

6 min read · Posted on: May 2, 2017 · Print this page

Our universe is in a continuous cycle of creation and destruction. How can this humble site escape that cosmic dance? It is time to change the blogging platform of arunrocks.com again.

You might remember my earlier lengthy justification of using Pelican. I have done numerous hacks and plugins to twist and bend it to my liking. While it has served me well for the past four years, it is time to move on.

The reason, of course, is a much better static site generator - Hugo. A fairly young but very actively developed project, Hugo has some extremely compelling set of qualities, which made the choice to migrate my site fairly obvious. Some of them are:

  1. Content Organization: Hugo believes in the philosophy that your content should be arranged in the same way they are intended for the rendered website. This brings tremendous clarity in identifying file locations and reduces the need for hacks.

    By default, some blogging engines (including Pelican) assume that all your “pages” will be finally rendered into the pages folder. A configuration setting can change it to use any URL scheme. But why doesn’t it leave it where it was? The source structure is nested and organized. Why flatten it and lose that information?

  2. Extremely Fast: Even if your site contains hundreds of files, the build time is usually under a second, without cached compilation,… inside a virtual machine, … without an SSD. Yes, it is unbelievable.

    This makes the edit-preview development cycle a pleasure to use. Tweak an SCSS variable and the browser will live reload almost instantaneously. I make a hundred tweaks after a page gets rendered, so a short feedback loop is ideal for my workflow.

  3. No Stack: This is usually marketed as the “single executable” advantage of Go applications. But it matters much more profoundly in the case of Hugo.

    Many new languages like Javascript and Python need a pile of third party libraries to make their tools run (even if they are “batteries included”). While it might be easy to setup initially with a single command like pip install Foo, future invocations might need you to update everything to their latest versions first and then fixing whatever breaks.

    Slacking Off T shirt

    Even though dynamic languages do not require a lengthy compilation step, a constant stream of updates can get tiring. “Updating my packages”" has become the new “I am compiling”.

    Ok, end of my rant. Hugo is a single self contained executable (in all platforms). This not only reduces the number of moving pieces that you need to keep track of (my requirements.txt for the site listed 20 packages), it simplifies the ongoing maintenance of your site.

    I would rather not have the headache of managing code environments just for writing a blog. In Arch Linux, where I develop my site, it is even easier considering it is a rolling distribution. Hugo automatically updates along with the rest of the system. The updates are usually backward compatible and nothing breaks.

  4. Actively Developed: Many static blog generator projects have this problem. The early days would have the community engaged and actively involved. Then the interest dwindles, code gets stale and the backlog of issues grows. Hugo is still in its early days and has a energetic community. Hopefully the interest will continue to grow.

  5. Not too Blog-oriented: My site, like most personal sites, is predominantly a blog. But it is not just a blog, it is a full-fledged site. Hugo has very minimal assumptions about what kind of site you have. For instance, I can convert a JSON file with all my talks into a Talks page. I just need to define a template for a new type of page in my layouts.

It is not all Peaches and Cream

Hugo does have some rough edges. But considering the rate of its development, you might find that all these problems have been solved by the time you read it. But, for the record, I did come across these issues:

  1. Lack of Static Assets Pipeline: I use SCSS to create my CSS files. In general, Hugo is unaware of any static assets pipeline which may involve compiling SCSS, minification or compression. I use a Makefile which invokes the compiler as a dependency for build. Sometimes I need to stop live reloading and explicitly call Make. Since everything is fast, it doesn’t matter much.

    Wasabi restaurant at Tysons Corner Center in McLean, Virginia taken by Ben Schumin

  2. Menu Generation Flaky: I found the “active section in menu” pattern used in most website menus a bit hard to implement. There are others who have faced similar issues. I resorted to not using this pattern for now.

  3. Outdated Blog posts Hugo documentation is extensive and covers a lot of material. But good documentation is very hard to get right. Some sections are confusing and I often look for better explanations say from blogs.

    But one needs to watch out for outdated content. For instance, I needed to change my RSS feed location and one blog recommended changing RSSUri in the config file. This is deprecated. Now, you need to use output formats say like this:

    outputFormats.RSS:
      BaseName: "index"
      Path: "feed/index.xml"
    
  4. Python Tooling: While using Pelican, I was happy that if I needed any additional functionality, I could always write a plugin in Python. This doesn’t worry me for two reasons. First, Hugo’s template system is very expressive and handles many of such needs. Second, ShortCodes offer a much cleaner alternative to plugins.

  5. Inconsistent Casing Sometimes a variable is mentioned in title case in one place and lower case in another. I would end up wondering whether it is copyright or Copyright or CopyRight. Probably, there is a naming convention. But I haven’t found it yet.

As you can see, most of these issues are solvable. Hugo is a long way from version 1.0 (currently we have v20.7). So this might all be fixed by then.

Changing a Jet Engine Mid-flight

Once your site achieves a certain amount of traffic, then making any change is fraught with risk. Every time I change this site’s underlying platform I make a short TODO list. It looks something like this:

  • Setup Redirects: Map the old link structure to the new ones
  • Fix Renders: Markdown is not quite a standard. Each Markdown engine has its own quirk. I manually check the rendered HTML is some cases.
  • Check Missing Images: Things have to move around to adjust for various source layouts. So images, scripts or download links can return 404s.

Even after all these checks, I still need to watch the error log for omissions. As this happens in my spare time, the whole migration “project” takes months. It is pretty much like changing a jet’s engine mid-flight.

Some Takeaways

In short, I would say you can never underestimate the sheer amount of work involved in migrating a site. There is a very good post on site migration by folks at Mozilla that covers many aspects that people tend to miss. Unless you have very good reasons to move, I would suggest that you stick with your blogging platform of choice.

As for me, time to start thinking about migration to HTTPS 😉


Arun Ravindran profile pic

Arun Ravindran

Arun is the author of "Django Design Patterns and Best Practices". Works as a Product Manager at Google. Avid open source enthusiast. Keen on Python. Loves to help people learn technology. Find out more about Arun on the about page.

Don't miss any future posts!

Comments →

Next: ▶   A Gentle Introduction to Creating a Minimal Hugo Site

Prev: ◀   Hangman in more than three lines of Python

Up: ▲   Blog

Featured Posts

Frequent Tags

banner ad for Django book

Comments

powered by Disqus