osteel's blog Web development resources

Install and deploy a Pelican blog using Fabric - Part 4: workflow, extras and conclusion

Been here before?

You can also subscribe to the RSS or Atom feed, or follow me on Twitter.

Alright! This was a bit of a long road, but we are finally getting there. In the previous part, we used Fabric to fully provision a server and pull our content from a Git repository. In this fourth and last part, we are going to review a complete worklow, take a few extra steps to complete our blog and conclude our journey.


Complete Workflow

Let's have a look at what a complete workflow would look like: it will also summarize all that we have done so far.

Here is mine:

  • Create a new article directly under "content/posts/", with "Status: draft"
  • Edit the content (I personally use Mou, a Markdown editor for Mac)
  • Generate and serve the blog locally: fab reserve
  • Access http://localhost:8000/drafts and check the look of the article
  • Edit and push the article to the Git repository as often as necessary until it is finished
  • When ready to publish, create the right year/month/day folders under "content/", move the article there and remove "Status: draft"
  • Git commit and push
  • fab publish
  • Check the article on the live website

...and Bob's your uncle.


If you followed all the steps up to now, you already have a fully functional blog. But there are a few extra things you will probably want to add in. Some of them are coming from the tips and tricks page.

Images, favicon and other static files

Chances are you will want to add images to some of your articles. They will have to be stored somewhere and copied over at compilation.

To that end, create a folder named "images" in "content". I personally follow the same structure as for the articles, e.g. I place pictures under "images/2015/02/22/" for articles published on that day.

To have this directory copied to "output/" with the rest of the content, open "pelicanconf.py" and add this section:


This simply indicates to the generation script that this directory is to be copied as is under "output/".

And this is how you would embed images in your articles (Markdown syntax):

!["Example image"](/images/2015/02/22/example.jpg "Example image")

How about a favicon? Create another directory under "content/", named "extra". Place your favicon in there, and edit the config file again:


    'extra/favicon.ico': {'path': 'favicon.ico'}

The "EXTRA_PATH_METADATA" allows to specify more precisely the path of specific files. Here, we basically say that we want "favicon.ico" from the "extra" directory to be copied at the root of the blog.

You can add as many files as you wish in there, such as a "robots.txt", for example.

Google Analytics

Pelican supports Google Analytics out of the box. All it takes is to add the following line to the "publishconf.py" file ("UA-XXXX-Y" being your own tracking id):



Under "theme/templates/", add a "sitemap.html" file:

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">

{% for article in articles %}
    <loc>{{ SITEURL }}/{{ article.url }}</loc>

  {% for translation in article.translations %}
    <loc>{{ SITEURL }}/{{ translation.url }}</loc>
  {% endfor %}
{% endfor %}

{% for page in pages %}
    <loc>{{ SITEURL }}/{{ page.url }}</loc>

  {% for translation in page.translations %}
    <loc>{{ SITEURL }}/{{ translation.url }}</loc>
  {% endfor %}
{% endfor %}


Edit "pelicanconf.py":

DIRECT_TEMPLATES = (('index', 'tags', 'categories', 'archives', 'sitemap'))
SITEMAP_SAVE_AS = 'sitemap.xml'


Are also supported by default. This is just a matter of configuration, which is all well explained in the documentation.


Well well well. Obviously this was way more complicated than just opening a Tumblr or a Wordpress. I assume that if you chose to go down that road, it was also for the educational aspects that were coming with it.

So did I.

And really, I have learned a lot putting all this together, and I hope you are taking away a little bit of new knowledge as well.

So now what?

Well first, tap yourself on the back and take a break, you deserved it.

Anything unclear? Don't hesitate to refer to the result repository, it might be helpful. Or just drop a line in the comments, I'll be happy to help.

Then, here are a few leads if you want to go further.

The first and obvious one is to host everything on a real server. I personally use a DigitalOcean (referral link) droplet, because it is cheap and easy to setup (the most basic one is more than enough to serve a static HTML blog like Pelican). In any case, once you have got your server, all it should take is to update the corresponding section of the "fabfile.py" file, as described at the end of the "provision" section.

You could also add a new Fabric function to speed up the process of starting a new article (have a look at the make version of this on the tips and tricks page for inspiration, or use it as is if you prefer).

Finally, if you are using GitHub to host your repository, why not trying to use a webhook to make the publication even easier?


This tutorial is the result of the combination of many different sources. Apart from the official Pelican documentation and the Fabric one, here are the articles and people that were helpful:

Enjoying the content?

You can also subscribe to the RSS or Atom feed, or follow me on Twitter.

Last updated by osteel on :: [ vagrant fabric tutorial python blog pelican ]