Recently I migrated this blog site from Octopress to Pelican. Here is why and how.

What's Wrong with Octopress?

I have been using Octopress for a while (actually almost two years!) and it's been working great. In fact, I even wrote a few Octopress plugins myself (e.g, page-view, post-revision and popular-posts) to make blogging easier.

However, the major problem with Octopress is that building the site is super slow. Right now I have roughly 100 posts, and a build can take up to several minutes to finish (vs. 9 seconds in Pelican). And I just can not stand it any more.

Additionally, Octopress is based on Jekyll, which uses Ruby, which I am never a fan of. And the author of Octopress promised to clean up the spaghetti layout of the repository, yet it seems takes forever to finish.

Why Pelican?

Pelican has several great features that look very appeal to me:

  • Using Python---my favorite language.
  • The framework is packaged cleanly as a single Python package, so I can use Virtualenv and all that great stuff from Python.
  • Support reStructuredText and Markdown, so it's potently easy to migrate from Octopress.
  • Because it uses Python, I might actually willing to fix a thing or two in case it breaks.


pelican-quickstart is great in set up a minimal working directory quickly. After copying the posts from source/_posts to content, there are a couple of things to take care of.

YAML Front Matter

Octopress uses YAML front matter for post meta data, such as title, date, tags, etc. Pelican can recognize most of them but tags and category. More specifically,

  1. In Octopress, you can put a post in multiple categories using the categories attribute. But in Pelican, one post can only in one category using the category attribute. This may cause trouble if you had some post in multiple categories in Octopress.
  2. Pelican can not recognize the YAML front matter for tags, which is very similar to a JSON array. For example, in Octopress, it's tags: ["tag1", "tag2"]. In Pelican, it's tags: tag1; tag2.

I fixed the first one by substituting all categories with category. Then I tried to manually convert the YAML style array to Pelican style array using sed, which failed miserably.

Then I found the md-metayaml Pelican plugin, which was exactly what I needed. Just add md-metayaml to your PLUGINS and boom, Pelican can now recognize YAML front matter!

Liquid Tags

Octopress uses Liquid Tags for multimedia resources, such as images, videos, etc. Similar to YAML, there is also a liquid-tags plugin for Pelican. I mostly use the img tag, so I just added liqued_tags.img to the PLUGINS. You can add others as well, such as youtube, video.

However, there is one tags that I used before that is missing in liquid-tags plugin---blockquote. Fortunately, I only used this tag in one post and I happily convert it using the standard Markdown block quote syntax.

Summary Text

By default, Pelican uses a fixed number of words as the post summary. I prefer the way that Octopress handles summary: explicitly use a excerpt separator (<!-- more -->) to control which part goes to the post summary (typically first paragraph).

Again, there is this summary plugin that does exactly as mentioned above. Just put summary in PLUGINS and set SUMMARY_END_MARKER to be <!-- more -->.

URL Pattern

This is probably just me: the URL pattern on this site is actually inherited from the old days when I was using WordPress. Basically, the post URL is something like /2015/10/11/title-slug/index.html, which corresponds to 2015-10-11-title-slug.markdown file in Octopress.

First, we need to tell Pelican to obtain URL slug from the file name:

FILENAME_METADATA = '(?P<date>\d{4}-\d{2}-\d{2})-(?P<slug>.*)'

Then we set the article URL pattern:

ARTICLE_URL = '{date:%Y}/{date:%m}/{date:%d}/{slug}/'
ARTICLE_SAVE_AS = '{date:%Y}/{date:%m}/{date:%d}/{slug}/index.html'

Wrap It Up

At this point, we have done most of the migrations. There are couple of more tweaks that makes Pelican works better:

  1. Using a theme (I used pelican-bootstrap3)
  2. Add some awesome plugins, such as related_posts, tag_cloud, sitemap, and tipue_search.
  3. Enable monthly and yearly archives.

You can see a full Pelican configuration file here.