Moving from Wordpress to Jekyll

I have been using Wordpress for many years. It produces good looking websites and is easy to install and maintain. Unfortunately, it isn’t easy at all to backup the website, and the interface is all web-based meaning it is difficult to create scripts which update the website. I will be switching them over at some point and moved the old domain to a spare

Most programmers use github which offers Github Pages for website hosting. The advantages over Wordpress plus hosting are:

  • It is free.
  • Websites can be edited with a normal text editor.
  • It is hosted by Github so version control etc is integrated.
  • A local copy is available so scripts to automate updating the website etc are simple and changes can be made while offline.
  • It is easy to make backups.
  • Latex rendering is easy.
  • Markdown makes code blocks easier.

I managed to move to Github under MacOS using the steps below.

Install Jekyll

Install minimal-mistakes-jekyll theme

  • Jekyll is not compatible with the stupid Dropbox directory name 'Dropbox\ \(Sydney\ Uni\)/', and I don’t think there is a way to change it. To get around this I put my website directory outside of Dropbox and made a symbolic link (inside Dropbox) so it would be backed up
  • Make a copy of, edit the _config.yml
bundle update
  • To use the local server, type bundle exec jekyll serve --incremental and browse to localhost:4000.

Convert website

  • Use the Wordpress exporter to export old website in xml format (tried the Jekyll converter plugin but that doesn’t work for large websites). This just gives the content, without attachments etc. Then
  • Use exitwp to convert Wordpress to Jekyll
  • Copy all the images and documents from the Wordpress site (wp-content directory) using ftp. I used FileZilla from the App store for this.
  • Copy the _posts directory from exitwp into the Jekyll website.
  • Copy wp-content files into assets/images on the Jekyll website.
  • To make publically available, type bundle exec jekyll build and then push the files up to Github (the repository is

Fix _posts and _pages

  • This took the most time. The main changes I needed to do was to fix the headers: remove the old link header, add a teaser image (blank one if unneeded). Then I edited the image insertion code, which involved the extensive use of Python scripts to do global replacements like
import fileinput
import re

for line in fileinput.input(sys.argv[1], inplace=1, backup='.bak'):
    line = re.sub(r'\[!.*\((.+)\).*\]\(.*\)', r'[![](\1){: .align-center}](\1)', line.rstrip())
  • I later added links to the original image with this script.
import fileinput
import re

for line in fileinput.input(inplace=1, backup='.bak'):
    line = re.sub('!\[(.*)\]\((.*)\)\{: .align-center\}',r'[![\1](\2){: .align-center}](\2)', line.rstrip())
  • and then changed them yet again to use the include form

{% include figure image_path="/assets/images/2019/10/IMG_1268.jpg" caption="Shenzhen" %}

Customise website

<div class="grid__wrapper">
{% for post in paginator.posts %}
  {% include archive-single.html type="grid" %}
{% endfor %}
  • Make figures linked to the image
<figure class="{{ include.class }}">
  <a href=
    {% if include.image_path contains "://" %}
      "{{ include.image_path }}"
    {% else %}
      "{{ include.image_path | relative_url }}"
    {% endif %}>
  <img src=
    {% if include.image_path contains "://" %}
      "{{ include.image_path }}"
    {% else %}
      "{{ include.image_path | relative_url }}"
    {% endif %}
    alt="{% if include.alt %}{{ include.alt }}{% endif %}">
  {% if include.caption %}
      {{ include.caption | markdownify | remove: "<p>" | remove: "</p>" }}
    </figcaption>{% endif %}</a></figure>
  • To enable rendering with mathjax (if it didn’t work the LaTeX symbol would not have appeared), I created a file in _includes/latex.html with
{% if page.use_math %}
<script type="text/javascript" async
{% endif %}

This is similar to the approach in

Google analytics

Go to -> Admin and create an account for website. Get the tracking ID from Admin -> Tracking Info -> Tracking Code and put it in _config.yml

# Analytics
  provider               : google-gtag # false (default), "google", "google-universal", "custom"
    tracking_id          : "UA-155095246-1"
    anonymize_ip         : false # true, false (default)

Reports will appear at

I found the following sites helpful: