(mis)adventures in software development...

01 June 2015

What’s New In VoidyBootstrap Version 2

Category Web Development

An overview of the changes and new features in version 2 of the VoidyBootstrap Pelican theme.

VoidyBootstrap is a theme for the Pelican static site generator.

This post is a summary of the main changes introduced in Version 2 of VoidyBootstrap.

As far as blog themes go, VoidyBootstrap is deliberately minimal in terms of design. It’s based on Bootstrap, and by default it just provides a standard Bootstrap look and feel. Nothing much has changed in this regard.

However, its main reason for existing is flexibility and customisation, and it’s here where I’ve made significant changes, some of which break backwards compatibility with previous versions. This is something I wanted to avoid, ideally, but in the end I decided it was justified. With these changes the result is a Pelican theme that is now even more flexible and customisable, with a more consistent naming convention for its many configuration options.

I never actually intended to undertake such an extensive update. When I started working on what would eventually become version 2, I just planned to update dependencies (Bootstrap, FontAwesome, etc) to the latest versions, and make a few other tweaks. But as often happens with these things, what started as a few small tweaks quickly escalated to into weeks of large scale hacking and refactoring. I ended up adding and changing so many things I felt I should call this release “version 2”. (For what it’s worth though, I don’t intend on making any more large scale changes like this. The version 2 series should be just small incremental updates — hopefully — but we’ll see…)


VoidyBootstrap started off as a custom theme for this blog, then gradually evolved into a stand-alone open source theme. Unsurprisingly, therefore, it reflects my requirements and is geared towards my Pelican workflow. VoidyBootstrap is admittedly a somewhat idiosyncratic Pelican theme, but it works for me, although of course your mileage may vary.

VoidyBootstrap came about out of my desire for a simple Bootstrap-based Pelican theme that was easy to customise. There are 3 main overriding goals I had with VoidyBootstrap:

  • It had to be flexible and customisable.
  • Despite its focus on customisation, it should be easy to set up. It should “Just Work” out of the box, with sensible defaults, and good documentation.
  • Customisation workflows should play nice with version control, making it possible to isolate changes and easily merge in upstream changes in the base theme.

Much of the changes in version 2 have been motivated by that last point, even though it may not be immediately obvious that’s the case.

Custom CSS and Javascript


The MAIN_LOCAL_STYLESHEET setting has been renamed to BOOTSTRAP_STYLESHEET. This option allows an alternative (customised) Bootstrap CSS file to be used in stead of the standard one.

As before, if BOOTSTRAP_STYLESHEET is not set, the standard Bootstrap CSS file is used via a CDN.

The above settings represent the primary means of incorporating custom CSS files, but in version 2, there are now even more options when it comes to configuring CSS and JavaScript files.

The new STYLESHEET_URLS setting allows additional style sheets to be linked in from arbitrary URLS (e.g. from a CDN). Once possible use case for this setting is to incorporate the Bootstrap theme CSS file from CDN, like so:

STYLESHEET_URLS = ("https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap-theme.min.css", )

Similarly, JAVASCRIPT_URLS and JAVASCRIPT_FILES settings have been added to make it easier to incorporate custom, site-wide JavaScript files.

For those who, for whatever reason, might not want to use any CDN files, it’s now possible to configure VoidyBootstrap without any dependencies on external CDNs. Doing this requires using the new SKIP_DEFAULT_CSS and SKIP_DEFAULT_JS settings, and then manually configuring all the theme’s dependencies (Bootstrap CSS and JavaScript, Font Awesome, jQuery) using the above settings:

BOOTSTRAP_STYLESHEET = "bootstrap.min.css"
STYLESHEET_FILES = ("font-awesome.min.css", "pygment.css",)
JAVASCRIPT_FILES = ("jquery.min.js", "bootstrap.min.js",)

Note that if you go this way, it’s entirely up to you to download all those files and put them in the correct directories. (The theme is designed to use CDNs by default, and does not ship with any vendor files.)

Optional Templates removed

A core idea behind VoidyBootstrap is that most “blog” type websites have certain similarities in layout and overall structures, and therefore there are certain semantic content blocks that are likely to appear in most blogs (e.g. navigation, footer, author bio, etc).

Wherever practical, VoidyBootstrap will leave these content blocks blank and provide ways to theme users to add their own content. Or alternatively, provide a default implementation, but let theme users override this with their own, if they prefer (for example, like with the sidebar, as discussed above).

Version 1 of VoidyBootstrap had two ways to customise these “content blocks”: “Optional Templates” and “Custom Includes”.

Optional Templates have now been removed in favour of Custom Includes. Everything that was possible with Optional Templates in earlier versions can now be accomplished with Custom Includes.

Optional Templates seemed like a good idea at the time, but in practice I found them unwieldy. And it seems kind of redundant — not to mention potentially confusing to new users — to have two arbitrarily different mechanisms for essentially accomplishing the same thing. So Optional Templates are gone (vestiges may remain in the code, but these will eventually be removed — do not rely on them), and new Custom Includes have been added in their place (see below).

New Custom Includes

Custom Includes”, for want of a better term, is a method VoidyBootstrap provides for customising content blocks. Custom Includes are settings beginning with the prefix CUSTOM_. They are all optional, but if used, must be set in pelicanconf.py to the filename of a Jinja template filename (or a list/tuple of filenames for some) which will then be added to the appropriate place in the website layout (via a Jinja include directive).

Lots of stuff has been changed when it comes to “Custom Includes”.

Some configuration setting were renamed, some were removed, and a whole bunch were added.

With the new “Custom Includes” settings, there is now far more fine grained control when it comes to adding blocks of custom content.

In many cases, it’s now possible to provided different templates for different page types (INDEX, ARTICLE, PAGE, CATEGORY, TAG, etc).

There are options for adding content outside of the main Bootstrap container used to wrap the 2 columns (CUSTOM_HEADER_*).

There are options for adding content inside the main Bootstrap container but above/below the columns, so in 2 column mode content will span above or below the 2 columns (CUSTOM_CONTAINER_TOP_* and CUSTOM_CONTENT_BOTTOM_*).

The settings CUSTOM_CONTENT_TOP_* and CUSTOM_CONTENT_BOTTOM_* are now the ones used for adding arbitrary content to the top or bottom of the content column.

Note that some of the new Custom Includes settings are lists: CUSTOM_SITE_HEADERS, CUSTOM_ARTICLE_HEADERS, CUSTOM_INDEX_ARTICLE_HEADERS, CUSTOM_ARTICLE_FOOTERS and CUSTOM_PAGE_FOOTERS. I realise this might be potentially confusing to new users of the theme. But I found with these settings in particular, it was often useful to be able to specify multiple templates. It makes it easier to split template fragments into smaller chunks, which could then be reused (DRY and all that).

For more details about the new Custom Includes see the “Custom Includes” section in the README, as well as the changelog.


The above is by no means a complete list of changes. Just the main ones (the ones most likely to affect anyone attempting to upgrade their installation from an earlier version). There have been other bits and pieces added or changed along the way. I think everything that deserves documenting has been documented in both the changelog and the README, although I might have possibly missed something.

If you do find anything I might have missed, let me know in the comments.