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.