Exercises in Restful Integration and Continuous Delivery

Musing on Software Development and Technologies.

Fri 01 January 2016

Moving to Pelican

Posted by Mikko Koivunalho in About the blog   

Pelican Logo

Moving to Pelican

From Blogger

I used to have this blog in Blogger. In the beginning I created my blog in Blogger simply because it seemed the easiest way to do it: everybody else's blog was already there. But soon afterwards I started to develop a dislike towards Blogger. The main causes were two:

  1. I wasn't sure anymore who actually owned my blog entries, and
  2. It was always a hassle to import my new writings.

The second one actually made me decide against Blogger. I never wrote using Blogger's editor but always in my own desktop or laptop, in my own time, and often off-line. And I like to edit in versions, i.e. I like to have different versions of the same article at my disposal so I can compare with what I wrote earlier. I use version control, nowadays Git.

Via Calepin

I knew about Calepin before. It uses Dropbox as a source for Markdown formatted text files which it converts into blog posts. These files can be edited again or even removed and Calepin will make the changes automatically into the blog. Too bad I don't use Dropbox, and won't start only to have a blog! Also, all Calepin blogs look alike; no chance for changing blog's appearance.

But I really liked the principles of blog generation behind Calepin:

  • Static content, only regenerated when the sources (blog texts) change.
  • Markdown used as format for source files.
  • Blog generation can be automated (in Calepin's case, by Dropbox' webhooks).
  • Because the pages are static, even the most simple webserver can handle it, and load is minimum.

The software behind Calepin is Pelican, a static site generator. Actually, "pelican" is an anagram of "calepin" (notebook in French).6

Setting up Pelican

There is a whole host of static site generators — made with a dozen different programming languages, anything from Perl1 to C++2 to Go3. Despite my long history with Perl, I decided to go with Pelican (Python) because I was nevertheless impressed by Calepin. If it could be used as the backbone of Calepin, it must be versatile for whatever application I can come up with.

All I need is a server with Apache or any other HTTP server running — and that I already have. And then off to see and sample the multitude of different themes ("skins") for Pelican: These are collected nicely to the webpage Pelican Themes.

I picked voidy-bootstrap. Not entirely happy with it, but for the moment it will do. I get things running — and that's the most important thing now. Then I can get back to writing.

Of course, one minor setback in abandoning Blogger was that now my (static) blog did not allow readers to leave comments. Pelican however supports blog comments via Disqus, so I set that up.

Disqus is a third-party commenting system. Pelican adds some JavaScript code to the web page and when a visitor's browser loads the page, it runs the code which fetches the Disqus interface, and any existing comments from Disqus' servers. This makes Disqus easy to install and as such, Disqus is a popular commenting system ("used by over 3.5 million websites")4.

This is another thing which I might change in the future. Disqus has lately attracted some criticism.5

Finalizing Exercises in Restful Integration and Continuous Delivery

And with that I was almost ready. Finishing touch, favicon, that little picture which is mostly used in browsers' bookmarks list, or before the page name in tab. Browsers have a bad habit of caching the favicon. It took several hours of trial and error to finally get the file favicon.ico into the right place. I got considerable help from Real Favicon Generator.net.

I copied my old blog posts from Blogger, created a Git repository for them and cloned that repo in my blog content directory. However, every time a new blog entry is created or an old one is edited, I need to log in to the server and run the pelican command from the shell to recreate the blog.

But this was easy to make automatic: Since the Git repository and the blog webpages reside in the same server, I created a git post-receive hook which runs pelican whenever I push to master branch or draft branch. Having the draft branch option allows me to make small changes and have them visible without polluting the master branch history. If I add to the blog entry file row Status: draft (instead of Status: published) the new entry will be published only in subdirectory /draft, not as part of the main blog. And of course, I can plan new articles on other branches without disturbing the published site.

My Git hook script:

#!/usr/bin/env bash

# shellcheck disable=SC2034
while read oldrev newrev refname; do
    if [[ "${refname}" =~ ^refs/heads/(${PUB_BRANCHES})$ ]]; then PUBLISHABLE_BRANCH=1; fi
    BRANCH="$(expr "${refname}" : '^.*/\(.*\)$')"
    echo "commit on branch '${BRANCH}'"

if [ 0 -eq "${PUBLISHABLE_BRANCH}" ]; then
    echo "No commits to any publishable branch. No publish! Exiting..."; exit

# Remove all Git related variables, especially GIT_DIR!
# shellcheck disable=SC2046
unset $(git rev-parse --local-env-vars)

cd ${BLOG_MD}/
git fetch --force --all
git checkout --force ${BRANCH}
git pull origin ${BRANCH}
cd .. # To blog config dir.

# Create and deliver to webserver
pelican content -s publishconf.py && rsync -avc --delete output/ ${BLOG_HTML}/

Goodbye Blogger

The only thing missing is a link in my old blog and a goodbye note!

For now anyway! Maybe one day Blogger has evolved into a good alternative — and I'll migrate back.