Introduction
Octopress does a good job of generating a blog that scales nicely for large computer screens and smaller devices (such as my iPad). However, it’s possible to thwart Octopress’s best intentions, as I inadvertently managed to do.
I occasionally post cartoons to my blog, and the images tend to be large enough that they flow outside the boundaries of the blog’s text area, which looks like crap. My first attempt at solving the problem was to use CSS to set a minimum size for the text region. That solution, however, ruins the blog layout for smaller devices, such as a tablet.
There’s a straightforward solution to this problem, though.
The general idea is to display a smaller version of the image in the text area; when a reader clicks on that image (or taps it, on the iPad), the full size image appears in a modal popup. Many sites use this approach, of course, including Facebook and Google+. Its popularity is part of its appeal.
This solution can be implemented in a simple plugin, making it easy to drop into individual blog articles.
Prerequisites
Since I am already using jQuery and jQuery UI elsewhere in my blog, I elected to use them to solve this problem, as well. Here’s the full set of extra software necessary to write the plugin:
- jQuery UI: I use jQuery UI Dialog to generate the popup containing the full size image.
- jQuery: Necessary for jQuery UI.
- The mini_magick Ruby Gem, used to query the image file to get its size. The plugin could use mini_magick to scale the image down, but it’s just as easy to let the browser do the scaling.
- Either ImageMagick or GraphicsMagick, because mini_magick uses the mogrify(1) command to do its work.
- Erubis, for fast ERB template processing. (You can just use ERB, itself, if you want.)
I could have used the RMagick gem, instead of mini_magick and mogrify(1), but RMagick uses a lot of memory on my machine.
The Plugin
Usage
The plugin implements a Liquid template tag. The tag syntax is straighforward:
1
|
|
The image path is relative to the source
directory. The percent argument is
the amount to scale the image down for the clickable preview. The optional
title is put in the title bar of the modal popup. Here’s a real example:
1
|
|
Implementation
The plugin, itself, is not large at all. It consists three distinct parts:
- An ERB template for the HTML and Javascript that will be emitted.
- The initializer, which parses the arguments given to the tag.
- The
render
method, which actually generates the HTML and Javascript.
The Plugin Code
Two files comprise the plugin: The Ruby source code and an accompanying ERB template.
Here’s the Ruby code, which belongs in the plugins
directory. It’s also
available in my GitHub repository, at
https://github.com/bmc/brizzled/blob/master/plugins/img_popup.rb.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
|
Here’s the ERB template, stored in file img_popup.html.erb
, also in the
plugins
directory. The template could, of course, be in the Ruby file, but
I put it in a separate file, because I find it easier to maintain that way.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
|
A Quick Walkthrough
The ERB Template
The ERB template is fairly straightforward.
The template generates HTML that does several things. The initial <div>
displays the scaled-down version of the image. The scaled width and height are
passed to the template renderer, but the image is the full size image; the
browser will do the actual scaling. The image is surrounded by an anchor tag,
as a trivial means to make it clickable. That initial <div>
also
contains the hidden <div>
will be displayed in the popup. Note the
screen
class: This class is used by the CSS rules to suppress display of the
entire <div>
when the media type is print
.
Next is a <script>
tag containing the jQuery logic that sets up the
dialog and registers the click event that triggers the dialog’s display. For
details on the jQuery UI Dialog capability, see the jQuery UI Dialog web
page.
Finally, there’s one last <div>
, which the CSS rules ensure is the
one that’s displayed in print
mode.
The Ruby Part
The plugin’s logic consists of just two methods. The initializer is simple:
- It parses and validates the arguments to the tag, as passed in the
markup
parameter. - It instantiates an
Erubis::Eruby
instance on the ERB template, storing theEruby
object in an instance variable.
The renderer is also fairly straightforward:
- It calculates the location of the
source
directory and figures out where the image is underneath that directory. - It creates a new, unique ID, to be used for the generated HTML. This allows the plugin to generate multiple dialogs in one page, without causing problems.
- It gets the image’s width and height, and calculates the scaled width and height.
- It generates the resulting HTML, wrapping it with
safe_wrap
so that Jekyll doesn’t attempt to parse and transform it.
jQuery
Be sure to add the following two lines to source/_includes/custom/head.html
,
to make jQuery and jQuery UI available:
1 2 |
|
The CSS
The only thing missing is the CSS. In my Sass rules for the screen, I added these rules:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
For the printer-friendly Sass rules, I use:
1 2 3 4 5 6 7 |
|
Wrap-up
Finally, here’s an example of the plugin, using one of my photographs:

The actual, working code is located in this blog’s GitHub repo, here:
https://github.com/bmc/brizzled/blob/master/plugins/img_popup.rb.
Feel free to use the code, adapt it to your needs, or send me suggestions. It’s released under a BSD License.