Categories
Uncategorized

Migrated Jekyll to WordPress with Ruby and API

A few years ago I migrated this blog from WordPress to Jekyll, and now I’ve migrated it back again. I want to be able to quickly post notes to this my notetaking site, and I’ve been using WordPress more lately.

How did I migrate Jekyll to WordPress? I made a Jekyll liquid template to make the API bodies and a Ruby script to insert them into the WordPress API.

WordPress API Authentication

First I tried copying the cookies from Chrome dev console and the nonce from the page source for API authentication, but I couldn’t get that to work.

So I installed the basic auth plugin (from WP-API GitHub) and activated it, and then I could use a simple username and password for my WordPress API calls.

After the import was complete and all the new posts were working, I deactivated the basic auth plugin for security.

Jekyll Template for WordPress API Post Creation

Since Jekyll is in Ruby, I just used Ruby for the API calls. I also made this export template to make the post bodies. You may want to change the author ID and/or change the statuses or format as desired. This leaves comments and pingbacks disabled and publishes the post as author ID 1 with the standard format. I named this export.json .

---
layout: null
sitemap: false
---
{
    "posts": [
    {% for post in site.posts %}
        {
            "date_gmt": {{ post.date | jsonify }},
            "slug": {{ post.url | jsonify }},
            "status": "publish",
            "title": {{ post.title | jsonify }},
            "content": {{ post.content | jsonify }},
            "author": 1,
            "comment_status": "closed",
            "ping_status": "closed",
            "format": "standard"
        },
    {% endfor %}
    ]
}

I then built the site with bundle exec jekyll build. Then I edited the output json file in _site/ to remove the last comma in the file to make it valid json.

Ruby Script to Upload to WordPress API

I made the following Ruby script to read the _site/export.json file and upload to the API. Ensure to put the password in the environment variable SECRET and then export SECRET if in Linux/Mac. Also edit the script for user_name, protocol, site, and json filename

#!/usr/bin/ruby

require 'net/http'
require 'json'
require 'time'

user_name = "jim"
password = ENV['SECRET']
login_cookie = ""
wp_nonce = ""

protocol = "https"
site = "www.thejimnelson.com"
api_path = "/wp-json/wp/v2"

init_header = {
    # 'X-WP-Nonce' => wp_nonce,
    # "Cookie" => login_cookie,
    'Content-Type' => 'application/json',
}

uri = URI("#{protocol}://#{site}#{api_path}/posts")

http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true

json_text = File.read("_site/export.json")
posts = JSON.parse(json_text)

req = Net::HTTP::Post.new(uri, initheader = init_header)
req.basic_auth user_name, password

posts["posts"]
    .each do |post|
        # Ensure date is in ISO8601 format
        post["date_gmt"] = DateTime.parse(post["date_gmt"]).iso8601
        req.body = post.to_json
        result = http.request(req)
        puts result.body
    end

Migrating Jekyll Pages to WordPress Manually

The above scripts only migrate the posts. It should be possible to modify them to handle pages, too, but I only had two pages and just created each manually and copy-pasted the content from the Jekyll-built pages into the WordPress new page editor.

By Jim Nelson

Hi, I’m Jim. I’ve owned computers since 1979 and have been an IT professional since 1994. I've been running my own public web servers since 2005.

This site is intended to provide useful, practical answers to challenges you have.