Data-Dive

Adding Colorbox to Pelican blogs for prettier images

· mc51

Blogs created with static site generators are en vogue. They are fast, safe and have minimal requirements. They can be hosted virtually anywhere. One of the more popular options at the moment is Pelican. It is the generator I use for this blog. (I recently switched to Hugo). Pelican is written in Python, has a lot of nice themes and is extensible with a bunch of plugins. Getting a basic version set up is quite easy. I recommend the following guides, which I partly relied on, for step-by-step instructions:

Adding plain pictures

One major thing bothered me after setting up my blog: I could not find an easy way to implement images in a way that made them look good. Adding images is simple:

  • Create an img/ folder inside pelican’s content/ directory
  • Add/Edit the following line in pelicanconf.py: STATIC_PATHS = [‘img’]
  • Refer to the image in your Markdown code: ![my_image](/img/my_image.png "Image Title on mouse-over")

The result is this: Carnival By Citanova Düsseldorf (Düsseldorf Karneval 2013) [CC BY 2.0 (http://creativecommons.org/licenses/by/2.0)], via Wikimedia Commons

That’s not bad, but there is no straight forward way to change the size, show a thumbnail or view the image in full resolution. Especially, when embedding screenshots in my posts that’s a serious downside. My first solution was to wrap a link around the image to make it clickable. That is a simple workaround for enlarging the picture [![my_image](/img/my_image.png "Image Title on mouse-over")](/img/my_image.png). It’s better, but still not good enough because you need to leave the page to view the image in full-size. I wanted something more practical and nice: having a thumbnail which on click opens a layover with the enlarged image. Turns out this feature is called a lightbox and there numerous options to choose from.
One that I like a lot is colorbox by Jack Moore. It is written in JavaScript and uses the jQuery library. Unfortunately, I could not find an out of the box way to make colorbox work with my pelican installation. Thus, I had to fiddle around a bit until I found my own little solution that is a bit hacky. Still, it does all that I need so far.

Implementing the colorbox plugin

First thing: get colorbox. Hopefully, you have git installed so you can just do:

~/blog/$ git clone https://github.com/jackmoore/colorbox.git && cd colorbox

Alternatively, get the .zip and unpack it. Now copy jquery.colorbox.js to your pelican’s theme folder into the /static/js/ subfolder:

~/blog/colorbox$ cp jquery.colorbox.js ~/blog/themes/pelican-bootstrap3/static/js

Also, make sure that this folder contains jquery.min.js, the jquery library. For the bootstrap 3 theme this is the case. Otherwise, get it here: https://jquery.com/download/ and rename it appropriately. Colorbox also needs a css file defining its look and some images for displaying control icons. The repository we just downloaded has a few examples with different designs you can use right away. They all look fancy, so I decided to use one of them. So let’s copy these files to our pelican theme as well:

~/blog/colorbox$ cp example1/colorbox.css ~/blog/themes/pelican-bootstrap3/static/css
~/blog/colorbox$ cp -a example1/images/ ~/blog/themes/pelican-bootstrap3/static/css

When creating the site, pelican will now copy our files to the corresponding place in the output folder along with the other files.

The javascript code is now theoretically available. In practice it is not loaded yet. The same goes for the css file which is not referenced anywhere. We can change that by editing base.html in the templates/ folder of our currently used pelican theme. This is where all the core definitions of our template are made. These are included in all other, more specific, template files that extend this base template.

~/blog/themes/pelican-bootstrap3/templates$ vi base.html

Somewhere between the <head> and </head> tag, add the following line to reference to our .css file:

<link href="{{ SITEURL }}/{{ THEME_STATIC_DIR }}/css/colorbox.css" rel="stylesheet">

Inside the <body> and </body> tag and as close to the end of the file as possible make sure to add this:

<script src="{{ SITEURL }}/{{ THEME_STATIC_DIR }}/js/jquery.min.js"></script>
<!-- Make sure jquery is loaded first, then load colorbox -->
<script src="{{ SITEURL }}/{{ THEME_STATIC_DIR }}/js/jquery.colorbox-min.js"></script>
<script src="{{ SITEURL }}/{{ THEME_STATIC_DIR }}/js/load-colorbox.js"></script>

The first line loads jQuery while the second line loads the colorbox script. The third line includes another file that we will create next. It will define how colorbox recognizes which links to deal with.

~/$ vi ~/blog/themes/pelican-bootstrap3/static/js/load-colorbox.js

Now add the following content and save it:

$('#content').find('.mybox').colorbox({ 
maxWidth:"90%",
maxHeight:"90%",
transition:"fade",
scrolling: false });

With this, we create a CSS selector that identifies all elements that we want to call the colorbox function on. Selectors enable you to target specific html (or possibly other) elements on a site. In other words: which links to pictures (or possibly other files) do we want to be opened up in a lightbox? With #content we define the section id closest to our image. The find('.mybox') function then searches for a class with a name equal to ‘mybox’. We will add this class name to all links that we want displayed in our lightbox with a simple trick later on. So when a link surrounding a picture is clicked on colorbox opens up the link! Inside the colorbox() function we set a few options that define how colorbox behaves. That’s it, we are done implementing the colorbox plugin in pelican.

Defining which pictures to load with colorbox in Markdown

As mentioned above, links that should be treated by colorbox must carry the ‘mybox’ class. We need to use a little trick in order to be able to add that class definition. One way would be to use plain html, but that defies the intention of Markdown somehow. Luckily, my version of Markdown (2.6.8) seems to support a syntax that I only expected to work with Kramdown. Namely, you can use { } to add additional attributes to elements. Consequently, we can now use our method from above with a little addition: [![my_image](/img/my_image.png)](/img/my_image.png "Title that is displayed on mouse-over and as caption in colorbox"){class="mybox"}

Knowing how easy it is to add attributes, we can now also implement a thumbnail-like solution. For that, we add a width= attribute to the image. The whole line now reads: [![my_image](/img/my_image.png){:width=300px}](/img/my_image.png "Title that is displayed on mouse-over and as caption in colorbox"){class="mybox"}. And here is the final result:

Düsseldorf Carnival
Figure 1. Düsseldorf Carnival [Citanova (Düsseldorf Karneval 2013), via Wikimedia Commons]