Rebuilding and Moving Old WordPress Posts to Jekyll

Earlier this week I did a major revamp of It started with redesigning my page templates to include a sidebar, then it morphed into making a long-standing goal of mine reality: Reviving the posts from my old 2008-2012 WordPress blog and getting them into Jekyll.

The Redesign

The redesign started as a seed in my mind when I visited a few months ago. I loved the look of the sidebar with the social links. What I didn’t love about it was the way the menu works and how the sidebar is sticky. I noticed the site is also built on Jekyll, so I briefly considered installing the theme, but I decided against it after about 30 seconds. I wrote most of my current theme myself and don’t want to mess up my TIL and Book Notes templates. So I took an afternoon and rewrote some of my templates to include a sidebar.

The trickiest part was figuring out what I wanted to do with the sidebar on smaller screen sizes. I decided to push it up to the top on pages, show the social buttons on the Home and About pages, and then hide it altogether on posts.

The other main issue was what to do with featured images. My templates were built to include featured images on posts before, but this time I decided to make them optional. The home page and archive pages don’t display featured images, but the category pages do.

Migrating my Microblog to Jekyll

Last year I started a Microblog, built a custom theme for it, and posted there 116 times over a few months.

I found it confusing to have multiple places to store content, so I decided to consolidate. I’m keeping separate, but I’m killed and moved all the posts here. This was originally on WordPress, so it a small test case for whether or not it would be possible to resurrect my old 2008-2012 blog and migrate the posts to Jekyll.

There is an official jekyll-import gem that supports WordPress, so I figured that this was going to be a piece of cake. That is, until I tried to install the gem. An hour later and 5 dependencies deep down the debugging rabbit hole, I finally gave up. Cryptic error messages somewhere around the mysql2 dependency finally made me throw in the towel and go to bed.

I woke up the next morning with a renewed sense of confidence and started searching. I came across this WordPress to Jekyll exporter, which worked phenomenally well. It dumped all of my posts out as .md files with the WordPress metadata translated into YAML front matter.

I was a little worried about what to do with all of the image links, but then I realized that all uploaded images in WordPress are stored at /wp-content/uploads/year/month/filename.jpg. If I add that /wp-content/uploads/ directory to Jekyll wholesale and replace all instances of with, all images in posts will work! So I pulled the directory down off my server, dusted off my grep skills, and everything worked as intended. Success.

The only other hiccup was that about half of my posts on the microblog didn’t have titles. That is part of the whole microblog philosophy. Those posts showed up in my main feed with just ID numbers, which looks strange. I solved that by adding hidden: true to the posts to hide them from the Jekyll paginator. Win number 2 for the old grep skills.

Resurrecting CAGblog

After my success with copying over my microblog posts, I decided to kick the difficulty up a notch and see if I could move over 500 posts from my old 2008-2012 site, which I affectionately called CAGblog. I was eager to get this stuff back online because 2008 is when I first started blogging, and I wanted my internet cred back. I know some of my stuff from when I was 18 is pretty cringeworthy, but having my old stuff up for posterity really matters to me.

Here is one of the few screenshots I have of it, from 2008:


Before I shut the blog down in 2013 and put up a landing page in its place, I made a backup and promptly forgot where I stored it. After hours of searching old hard drives, I finally found it on It hadn’t synced to my local machine because I had selective sync turned on. I almost panicked earlier because I thought I had lost all my old stuff. Thank goodness for Dropbox!

The first step in the revival was to restore my old database to a working WordPress site so that I could install the Jekyll exporter plugin. I only really needed the posts, not a complete working site, so I ignored all my old post templates and stuff. The database was from an early version 3 of WordPress, so I was concerned that it wouldn’t work on my Homestead dev environment and I’d have to go hunt down an old WordPress install somewhere. Thankfully WordPress has a bunch of update routines in place to handle just this kind of thing, so after going through a few “You need to update this database” prompts, I was able to log in to the wp-admin area and access all my old posts.

Just like on, the WordPress to Jekyll exporter worked exactly as intended. Now the fun began: I had a ton of old categories and tags I didn’t want to use, old images I needed to find and get linked up, and old links that needed to be rewritten.

Categories and Tags

For categories and tags, I simply edited the yaml metadata on the old posts and changed the keys to oldcategories and oldtags so that Jekyll wouldn’t parse them as normal. Grep win number 3.

For old images, I used the same method as on my microblog: I moved the wp-content/uploads/ folder to the root of my Jekyll site. That took care of about 50% of the broken images. The rest were scattered around other folders, so I searched for broken images, looked at where they were, and moved over every folder I could find. There are a few casualties, namely images that I didn’t host myself, but the vast majority are back up and running. I was a n00b 10 years ago and just threw stuff in my main directory, so now I have a bunch of old stuff cluttering up my previously pristine main Jekyll folder. Perhaps one day I will move all that to more logical folder structure and write redirects, but for now it is all staying where it is.

The links aren’t easy to preserve on a static site because I used the default post ID permalinks on my WordPress site. Those are the ones that look like I used the permalink key in Jekyll to set the permalink to /blog/[oldid].html. (Another win for grep. Man, regex is useful.) Then I followed this post to do some apache magic, fetch the ID from its query string, and redirect it to its new home. Now all of my old post links redirect to their new home on my Jekyll site! I clicked a few old ones from Facebook just to make sure.

When I moved to Cloudflare, my site search broke. With all of this old content back on my site, I knew I needed to get search working so the posts are findable, so I took a look at it again. The issue was that I had been submitting the form action to the same page. The query string didn’t get preserved with all the redirects/rewrites I’m doing/Cloudfront does, so I edited the submit function to just kick off the JS search function with the query directly instead of submitting/refreshing the page. Go run some searches and dig through my archives!

One response to “Rebuilding and Moving Old WordPress Posts to Jekyll”

  1. I set up this blog on WordPress in 2008. In 2015 I moved it to Jekyll and back filled those old posts in 2018. Now I’m back on WordPress with the entire archive. Why? I want to post more and WordPress is more conducive to that.

    With Jekyll I had to create a new markdown file with all of the yaml front matter I wanted and my automated templates were never quite right, then I had to get the Jekyll site running to preview the post (running the inevitable Jekyll and gem upgrades and troubleshooting issues with some plugin that broke), then run the custom build process I made to commit the changes, push them to Github, build the site, then deploy the changes to S3 and Cloudfront with s3_website, which is no longer being maintained. It was “rickety as hell” as an old family saying goes.

    With WordPress, Pressable keeps core up to date for me, so I just open the site, write the post, and click publish. No messing around with build tools, no finicky yaml templates, and no annoying Ruby and Java dependencies to fight with.

    Also, with WordPress, basic things like Search and Category Archives are available by default instead of something you need to hack on. The Plugin ecosystem is much better, too.

    The Jekyll site build and all the tools I built around it was a fun project, but I’m glad to be back on WordPress. I recently started working at Automattic, which of course played a role in my decision to switch back, but I had planned to make the switch long before I had applied.

    The speed of the 100% static Jekyll site served via Cloudfront was slightly faster than this WordPress site, but the difference isn’t big enough to matter to me. The Pressable CDN and object caching is pretty dang fast, and as I said above, I care more about being able to update the site faster and easier than I could with Jekyll.

    Getting started

    I had big ambitions for this project: I wanted to build a new theme from scratch adhering to the WordPress-Extra ruleset for PHPCS and the starter theme my team uses. I kept putting it off, preferring to be offline when not working. I was itching to get my site migrated, so I decided to modify an existing theme with a child theme and focus my energy on the migration.


    I essentially combined three sites into one.

    Old WordPress posts: I’m a digital hoarder, so I still have the database for my 2008 WordPress site. I loaded it up in a local instance, ran some upgrades so it would work with WordPress 5.5, and then used the typical WordPress WXR files to import them to the new site. I temporarily put my old /wp-content/uploads/ folder on the server hosting so that the import would also pull in the featured images.Microblog posts: was still live and I keep WordPress up to date thereJekyll posts: I heavily customized my Jekyll RSS feed to include all kinds of extra metadata that it normally wouldn’t. I then used the excellent WP All Import Pro to parse the XML and map it to WordPress fields and download and import the media. Attempting to do this and getting stuck? Shoot me an email and I’ll do what I can to help!Reading list

    I built out a cool reading list feature in Jekyll using yaml data files and a template that grouped the books I read by year and displayed the count. I was able to rebuild it pretty quickly with a custom post type, custom fields, and two queries: One to group the books by year and sort by date read, and the other to display the counts.

    Check out the reading page, my favorite page on the site!


    I thought I’d have a big issue with redirects, but with some careful planning about 95% of old links just work.

    By going back to the old databases from existing WordPress sites, I was able to use existing post IDs, which is great because my old links used the post ID permalink structure. Post ID permalinks redirect to the post by default, even if you have a different permalink structure.

    For the Jekyll posts, I was able to match the permalink structure I had on the Jekyll site, category/year/month/day/slug, so those work, too. The only issue I ran into is that I had some uncategorized posts in Jekyll and Jekyll leaves uncategorized out of the permalink while WordPress doesn’t. So I installed the Redirection plugin to add some redirects for those and monitor 404s.

    Ongoing issues

    I do have a few issues left to clean up:

    Code blocks with the Rouge syntax highlighter I used in Jekyll are a bit garbled. They need some styling to make them pretty again.JavaScript embeds in posts don’t work. I had a bunch of d3.js tutorials with interactive examples that don’t work right now. As a stop-gap I’ve linked to the old Jekyll version that is still accessible on S3, but I need to go through and fix those. I plan to eventually build out my own theme from scratch and I want to build some of my own custom blocks for a few ideas I have.

    But first, back to regular blogging.
    Like this:Like Loading…

Leave a Reply

Your email address will not be published. Required fields are marked *

%d bloggers like this: