I just finished the last bits of migration for this site. It involved moving my podcasts from the podcast.sysca.st
domain to a dedicated overview on this site.
In this post, I’ve documented all the steps I took to migrate from that WordPress system to this installation of Hugo.
Installation of Hugo
You’ll need to install Hugo first. Their docs cover that pretty well.
The hugo
binary is what will generate the static HTML from the markdown & template files we will use later on.
Export your WordPress data to a Hugo format
Hugo uses markdown files to store its content. Everything is in flat files.
First, install the SchumacherFM/wordpress-to-hugo-exporter plugin. It isn’t available in the search in WordPress itself, you’ll have to download & install it.
- In their git repo, download the plugin as a ZIP file
- Go to your WordPress,
Plugins > Add New
- Pick
Upload Plugin
and choose the ZIP file you just downloaded - Activate the plugin after installation
Once the plugin is installed, you can try to go to Tools > Export to Hugo
. That page might take a while to load.
If that works, you’ll be presented with a ZIP file that contains:
- All your posts & pages
- All your uploaded files (/wp-content/*)
However, it might fail. If your site is too large, the creation of that ZIP fails and you’ll have to try via CLI. SSH into your server to get started.
Note: if you can’t SSH, ask your host to do this for you.
$ cd wp-content/plugins/wordpress-to-hugo-exporter-master/
$ php hugo-export-cli.php
This is your file!
/tmp/wp-hugo.zip
This’ll take a while, too.
Now you have a ZIP file with all your site content (which serves as a pretty good backup).
$ ls -alh /tmp/wp-hugo.zip
294M Nov 9 07:25 /tmp/wp-hugo.zip
Now download and extract that to your local machine.
Exporting custom data types in WordPress
By default, the plugin above will export posts & pages. If you have custom post types, you’ll have to modify the export ever so slightly.
To do so, open and edit the file hugo-export.php
. Around line 100 you’ll find a query like this one:
<?php
return $wpdb->get_col("
SELECT ID FROM $wpdb->posts
WHERE post_status in (
'publish',
'draft',
'private'
)
AND post_type IN (
'post',
'page'
)
");
In my case, I had a custom post type for the podcasts. I changed the query to this:
<?php
return $wpdb->get_col("
SELECT ID FROM $wpdb->posts
WHERE post_status in (
'publish',
'draft',
'private'
)
AND post_type IN (
'post',
'page',
'podcast'
)
");
Run the export again and you’ll find all custom posts exported in the posts/
directory. More on that below.
Exploring the exported data
Once unzipped, you’ll find a directory structure like this.
config.yaml
posts/
\_ 2016-08-01-episode-1.md
\_ 2016-08-02-episode-2.md
\_ 2016-08-03-episode-3.md
preparing-guest-syscast/
\_ index.md
wp-content/
\_ uploads/
\_ 2017/
\_ 2018/
There’s a general config.yaml
with the meta data of your site (like title, description etc.) and an export of all the posts and pages you had.
Now that you have all data exported, you can begin using this in hugo.
Using your WordPress data in Hugo
Start by creating a new Hugo project.
$ hugo new site mysite
$ cd mysite
This’ll create a new hugo site with all the required directories. Now, copy your exported data into it.
$ cp -r /path/to/hugo-export/ content/
In other words: copy all the directories from the export into your content
directory in Hugo. The end result should look something like this.
$ ls -alh
archetypes/
content/
\_ posts/
\_ 2016-08-01-episode-1.md
\_ 2016-08-02-episode-2.md
\_ 2016-08-03-episode-3.md
\_ preparing-guest-syscast/
\_ index.md
\_ wp-content/
\_ uploads/
\_ 2017/
\_ 2018/
data/
layouts/
[...]
Now, for testing, apply a default theme to Hugo and watch it go.
$ git init
$ git submodule add https://github.com/budparr/gohugo-theme-ananke.git themes/ananke
$ echo 'theme = "ananke"' >> config.toml
$ hugo server -D
That last command will start a local Hugo server and you can browse to http://localhost:1313/
to view your site.
You’ve moved all data from WordPress to a local Hugo install. It’s up to you now to find or create a good theme. 😉