At the beginning of 2014 I changed my blogging platform from Wordpress to Pelican. The reasons are briefly described in this blog-article. Now I’m going to describe the setup-process. The sources for my whole blog including this post are available on Github.


Table of Contents


As pelican is written in Python, you need to set up a dev-environment for the blog. For that I use the virtualenvwrapper by Doug Hellmann that makes working with virtual environments in Python easier. In fact it’s only one command:

mkproject -p /usr/bin/python2.7 blog

This command creates a new virtualenv and a new working directory where the code of the blog resides. In this new environment you need to install pelican and all the dependencies it has (including the dependencies of the plugins I’m using). Pip is already installed in the virtualenv so all you have to do is:

pip install Jinja2 Markdown MarkupSafe Pillow Pygments Unidecode beautifulsoup4 blinker docutils feedgenerator pelican pytz six smartypants typogrify

After installing everything you can kickstart the new blog with the following command:


This command asks some questions about your future web page to create the initial configuration files and These two files are the main configuration of the blog.


The configuration options are plentiful but pretty self-explanatory so I am only going to describe the important ones. There’s also an extensive documentation from the pelican authors.


The following two directives control how the URLs of my blog are shown in the browser and how they are saved on the server.

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

When configured as above, the URLs look like this

… and are saved on the webserver like this:


RSS Feeds

I enabled full RSS-Feeds for my website. There are two feeds: an article feed for all articles and a feed for articles of only a specific category. The last option causes the feed to be fully displayed.

FEED_ALL_RSS = 'feeds/all.rss.xml'
CATEGORY_FEED_RSS = 'feeds/%s.rss.xml'


The PATH setting controls where pelican searches for the articles, the PAGE_DIR setting tells pelican where to search for static pages, that do not get handled like normal posts (e.g. an “about me” page). The content-directory is created by default, but the pages-directory must be created as a subdirectory of the pages-directory.

PATH = "content"
PLUGIN_PATHS = ['pelican-plugins']
PAGE_PATHS = ['pages']

The third option tells pelican where to look for it’s plugins. You’ll have to download them from Github by cloning its repository:

git clone

I’ll show later on how to use these plugins.

Aside from the pages-subdirectory, there’s also another static path called images where you store the images you use in the articles (who would have guessed). A static path is a path you want to have a accessible on the output path “static”, and the images-folder will be copied by default. I defined another static path called extra. In it resides the robots.txt. The robots.txt should normally be accessible from directly from the root of the page (e.g. but my robots.txt is in the folder called extra. How do we get it into the content root? You can use EXTRA_PATH_METADATA for that. With it you can shift the location of a file:

#static paths will be copied without parsing their contents
#path-specific metadata
    'extra/robots.txt': {'path': 'robots.txt'},


If you have Piwik instance running, there’s an easy way (in most templates) to include it automatically when creating your website. Just configure the following two lines in your


(You can find the ID of your site in your Piwik settings.)


A huge plus for pelican is its easy plugin-system. To use one, you simply add it to a list!

PLUGINS = ['better_figures_and_images','extract_toc','summary','optimize_images','related_posts','sitemap','tipue_search']

But before you can actually use these plugins, you’ll have to download them from Github. Execute the following command in the root directory of your pelican installation:

git clone

If you didn’t change the plugin-path in the paths-section as mentioned above, you now can use these plugins. If you downloaded the plugins to another directory, you’ll have to edit the path to point to the correct location.

I’m using several plugins right now. You’ll find all of them and the correspondending documentation in the Github repo. That’s why I an only going to describe one plugin, the tipue_search.

Searching is done via Tipue Search. What Tipue search is, is explained best by the website:

Tipue Search is a site search engine jQuery plugin. It’s open source and responsive. Tipue Search only needs a browser that supports jQuery. It doesn’t need MySQL, PHP or similar. In Static mode it doesn’t even need a web server. Tipue Search is released under the MIT License, which means it’s free for both commercial and non-commercial use.

To use it, create a separate search.html-page where the search-results will be displayed. It should contain the Tipue Search javascript files, some css-markup and the javascript function that displays the results:

{% extends "base.html" %}
{% block content %}
<link rel="stylesheet" type="text/css" href="{{ SITEURL }}/theme/css/tipuesearch.css" media="screen">
<script type="text/javascript" src="{{ SITEURL }}/theme/js/tipuesearch_set.js"></script>
   <script type="text/javascript" src="{{ SITEURL }}/theme/js/tipuesearch_min.js"></script>
    <script type="text/javascript">
    $(document).ready(function() {
            'mode' : 'json',
            'show': 10,
            'newWindow': false,
            'contentLocation': 'tipuesearch_content.json'
        <div id="tipue_search_content">
            <div id="tipue_search_loading">
{% endblock content %}

Then you have to insert the search-field into your web page. I put it in the header, so it can be used on any page on my site. To do this, you just have to insert the search form of the header:

<form class="navbar-form navbar-left" role="search" action="{{ SITEURL }}/search.html" onsubmit="return validateForm(this.elements['q'].value);">
    <div class="form-group">
        <input type="text" class="form-control" placeholder="Search" name="q" id="tipue_search_input">

Make sure to point it to the right search-page in the “action”- field.


Since pelican doesn’t need a backend like MySQL to store it’s contents, I don’t want to store the comments on my articles in a separate database either. Furthermore I do not want to host my comments on third party sites like Disqus. So there aren’t many options left. By the time of writing this article, there’s a plugin that lets you store the comments in plain text on your server, but when installing this blog, I didn’t have this alternative. That’s why I used isso. Isso is a commenting system like disqus but stores the comments in a local sqlite-database. To use isso in pelican, you’ll have to install it first, using the provided documentation. Then you’ll have to insert it into your website. Create a new html-file called comments.html and fill it with the following content:

<script data-isso="/isso" src="{{ SITEURL }}/theme/js/embed.js"></script>
<section class="comments" id="comments">
    <h2 class="panel">Comments</h2>
        <section id="isso-thread"></section>

Edit the script-src to point it to the right javascript-file. Depending on the vhost where isso runs, you likely have to edit the data-isso, too.

To include this comments.html in your articles, insert the following lines in the article.html after the article-content.

            {% include 'comments.html' %}

Writing and publishing posts

The most important part of your page. Please refer to the documentation on how to write posts as I can not explain it better myself.

Related posts: