How to convert your WordPress blog to Hugo
I have recently converted this blog to Hugo. Reasons include not wanting to maintain a grossly outdated WordPress instance which could potentially harbour attackers trying to install Crypto miners on my server.
Here are the steps I had to take to export my posts to Hugo, and to fix my posts so they actually display correctly.
Step 1: Export WordPress content
Install the wordpress-to-hugo-exporter plugin onto your WordPress instance. You will then be able to export a ZIP file of your entire blog. The ZIP will look something like this:
# ls -ll hugo-export
total 36
drwxrwxr-x 2 nuke nuke 4096 Okt 24 16:58 about-me
-rwxrwxrwx 1 nuke nuke 150 Okt 24 17:01 config.yaml
drwxrwxr-x 2 nuke nuke 12288 Okt 24 16:58 posts
drwxr-xr-x 6 nuke nuke 4096 Okt 24 17:03 public
drwxrwxr-x 3 nuke nuke 4096 Okt 24 17:00 resources
drwxrwxr-x 3 nuke nuke 4096 Okt 24 17:01 themes
drwxrwxr-x 3 nuke nuke 4096 Okt 24 16:58 wp-content
Step 2: Install a theme
Your blog will not be able to function without a theme. In my case I installed the Ghostwriter theme.
mkdir themes
cd themes
git clone https://github.com/jbub/ghostwriter
To use the theme you have to set up some variables in your config.yml
file.
For reference copy the entire contents as specified in the Ghostwriter README.md
Adjust the variables so they match the configuration of your blog.
Additionally, you will have to move the posts
directory so the theme can find it:
mkdir content
mv posts content/post
If all worked, you should be able to run hugo server
and see a lists of your posts and be able to view them!
Step 3: Fix images
Create a static
folder and move your wp-content
folder there, so it can be served by Hugo.
make static
mv wp-content static
To make the theme display the featured image of your posts, the theme expects a image
key for each post.
But the export plugin exports the variable as featured_image
. So to fix that, change featured_image
to image
for each post.
cd content/post
for f in *.md; do sed -i 's/featured_image/image/g' $f; done
Also in my case, the actual image URLs in my posts were being proxied through WordPress, which means the image URLs were not relative. To fix that run:
cd content/post
for f in *.md; do sed -i 's/https:\/\/i0.wp.com\/blog.gian-sass.com\/blog//g' $f; done
for f in *.md; do sed -i 's/https:\/\/i1.wp.com\/blog.gian-sass.com\/blog//g' $f; done
for f in *.md; do sed -i 's/https:\/\/i2.wp.com\/blog.gian-sass.com\/blog//g' $f; done
for f in *.md; do sed -i 's/https:\/\/i3.wp.com\/blog.gian-sass.com\/blog//g' $f; done
for f in *.md; do sed -i 's/https:\/\/i4.wp.com\/blog.gian-sass.com\/blog//g' $f; done
Additionally you will have to allow unsafe HTML in your posts, because the plugin just happens to export images as native HTML and not as Markdown.
markup:
goldmark:
renderer:
unsafe: true
And voila, images should work now!