If you read my previous post on Jekyll, you already know why I switched from WordPress to Jekyll. In continuation of that post I want to explain how I migrated to Jekyll. For those who are not interested in the software side of things should skip this post. Wordpress offers a lot of features out of the box, like search engine and comments engine. So all I have to do is write posts and users can search and comment on them. This works because Wordpress is dynamic and runs a DB to store data. However since Jekyll is static, one needs to figure out a way to make things work.

Installing Jekyll

I followed the instructions on how to install Jekyll from their website. Well to be fair, I did not follow all the instructions exactly as mentioned. May be that was the reason I had some problems. Basically I use Manjaro Linux and I installed bundler and jekyll from the package manager.

When launching Jekyll I got this error

       Jekyll Feed: Generating feed for posts
  Liquid Exception: uninitialized constant Liquid::Expression::MethodLiteral in /usr/lib/ruby/gems/3.0.0/gems/minima-2.5.1/_layouts/default.html
bundler: failed to load command: jekyll (/usr/bin/jekyll)
/usr/lib/ruby/gems/3.0.0/gems/jekyll-4.2.0/lib/jekyll/filters.rb:407:in `compare_property_vs_target': uninitialized constant Liquid::Expression::MethodLiteral (NameError)

I could not figure out the issue, but I know something is wrong with Liquid. So I changed the dependency from liquid (5.1.0) to liquid (4.0.3) in my Gemfile.lock. Then everything worked fine.

Importing posts and pages from WordPress

Next I installed the Jekyll Exporter plugin in my WordPress site. I tried to export from the WordPress Admin UI, but it did not work. So I had to use the command line version of the plugin. I SSHed into my Google Compute Engine instance running WordPress. Then ran php jekyll-export-cli.php > jekyll-export.zip and that worked.

Followed the instructions for importing posts and pages to my local Jekyll directory and that worked. Remember that this operation only imports draft posts, published posts and pages. It does not import any styling information, comments or images from the blog.

Importing images

I SSHed again to my Google Compute Engine instance and zipped up all the images related to the blog which is basically /var/www/html/wp-content/uploads. Then I unzipped them to my local Jekyll blog. I had to remap all the images in my posts to point to the local images using sed. Then another trouble.

In WordPress when you click on an image, it enlarges it. I don’t remember if that was an inbuilt feature of Wordpress or through a plugin. But in Jekyll the images are not clickable by default. So I had to write a small script that wraps all <img> tags with <a> tag pointing to the image. Here is the script incase someone needs to do the same

#!/usr/bin/env python

# Makes images in posts clickable to expand to full-size.
# Usage: 
#   ./linkify_images.py blog/_posts
#   ./linkify_images.py blog/_drafts

import sys
import os
import glob


if len(sys.argv) != 2:
  print('Usage:', sys.argv[0], '<directory>')

media_path = sys.argv[1] + '/*/**'
media_path = os.path.join(sys.argv[1], '**')
for filename in glob.iglob(media_path, recursive=True):
  if not filename.endswith(FILE_EXTENSIONS):
  f = open(filename, 'r')
  for line in f.readlines():
    if '<img ' in line and '<a ' not in line:
      start_index = line.find('<img')
      end_index = line.find('/>', start_index)
      if end_index > 0:
        img_el = line[start_index:end_index+2]
        src_start = img_el.find("src=") + 4
        src_end = img_el.find(img_el[src_start], src_start + 1)
        a_el = '<a target="_blank" href=' + img_el[src_start:src_end+1] + '>' + img_el + '</a>'
        img_el = img_el.replace('"', '\\"')
        a_el = a_el.replace('"', '\\"')
        os.system('sed -i "s|' + img_el + '|' + a_el + '|g" ' + filename)

Layout and styling

I then fixed a bunch of other minor issues with image aspect ratios etc. Added a couple of CSS files to make the blog look the way I like. Basically the fonts, colors, spacing, alignment etc. I added the blog header image, and favicons. I followed an excellent guide to get favicon working. Thats is pretty much all I wanted to migrate from WordPress to Jekyll.

At this point I had a pretty nice looking and mostly functional blog. I did not want to add comments section. Adding comments section needs a dynamic platform to save the comments. I did not want to run any more services on compute engine because the maintenance is becoming too much. Moreover very few people comment on my site anyway so who would notice it gone? The only other things I wanted to add before I can host the Jekyll site were pagination and search. Which I will cover in another post.