Marco's Blog

All content personal opinions or work.
en eo

Moving on again: Joomla to WordPress to Hugo

2023-11-09 6 min read Site marco

It’s that time of the century again: I need to move on from one platform to another and carry (almost) all the content with me. This time, the move was not necessary and I could have continued working with WordPress. But updating the software every few days added up in time, the concern that eventually I’d be caught by a WordPress flaw that allowed remote execution, and ultimate takeover of the server, and the resources required to run PHP and MySQL were all too much.

So I decided to take the plunge and move to a static site generator. I didn’t think much of them for the longest time, but then I realized that the content on here is not all that interactive and that I can add comments more easily with an external provider than having to update spam filters all the time.

Which Static Site Generator Did I Pick and Why?

Static site generators are So Hot Right Now, and pretty much every environment has one. The most famous one might be Jekyll at the time, but the competition is catching up in popularity and feature set. Of the currently available SSGs, I evaluated:

  • Jekyll: full-featured, a devoted fan base, lots of themes and plugins, written in Ruby
  • Hugo: closely aligned with Jekyll, written in Go
  • Pelican: smaller user base, but leading SSG in Python
  • Astro: very modern-looking themes, written in JavaScript
  • Eleventy: very popular, with lots of different themes, also JavaScript
  • Vuepress: not very popular, themes are not that great, but tailored towards the JS/Vue combination

There is no one good answer for which SSG is the best, because all the technology does is spit out a lot of HTML/CSS/JS. The main technological difference seems to be speed, but the real difference to a user is the theming available, which can change at any time.

After looking at all available templates, it was clear that only Jekyll, Hugo, Astro, and Eleventy stood the Test of Pretty. I wanted to make do with Pelican, but there wasn’t a single theme that didn’t look like it was born in 2004. Vuepress was another one I wanted to like, because I simply love the Vue framework, but the same problem was manifest here.

Very personally, I am not too fond of the Ruby and JavaScript ecosystems. Ruby was poised to take over the world, but then lost favor. While Jekyll is doing really well and there is no issue with using it, I didn’t want to invest the time.

On the other hand, JavaScript frameworks have consistently burned me in the past with dependency nightmares. They require so many packages that the NPM installer kindly tells you how many of them are unsafe. I would absolutely not make too much of this opinion, it’s really just witchy-crafty-feely and you should use all the JavaScript you feel comfortable with. But I had other options, so I took them.

I ended up with Hugo because of a variety of reasons. The first one is that Hugo is a standalone, like so many Go applications. You download a single executable file and off you go, you can run Hugo. So there are no dependencies and no downloads other than the single file. The second one is that Hugo has lots of beautiful and mature themes. Not only that: you can easily swap a theme for a new one by simply plopping the new one into the themes directory and running Hugo with the --theme option. Hugo is also fast, rebuilding my entire site with almost 1000 articles and tens of thousands of pictures in about 20 seconds on my machine.

Perfectly Happy with Hugo?

Not really. I wish Hugo did a lot more than it does, natively. There are awesome add-ons and plugins, but they each do things differently and there is just no great consistency among them. For instance, a theme might require the tag image: in the front matter, while another one prefers featuredImage:. The inconsistency is slightly annoying, as it affects the front matter of each article. If you want to swap two themes, you have to change each file.

Front Matter? Files?

Unlike traditional blog software, that stores virtually everything in a database, SSGs do not even use a database. A series of input sources are translated into a set of HTML/CSS/JS files. Usually, the sources are some kind of Markdown document, but they can also be other types.

Usually, in addition to the regular text in markdown format, these files have some extra sauce. They are usually placed in special directories, and are usually named something meaningful. Also, the first section of the document (usually) is devoted to front matter, which is metadata used by the engine/theme to determine where and what and how to show the post.

For instance, your post will usually have a title. This is handled in front matter by writing something like: title: This is the title of my post. You can usually add a date (for sorting purposes), an author (here always me), categories and tags, etc. If you pick a theme that knows how to display all of this, it will show up.

Problems? Issues?

I will not lie, the setup was less than straightforward. To go from WordPress to Hugo, there is a plugin (that didn’t work for me). You can also go the circuitous route and go from WordPress to Jekyll, and then use the Jekyll to Hugo converter. That worked for me and made me think that maybe Jekyll would have been a better choice.

So I generated an export of the WordPress site and imported/converted into Jekyll. That turned a bunch of posts and articles into markdown files, each placed into the appropriate directory. Then I could simply generate the site and look at the posts.

Obviously, the translation was not entirely perfect. In particular, there were Unicode entities that I had to translate. That was handled easily enough with search and replace. Then I had to translate the galleries, which I had already moved from Joomla’s better galleries to WordPress’s pretty slim selection. I created a script that generated galley files for the new Markdown environment.

Finally, I had to change the front matter. I didn’t care about site continuity, since I haven’t had much traffic lately and a re-index might be in order. But the new site was fixated on keeping the same URLs, and I didn’t want that. So I simple got rid of UID, ID, and URL front matters.

I went through most of the newer articles to ensure the content was still alright, and finally moved two series of articles on snowboarding trips into their own section, so that you don’t have to look at each article in the series as if it’s a standalone thing in the blog.


The entire process took about four days of fairly consistent coding and typing. A lot of it came from getting used to the environment and theme, but I know added multilingual functionality to the site that is actually pretty easy to use.

The evaluation of different SSGs happened earlier and took a lot longer. But I won’t count it here as it was done for a different project.