Fozzologs

RSS Feeds

About...

These posts are the creation of Doran L. Barton (AKA Fozziliny Moo). To learn more about Doran, check out his website at fozzilinymoo.org.

Right Side

This space reserved for future use.

Polishing my family photo presentation with Perl

Posted: 26 September 2006 at 00:20:04

I thought I'd share a short demonstration of some very cool Perl technology.

About a week ago, I got back from taking my family on a short vacation to beautiful southern Utah. I documented our trip and posted copies of a few photos we took in the Events section of my website. You can read the Sept. Mini-Vacation page yourself.

In the past, when preparing images for publication on the web, I've either hand-coded the HTML -- usually a mess of table elements -- or I've used a homegrown shell script called buildgallery.sh that generates the HTML table code around a set of images. After generating the scaffolding of tabl code for the image organization, I'd go in and populate various cells with image captions, descriptions, and links to different sizes.

This works, but tables are ugly. CSS-only presentation is so much more elegant. Plus, it'd be better if I didn't have to jump around the HTML to populate the caption and description text for all the images.

Perl to the rescue!

I'm already using the Perl Template Toolkit to generate static pages for each page on my website. I use the ttree command at the command line on my staging server to generate the pages by "wrapping" the main content.

Since the page about our southern Utah vacation was just being fed to a template processing engine to generate a resulting HTML file, it made sense to use the power of the Perl Template Toolkit to generate the HTML around my gallery of images.

By the time I've gotten to this point, I've already run a shell script that uses ImageMagick's, uhm, magic, to create sensibly-sized thumbnail and web-friendly sized versions of each image. Those images are stored in files with .med and .thumb in the names before the filename extension.

For each group of images, I declared a data structure called images which is essentially an anonymous list of anonymous hashes. Each anonymous hash contains information about an image such as the base filename, image dimensions, title, and description text.

[% images = [
    {   basename    => "fiesta_fun-all_3-2",
        width       => 156,
        height      => 117,
        title       => "Our kids driving the kiddie-carts",
        description => "Maya, Lucy, and Eli on the kiddie-carts course."},
    {   basename    => "fiesta_fun-lucy_eli-4",
        width       => 156,
        height      => 117,
        title       => "Lucy and Eli",
        description => "Lucy and Eli on the kiddie-carts course."} ] %]

For those unfamiliar with the Perl Template Toolkit syntax, it is similar (but not too similar ;-)) to PHP or ASP in that template code can be embedded with HTML as long as each piece of template code begins with [% and ends with %]. This is, of course, overrideable -- You can change those start/end sequences to anything you want.

Next, I declared a block called doimage which takes one set of information about an image -- one hash from our list of hashes -- and generates HTML for it.

This BLOCK section only needs to be declared once in the file and could be placed in its own file for re-use later, if I chose to do so.

[% BLOCK doimage %]
    [% DEFAULT img_path = "images" %]
        <div class="picture">
            <div class="imagecontainer">
                <a href="[% img_path %]/[% img.basename %].med.jpg" target="_new">
                    <img width="[% img.width %]" height="[% img.height %]" 
                    src="[% img_path %]/[% img.basename %].thumb.jpg"
                    alt="[% img.title %]" 
                    title="[% img.title %]"/></a>
            </div>
            <div class="textcontainer">
                <div class="picture_caption">[% img.title %]</div>
                [% IF img.description %]
                <div class="picture_description">[% img.description %]</div>
                [% END %]
            </div>
            <div class="floatbreak"></div>
        </div>
[% END %]

It should be pretty obvious by looking at the code (unless you're reading from an RSS feed of this document, in which case, the above example will be all messed up) how the values of the individual hash elements are interpolated into the HTML.

Next, I need to loop through all the images by iterating through the list of hashes I declared earlier. For each one of these hashes, I want to process the information in the hash using the block I declared.

[% FOREACH img = images %]
     [% PROCESS doimage img_path = "images" %]
[% END %]

Finally, I dressed up the HTML by adding some properties to the stylesheet:

.picture {
margin: 5px;
margin-left: 20px;
border: solid #aaa 1px;
}
.imagecontainer {
text-align: center;
float: left;
width: 170px;
}
.picture img {
margin: 5px;
}
.textcontainer {
margin-left: 200px;
}
.textcontainer .picture_caption {
font-family: sans-serif;
font-size: large;
font-weight: bold;
}
.textcontainer .picture_description {
font-family: sans-serif;
font-size: medium;
font-weight: medium;
}
.floatbreak {
clear: both;
height: 0;
}

(A big shout-out of kudos to Tene for helping me with that CSS.)

In summary, I don't think I'll be using any shell scripts to build HTML table scaffolding around my simple image galleries anymore.

I've already thought of some ways to improve upon this. For example, I could use the Perl Template Toolkit's Image plugin to examine each image file and automagically extract information such as image dimensions, EXIF data, etc. as it iterates over the list of image information.