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.
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 implements a Liquid template tag. The tag syntax is straighforward:
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:
The plugin, itself, is not large at all. It consists three distinct parts:
- The initializer, which parses the arguments given to the tag.
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
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
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
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
<div> when the media type is
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
Finally, there’s one last
<div>, which the CSS rules ensure is the
one that’s displayed in
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
- It instantiates an
Erubis::Erubyinstance on the ERB template, storing the
Erubyobject in an instance variable.
The renderer is also fairly straightforward:
- It calculates the location of the
sourcedirectory 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_wrapso that Jekyll doesn’t attempt to parse and transform it.
Be sure to add the following two lines to
to make jQuery and jQuery UI available:
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
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:
Feel free to use the code, adapt it to your needs, or send me suggestions. It’s released under a BSD License.