Almost exactly a year ago, I closed down my WordPress site and created a statically published, Assemble.io site to house technical articles and my resume. The engine used Markdown templates, an off-the-shelf bootstrap UI, and Grunt with Assemble.io to build and publish changes to S3, which served my site to the public.

I chose Assemble.io because I was coding regularly in Node.js at the time. As my Assemble.io tutorial states, Assemble.io is “a Node.js alternative to the popular static publishing tool, Jekyll.”

Now here we are in 2016, a leap year, an Olympic year. I didn’t like the design of my old site and I wanted a fresh start. What a great time to switch over to Jekyll, The King of Static Publishing™.

Migration Requirements

My old site had the following components:

  • A blog that I pretentiously called a Journal.
  • My resume as a section of the home page.
  • Links to my social media accounts.

I was happy to ditch the design and the resume, but I wanted to keep the journal entries and social media links.

Additionally, I needed to import all of my old WordPress posts, which I exported to the convoluted WordPress XML format called WordPress eXtended RSS (WXR). Some of these posts were written over a decade ago so I wanted to be able to hide some and show others.

Finally, I wanted to continue hosting the site on S3.

To summarize, I needed to do the following:

  • Create a basic Jekyll blog.
  • Create a simple look and feel for the site.
  • Import my old journal entries from the previous site and blog entries from my old WordPress site.
  • Host it on S3.

Create a Basic Jekyll Blog

Note: The source code for this Jekyll-powered website is hosted on GitHub in the webercoder.com repository.

Jekyll requires RubyGems to operate. I installed Ruby 2.2.3 using rbenv, which circumvented permissions issues that I had when using the built-in gem command on OS X.

I installed Jekyll using gem:

$ gem install jekyll

Next I created a new branch in my webercoder.com repository on GitHub, deleted everything in the folder, and committed the result.

I created a basic blog scaffolding in the current directory (specified by the .):

$ jekyll new .

This command creates a directory structure that looks like this:

$ tree .
.
├── _config.yml
├── _includes
│   ├── footer.html
│   ├── head.html
│   ├── header.html
│   ├── icon-github.html
│   ├── icon-github.svg
│   ├── icon-twitter.html
│   └── icon-twitter.svg
├── _layouts
│   ├── default.html
│   ├── page.html
│   └── post.html
├── _posts
│   └── 2016-05-04-welcome-to-jekyll.markdown
├── _sass
│   ├── _base.scss
│   ├── _layout.scss
│   └── _syntax-highlighting.scss
├── about.md
├── css
│   └── main.scss
├── feed.xml
└── index.html

5 directories, 19 files

To work with the site, type jekyll serve in a shell and then go to http://localhost:4000. The serve command is also a listener that will rebuild the blog whenever a local file is saved.

Create a Simple Look and Feel

This Jekyll template comes with a UI, and reshaping it started with css/main.scss. This SASS file does the following:

  1. Declares variables to be used in other SASS files located in the _sass folder.
  2. Defines a mixin that will be used to create a responsive UI.
  3. Includes the SASS files from the _sass folder.

I deleted all the SASS files in the _sass folder–aside from _syntax-highlighting.scss which is useful for code snippets–and replaced the contents of css/main.scss with the following:

---
# Main SCSS File
---
@charset "utf-8";

@import
    "variables",
    "media-queries",
    "base",
    "font-awesome/font-awesome",
    "post",
    "other",
    "syntax-highlighting"
;

I could chuck all the code from each include into css/main.scss but that would be a maintenance nightmare. In all honesty, my design was done ad-hoc and isn’t much better. I’ll clean it up eventually, keeping variables, syntax-highlighting, base, and media-queries. The remaining files will be structured in a more thoughtful manner.

The layout starts and ends with _includes/header.html and _includes/footer.html. I cleaned up the HTML for my site header and about page in the header, and added Font Awesome social media icons and Google Analytics code in the footer.

Each page in the system has a layout parameter in the header YAML that tells Jekyll how to render the resulting HTML. I’ve kept the three layout files, but I changed a few minor things, like the rendering of titles and the adding of Disqus comments.

Finally, I changed the page files at the root of the repo. index.html is the home page and about.html is the about page.

For index.html, I broke up the entry lists into three sections for each of my blog categories. I looped over site.categories map to retrieve the posts for each:

{% for post in site.categories.Technology %}
	[...]
{% endfor %}

Inside the loop, I wrote the statement {% unless blog.secret %}. I’ve added secret: true to each old blog post that is not ready for publication. I was too liberal with my revealing of posts, so I’m frantically trying to update them on train rides to and from work.

Importing Old Entries

Assemble.io Posts

Importing my most recent entries from Assemble.io was trivial because they were already in Markdown format. I just manually changed the YAML headers in each to match the Jekyll format, which was nearly identical.

My new styles support <figure> for images, so I also modified the content of the entries to match the new site design.

WordPress Posts

I previously tried this using the wp2md Python package and my own WordPress to Markdown wrapper script, and it worked. In the end I decided to just use new posts and start fresh for other reasons.

I’ve changed my mind for this site. I didn’t even have to use my own importer since Jekyll has a WordPress importer built in!

This command from the Jekyll WordPress document imports all posts from a WXR XML file to the local Jekyll structure:

ruby -rubygems -e 'require "jekyll-import";
    JekyllImport::Importers::WordpressDotCom.run({
      "source" => "wordpress.xml",
      "no_fetch_images" => false,
      "assets_folder" => "assets"
    })'

The command fails the first few times it runs. After installing what it asked for, it worked like a charm.

The posts are imported as HTML rather than Markdown and the importer pollutes the YAML headers with a bunch of WordPress metadata.

I’ve been slowly converting my posts to Markdown; it’s a very time consuming task. Luckily the nostalgia I feel from reading these old posts makes it much more bearable.

Hosting on S3

The Ruby and Jekyll world are filled with useful tools, such as the s3_website program, which uploads the generated site to an S3 bucket. Check out their site for more information.

I already had my bucket setup to serve content via Route 53 rules, so I’m not going to cover that here. Feel free to ask me questions if you’re interested, though!

Conclusion

Hope you enjoyed the entry! I’m happy with my move, but check back next year since I seem to restructure on an annual basis. ;)