Sign In/My Account | View Cart  
advertisement


Listen Print

An AxKit Image Gallery

Introducing AxKit

by Barrie Slaymaker
September 24, 2002

AxKit is not limited to working with pure XML data. Starting with this article, we'll work with and around non-XML data by developing an image browser that works with two types of non-XML data: a directory listing built from operating system calls (file names and statistics) and image files. Furthermore, it will be built from small modules that you can adapt to your needs or use elsewhere, like the thumbnail generator or the HTML table wrapper.

By the time we're done, several articles from now, we'd like an application that:

  • provides navigation around a tree of directories containing images,
  • displays image galleries with thumbnails,
  • ignores nonimage files,
  • allows you to define and present a custom set of information ("meta data") about each image,
  • allows you to view the complete images with and without metadata,
  • uses a non-AxKit mod_perl handler to generate thumbnail images on the fly, and
  • allows you to edit the metadata information in-browser

That feature list should allow us to build a "real world" application (rather than the weather examples we've discussed so far), and hopefully a useful one as well. Here's a screenshot of the page created by this article and the next:

Example page.

That page has four sections:

  1. Heading: Tells you where you are and offers navigation up the directory tree.
  2. Folders: links to the parent directory and any sub folders (Jim and Mary).
  3. Images: offers a thumbnail and caption area for each image. Clicking on an image or image title takes you to the full-size variant.
  4. Footer: A breadcrumbs display for getting back up the directory tree after scrolling down through a large page of images.

We'll implement the (most challenging) third section in this article and the other section in the next article.

If you want to review the basics of AxKit and Apache configuration, then here are the previous articles in this series:

Working with non-XML data as XML

The easiest way to actually work with non-XML data in AxKit is to turn it in to XML often and feed it to AxKit. AxKit itself takes this approach in its new directory handling feature -- thanks to Matt Sergeant and Jörg Walters AxKit can now scan the directory and build an XML document with all of the data. This is a lot like what native Apache does when it serves up an HTML directory listing, but it allows you to filter it. The main part of this article is about filtering this directory listing in order to create a gallery, or proofsheet, of thumbnail images.

In This Series

Introducing AxKit
The first in a series of articles by Barrie Slaymaker on setting up and running AxKit. AxKit is a mod_perl application for dynamically transforming XML. In this first article, we focus on getting started with AxKit.

XSP, Taglibs and Pipelines
Barrie explains what a "taglib" is, and how to use them to create dynamic pages inside of AxKit.

Taglib TMTOWTDI
Continuing our look at AxKit tag libraries, Barrie explains the use of SimpleTaglib and LogicSheets.

In this case, we'll be using a relatively recent addition to AxKit's standard toolkit, SAX Machines, integrated in to AxKit thanks to Kip Hampton. (disclaimer: XML::SAX::Machines is a module I wrote.) The SAX machine we'll create will be a straight pipeline with a few filters, a lot like the pipelines that AxKit uses. This pipeline will dissect directory listings and generate a list of images segmented into rows for easy display purposes. We don't get in to the details of SAX or SAX machines except to bolt together three building blocks; all of the gory details are handled for us by other modules. If you are interested in the gory details, then see Part One and Part Two of Kip's article "Introducing XML::SAX::Machines" on XML.com.

After the SAX machine builds our list of images, XSLT will be used to merge in metadata (like image titles and comments) from independant XML files and format the result for the browser. The resulting pages look like:

Managing non-XML data (the images)

On the other hand, it doesn't make sense to XMLify raw image data (though things like SVG--covered in XML.com's Sacre SVG articles--and dia files are a natural fit), so we'll take advantage of AxKit's integration with Apache and mod_perl to delegate image handlng to these more suitable tools.

This is done by using a distinctive URL for thumbnail image files and a custom mod_perl handler, My::Thumbnailer to convert full-size images to thumbnails. Neither AxKit nor mod_perl code will be used to serve the images, that will be left to Apache.

Thumbnails will be autogenerated in files with the same name as the main image file with a leading period (".") stuck on the front. In Unix land, this indicates a hidden file, and we don't want thumbnails (or other dotfiles) showing up in our gallery pages.

My::Thumbnailer uses the relatively new Imager module by Arnar M. Hrafnkelsson and Tony Cook. This is a best-of-breed module that competes with the likes of the venerable GD, the juggernaut Image::Magick, and Graphics::Libplot). Imager is gaining a reputation for speed, quality and a full-featured API.

The .meta file

Before we delve in to the implementation, let's look at one of the more subtle points of this design. Our previous examples have all been of straight pipelines that successively process a source document into an HTML page. In this application, however, we'll be funneling data from the source document and a collection of related files we'll call meta files.

This subtlety is not apparent from the screenshot, but if you look closely you can see that the caption for the first image ("A baby picture") contains more information than the captions for the other eight. This is because the first image has a meta file that contains a title and a comment to be displayed while the others don't (though they could).

The first image ("A baby picture") is from a file named a-look.jpeg, for which there is a meta file named a-look.meta in the same directory that looks like (bold shows the data that ends up getting sent to the browser):

    <meta>
      <title>A baby picture</title>
      <comment>
        <b>ME!</b>.  Well, not really.  Actually, it's some
        random image from the 'net.
      </comment>
    </meta>

An important feature of this file is that its contents and how they are presented within the caption area are completely unspecified by the core image gallery code. This makes our image gallery highly customizable: the site designer can determine what meta information needs to be associated with each image and how that information gets presented. Data can be presented in the thumbnail caption, in the expanded view, or used for nondisplay purposes.

Here's what's in each caption area:

  1. The title. If a .meta file is found for an image and it has a nonempty <title> element, then it is used as the name, otherwise the image's filename is stripped of extensions and used.
  2. The last modified time of the image file (in server-local time, unfortunately).
  3. A comment (optional): if a .meta file has a <comment> element, including XHTML markup, it is displayed.

Why a .meta file per image instead of one huge file? It will hopefully allow admins to manage images and meta files together and to allow us to access an image's meta information in a single file, a natural thing to do in AxKit. By having a pair of files for each image, you can use simple filesystem manipulations to move them around, or use filesystem links to make an image appear in multiple directories, perhaps with the same meta file, perhaps with different ones. This way we don't need to develop a lot of complex features to get a lot of mileage out of our image gallery (though we could if need be).

The Pipeline

No AxKit implementation documentation would be complete without detailing the pipeline. Here is the pipeline for the image proofsheet page shown above (click on any of the boxes to take you to the discussion about that portion of the pipeline, click on any of the miniature versions of this diagram to come to this one):

The AxKit pipeline for the image gallery application, take 1
The <filelist> document generated by AxKit My::Filelist2Data. Converts the <filelist> to a Perl data structure My::ProofSheet.  Takes the Perl data structure and generates a list of images with some metadata XML::Filter::TableWrapper.  Segments the list of images in to rows suitable for use in an HTML <table> My::ProofSheetMachine.  A SAX machine containing 3 SAX filters rowsplitter.xsl.  Converts each row of thumbnail metadata in to two rows, one for images, the other for captions metamerger.xsl.  Adds in the external .meta files, if they exist .meta files for the images captionstyler.xsl.  Converts the captions to XHTML pagestyler.xsl.  Converts the main part of the page to XHTML the final output The blue documents are content: the directory listing, the meta files and the generated HTML. This does not show the image processing, see My::Thumbnailer for that.

In this case, unlike our previous pipelines, data does not flow in a purely linear fashion: The directory listing from AxKit (<filelist>) feeds the pipeline and is massaged by three SAX filters and then by four XSLT filters. There are so many filters because this application is built to be customizable by tweaking specific filters or by adding other filters to the pipeline. It also uses several SAX filters available on CPAN to make life much easier for us.

In actual use, you may want to add more filters for things like branding, distinguishing groups of images by giving directory heirarchies different backgrounds or titles, adding ad banners, etc.

Here's a brief description of what each filter does, and why each is an independant filter:

  • My::ProofSheetMachine is a short module that builds a SAX Machine Pipeline. SAX filters are used in this application to handle tasks that are more suited to Perl than to XSLT or XSP:
    • My::FileList2Data is another short module that uses the XML::Simple module from CPAN to convert the <filelist> in to a Perl data structure that is passed on. This is its own filter because we want to customize XML::Simple and the resulting data structure a bit before passing it on.
    • My::ProofSheet is the heart of the gallery page generation. It builds a list of images from the filelist data structure and adds information about the thumbnail images and meta files.
    • XML::Filter::TableWrapper is a module from CPAN that is used to wrap a possibly lengthy list of images into rows of no more than five images each.
  • rowsplitter.xsl takes each row of images and makes it into two table rows: one for the images and one for the captions. This is easier to do in XSLT than in SAX, so here is where we shift from SAX processing to XSLT processing.
  • metamerger.xsl examines each caption to see if My::ProofSheet put the URL for a meta file in it. If so, it opens the meta file and inserts it in the caption. This is a separate filter because the site admin may prefer to write a custom filter here to integrate meta information from some other source, like a single master file or a centralized database.
  • captionstyler.xsl looks at each caption and rewrites it to be XHTML. This is a separate filter for two reasons: it allows the look and feel of the captions to be altered without having to mess with the other filters and, because it is the only filter that cares about the contents of the meta file, the site admin can alter the schema of the meta files and then alter this filter to match.
  • pagestyler.xsl converts everything outside of the caption elements in to HTML. It is separate so that the page look and feel can be altered per-site or per-directory without affecting the caption content, etc.

There are several key things to note about this design. The first is that the separation of the process into multiple filters offers the administrator the ability to modify the site's content and styling. Second, because AxKit is built on Apache's configuration engine, which filters are used for a particular directory request can be selected based on URL, directory path, query string parameters, browser types, etc. The third point to note is the use of SAX processors to handle tasks that are easier (far easier in some cases) to implement in Perl, while XSLT is used when it is more (programmer and/or processor) efficient.

Pages: 1, 2, 3, 4

Next Pagearrow