How the menu appears on my phone.

I updated this website for a cleaner look, nicer video embeds, and to include an auto-generated blog series index. Most important management is easier using Jekyll and Octopress 3. Currently Octopress 3 lacks an official release website ( still on version 2), but the Octopress GitHub page includes basic usage. The nice part of version 3 is that it is a plugin for Jekyll so everything Jekyll works, and the management is cleaner than Octopress 2. Even if Octopress 3 isn’t quite ready for prime time, I’m liking it. Before taking the plunge, I looked up posts on migration to see how it went for others switching from 2 to 3. Check out what @dgmstuart and @samwize on GitHub have to say.

Migrating from Octopress 2 is dead simple by creating a new Octopress 3 blog and copy all the post and page markdown files over. Then choose a theme, or customize base Jekyll to your liking. I enjoy being able to organize my page markdown files as a like and setting the YAML permalink to where it needs to go. Let’s go over key components and customizations I made.


Your system needs tools to get started. If you’re migrating from Octopress 2 like I did then you likely have these.

Setup Jekyll and Octopress 3

mkdir mywebsite
cd mywebsite
touch Gemfile

Edit your Gemfile. Mine looks like this:

source ''
gem 'jekyll'
group :jekyll_plugins do
gem 'octopress', '~> 3.0.11'
gem 'octopress-image-tag'
gem 'octopress-video-tag'
gem 'octopress-codeblock'
gem 'octopress-quote-tag'
gem 'octopress-codefence'
gem 'octopress-solarized'
gem 'jekyll-paginate'
gem 'jekyll-feed'

Run bundle to add your gems, and make a default website.

bundle install
octopress new

To view your site on the localhost, run:

bundle exec jekyll serve

Your site ends up in the _site folder. If you just want to build then:

bundle exec jekyll build

Migrating from Octopress 2

Copy your old posts from /source/_posts to /_posts. For pages, copy and rename your old markdown files organized as you wish. Make an images folder and copy your images over. Edit the page YAML to include “permalink: /” with location you want it to appear in. If you used the Octopress 2 Liquid blockquote, you’ll want to replace “blockquote” with “quote” to work with the new octopress-quote-tag gem. You may do this using grep as follows if using macOS:

grep -r -l ‘blockquote’ . | sort | uniq | xargs perl -e “s/blockquote/quote/“ -pi

See Marc Juchli’s answer on StackExchange for the grep tip.

Edit your _config.yml to set your plugins:

_config.yml partial
- jekyll-paginate
- jekyll-feed
- octopress-image-tag
- octopress-video-tag
- octopress-codeblock
- octopress-quote-tag
- octopress-codefence
- octopress-solarized

Also update _config.yml with your old permalink, date_format, and all that good stuff.


Octopress 2 supported the breaking long posts into excerpts to keep the index page shorter with a “read more” link. The Jekyll document page on excerpts describes how to achieve this. Add your seperator into your _config.yml:

_config.yml partial
excerpt_separator: "<!-- more -->"

Edit index.html to include the excerpt and “read more” text:

index.html partial
<!-- This loops through the paginated posts -->
{% for post in paginator.posts %}
<h1><a href="{{ post.url }}">{{ post.title }}</a></h1>
<p class="author">
<span class="date">{{ | date: "%b %-d, %Y" }}</span>
<div class="content">
{{ post.excerpt }}
{% if post.excerpt != post.content %}
<a href="{{ site.baseurl }}{{ post.url }}">Read more...</a><br />
{% endif %}
<br />
{% endfor %}

Landing page

By default, Jekyll puts your posts index page (index.html) at the root and everything below that. I like having a home landing page with my post index in /blog/ on the same level as other main pages in the mneu. Simply move the index.html into the /blog/ folder and create a new with YAML “permalink: /” and fill in the landing content. All my posts are by title beneath /blog/ so my _config.yml contains this:

_config.yml partial
permalink: /blog/:title/
baseurl: "" # the subpath of your site, e.g. /blog/

Add a link to the blog post index in the menu by editing /includes/header.html.

Archives and categories pages

Octopress 2 came with category index pages and a blog archives page listing by date. If you want these, there’s some extra work involved. Justin James has a nice tutorial, “Adding a Category Page” which I borrowed and customized to my liking. Since Octopress 2 puts each category in a separate page, I also created sub-pages by category to maintain compatibility by not having to update links or create redirects. You can see my main categories at /blog/categories/, my programming category, and gaming category pages as examples. Use a similar approach for archive-by-date page ordered by date and formatted as you wish.

Exclude pages from auto-generating to menu

Michael Chadwick has a nice tutorial, “Exlcuding Pages from Top Navigation in Jekyll”. Chadwick suggests adding an unless clause in _includes/header.html and add the exlude key to the page’s YAML front matter.

header.html partial
{% for page in site.pages %}
{% unless page.exclude %}
{% if page.title %}
<a class="page-link" href="{{ page.url | prepend: site.baseurl }}">{{ page.title }}</a>
{% endif %}
{% endunless %}
{% endfor %}
category page YAML header
layout: page
title: "Posts by Category"
permalink: /blog/categories/
exclude: true
comments: false
sitemap: false

Other bits

I switched codeblock to use the Solarized theme to fit in better by using Octopress Ink to add the plugin file. See the tip on Github. For building a blog series index, check out the tutorial by Justin James, “Creating an Article Series”. See an example in action: Skyrim mod series.