From Wordpress To Eleventy With Ease
I recently converted this site from an old Wordpress to Eleventy. I then promised I’d share how I did it, because it really doesn’t have to be difficult. In fact, with the small node script to follow, you should have everything set up in about 5 minutes.
Step 1: Get the old Wordpress data
First you need to get your post content—and associated media—from Wordpress. Since I’ve obliterated the original Wordpress site now, I can’t retrace quite how I did this. I remember it being very straightforward. To get all of my Wordpress post data as JSON, I either used the core export functionality or a popular plugin. Or maybe the Wordpress REST API. If I could manage it, you shouldn’t have much trouble. To get all the images, I almost certainly used a plugin like this one.
In any case, you should end up with a JSON file full of stuff that looks something like this…
...
"post": {
"ID": 14,
"post_author": "1",
"post_date": "2014-08-01 00:00:09",
"post_date_gmt": "2014-08-01 00:00:09",
"post_content": "<p>Hi everybody! I've just done a lot of cocaine on the company expense account...",
"post_title": "Reinventing The Hyperlink",
...
… and a directory of media with subfolders named after years, like:
- 📂 2011
- 📂 2012
- 📂 2013
- 📂 2014
- etc.
You’ll want to unzip this exported media archive into wherever the rest of your Eleventy images go.
Step 2: JSON to markdown plus Front Matter
This is where you can use my simple node script. Here it is in its entirety, with notes to follow:
const transformAndWriteToFile = require('json-to-frontmatter-markdown').default;
const wordpressData = require(__dirname + '/wordpress.json');
const slugify = require('slugify');
const posts = wordpressData.post.posts;
Object.keys(posts).forEach((p, i) => {
let post = posts[p].post;
transformAndWriteToFile({
frontmatterMarkdown: {
frontmatter: [
{ title: post.post_title },
{ date: post.post_date.split(' ')[0] },
{ permalink: `article/${slugify(post.post_title).toLowerCase()}/index.html` }
],
body: post.post_content.replace(/http:\/\/www.heydonworks.com\/wp-content\/uploads/g, '/images')
},
path: './src/posts',
fileName: `${slugify(post.post_title).toLowerCase()}.md`
})
})
- Take a note of the
require
lines. You will have tonpm install
(or Yarn, whatever) thejson-to-frontmatter-markdown
andslugify
dependencies. Thewordpress.json
file is the JSON data I exported in Step 1: Get the old Wordpress data. - The
frontmatter
part takes the properties I’m interested in from each post and converts them to front matter values. The permalink structure I happen to use starts with/article
. By salvaging this structure from the original site, I could avoid doing rewrites/redirects. - The
body
part writes the post content but, critically, re-paths each of the images to use the local Eleventy URL - The
path
is where to write the file (presumably where all my non-legacy posts also reside) - Finally,
fileName
actually names the markdown file itself, slugifying thepost_title
value as my Wordpress site was instructed to do.
Step 3: Run the script
You can set up an npm script if you really must, but since I knew I’d only run this once, I just hit node wordpress.js
(where wordpress.js
is the name of the script file, and it’s in the root of the directory).
Step 4: There is no step 4
This step doesn’t even exist. But it's worth noting that, on my site, I split my old Wordpress posts between archive and best (my best posts) directories. Each article (including each new article) on my site has an article/slug-here
URL structure, but belongs to one of the latest, best, or archive collections.
In Eleventy, you can set the collection per-post by adding a tags
property to its front matter. But it’s less verbose to to add a data file to the appropriate directory instead. For example, my latest posts go in the /latest
directory, which contains a latest.json
file with the line "tags": "latest"
.
Not everyone is a fan of my writing. But if you found this article at all entertaining or edifying, I do accept tips. I also have a clothing line: