Even before the Wordpress community started to implode I was considering moving my site to a Static Site Generation (SSG) system.
Back when blogs were actually a thing, it was important to have things like comments, etc., on your site, but now most of the discussion about anything I post (if there is any discussion) happens on social media. Wordpress is overkill for what I need, and it also seems that quite frequently common Wordpress plugins are found to have security vulnerabilities. A static site would address most of these issues.
The question next would be “which SSG do I choose?”
I narrowed the choice down to three: Hugo, Jekyll and Eleventy.
Hugo is written in Go, Jekyll in Ruby and Eleventy is Javascript. I personally didn’t really care since the output would be static HTML. Eleventy was apparently inspired by Jekyll, so I decided to check out Jekyll first.
It didn’t go well.
I do most of my personal work on an aging iMac, and while I’m running MacOS Sequoia I could not get Jekyll to install. Hugo, however, is available in Homebrew, and so it was dead simple.
In fact, all you really need to get a Hugo site up and running in minutes is to choose a theme. I ended up going with Hyde, as it closely matched the Wordpress Hum theme I was using on tarus.io.
Once I had that choice made, I simply followed these steps:
brew install hugo
hugo new site quickstart
cd quickstart/themes
git clone https://github.com/spf13/hyde.git
cd ..
echo "theme = 'hyde'" >> hugo.toml
hugo server
That was it. The “server” command will output a URL to a port on localhost. Visit that URL with a browser and you will see a realtime view of your website.
Now a concept that took me a little bit to understand was the directory structure. There is a directory called “content” where you put all of your markdown files, and as those files are updated Hugo will create HTML versions in the “public” directory. Sync the files in “public” to your webroot and, voilà you have a web site.
I started off by customizing the theme sidebar. All the files for a particular theme are in the themes\[theme name]
directory, so it was pretty easy to edit the css to approach the look of my old Wordpress site.
The next step was to migrate my Wordpress posts and pages to Hugo. I decided to follow the instructions and use the wordpress-to-hugo-exporter.
On that Github page simply save the repo as a .zip file and then you can manually upload it as a plugin to your Wordpress instance. If you are on a Mac like I am the system tends to automatically unzip .zip files, so use something like:
wget https://github.com/SchumacherFM/wordpress-to-hugo-exporter/archive/refs/heads/master.zip
(and you can brew install wget
if you don’t have it).
Once installed, you will have a new menu item under “Tools”
Executing that plugin will create a .zip file with your posts converted to markdown. Copy the contents of that .zip file into your [site]/content/
directory and you should see your posts show up at the Hugo URL that was generated when you ran hugo server
. Note that the server is dynamic, so as you add files to the “content” directory it will automatically update, no need to restart.
Now the real work began. I started with the tarus.io site because it had only about 85 posts. Even with the exporter most of them needed a bit of work. When the exporter hit something it couldn’t deal with, namely images, it just left in the native HTML. Well, Hugo won’t, by default, display HTML.
Rather than go through and manually convert the “img” tags to markdown, I found out that you can add “shortcodes” to Hugo.
One was called “rawhtml”.
Basically, you create a directory under your site directory called layouts/shortcodes
and in that directory create a file called rawhtml.html
with the content:
<!-- raw html -->
{{.Inner}}
Then you can use the shortcode {{< rawhtml >}}
at the line before we want to use html and {{< /rawhtml >}}
at the end of the block. I just put those around the “img” tags in the exported markdown and my posts started displaying images correctly.
I’m lazy, so hand editing all of these files was getting a bit monotonous so I figured I needed some sort of script.
Now usually I would just message my friend Ben who would create one for me, but now we live in the world of GenAI, so could I get GenAI to do it?
I hopped onto Amazon Bedrock and brought up an Anthropic model, and low and behold it spit out a very useful script.
#!/bin/bash
# Check if a filename was provided
if [ $# -eq 0 ]; then
echo "Please provide a filename as an argument."
exit 1
fi
# Store the filename
filename="$1"
# Check if the file exists
if [ ! -f "$filename" ]; then
echo "File not found: $filename"
exit 1
fi
# Process the file and save to a temporary file
temp_file=$(mktemp)
awk '
BEGIN { in_img = 0 }
{
if ($0 ~ /^<img/) {
if (!in_img) {
print "
"
in_img = 1
}
print $0
} else {
if (in_img) {
print "
"
in_img = 0
}
print $0
}
}
END {
if (in_img) {
print "{{< /rawhtml >}}"
}
}' "$filename" > "$temp_file"
# Replace the original file with the processed content
mv "$temp_file" "$filename"
echo "File processed successfully: $filename"
This script will look at the file you include as an argument and find any line that starts with “<img”. It will then add the shortcode before and after that line. That fixed the majority of the issues I had with images not displaying correctly.
The final little nitpick was that markdown in titles was not being converted. I went into the theme directory and did a search on all instances of “.Title” and replaced it with “.Title | markdownify” and that issue was corrected.
I’m pretty happy with the site, especially considering the amount of time I put into it.
There are a couple of other things I need to do, but it works for now. I need to add an RSS feed, and I used to have a page called “planet” where I combined all of the RSS feeds of my various blogs on to one page.
Since there is no active code on the new blog I also need to add a Search function, which in Hugo-land seems to be done by having the site indexed by Google and then just using Google search.
Oh, and to create this post I installed, via Homebrew, the MacDown application. MacDown is a markdown editor and it gives me back some of the UI functionality I used to get with Wordpress.
Once I let this simmer for a bit I plan to migrate all of my other sites to Hugo. Just seems to be more secure and with a lot less drama than Wordpress.
UPDATE: I did run into one problem when I used rsync to copy the “/public” directory to my webroot. The URLs for the css files were still showing “localhost” which meant it worked on my home machine but not when served from my server.
Starting Hugo with:
hugo server -D --baseURL=https://tarus.io --appendPort=false
caused it to properly render the pages.