NAME

Image::Shoehorn::Gallery - generate "smart" HTML slideshows from a directory of image files.

SYNOPSIS

 use Image::Shoehorn::Gallery;

 Image::Shoehorn::Gallery->create({
   	 	                   directory   => "/htdocs/images",
		                   url         => "http://mysite.com/images",
		                   static      => 1,
		                   scales      => [
				                   [ "thumb","75x50" ],
				                   [ "small","25%"   ],
				                   [ "medium","50%"  ],
				                ],
                                   iptc        => ["headline","caption/abstract"],
                                   maxdepth    => 0,
                                   set_styles  => {
                                                  image => [
                                                            {title=>"my css",href=>"/styles.css"},
                                                           ],
                                                 },
                                   set_index_images => { default => 1 },
    		                  });

DESCRIPTION

Image::Shoehorn::Gallery generates HTML slideshows from a directory of image files. But wait, there's more!

Image::Shoehorn uses XML::Filter::XML_Directory_2XHTML, XML::SAX::Machines and a small army of Image::* packages allowing you to :

  • Create one, or more, scaled versions of an image, and their associate HTML pages. Scaled version may also be defined but left to be created at a later date by Apache::Image::Shoehorn.

    Associate HTML are always "baked", rather than "fried" (see also : http://www.aaronsw.com/weblog/000404 )

  • Read a user-defined list of IPTC and EXIF metadata fields from each image and include the data in the HTML pages.

  • Generate named indices and next/previous links by reading IPTC "headline" data.

  • Define one, or more, SAX filters to be applied to "index" and individual "image" documents before they are passed the final XML::SAX::Writer filter for output.

    The default look and feel of the gallery pages is pretty plain, but you could easily define a "foofy design" XSL stylesheet to be applied with the XML::Filter::XSLT SAX filter:

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                    version = "1.0" >
    
     <xsl:template match = "/">
     <html>
      <xsl:copy-of select = "html/head" />
      <body>
    
       <!-- lots of foofy design stuff -->
       <xsl:copy-of select = "/html/body/*" />
       <!-- lots of foofy design stuff -->
    
      </body>
     </html>
     </xsl:template>
    
    </xsl:stylesheet>
  • Generates valid XHTML (strict) and CSS!

PACKAGE METHODS

__PACKAGE__->create(\%args)

This is the magic spell that will create your galleries.

Valid arguments are :

  • directory

    String.

    The path on your file system where your images are kept.

    Required

  • url

    String.

    The URL that maps to directory on your webserver.

    Required

  • maxdepth

    Int.

    The maximum number of sub directories to munge and render.

  • static

    Boolean.

    Used in conjunction with the scales option for generating scaled versions of an image and their URLs.

    If false, or not defined, the package will assume that you have configured Apache::Image::Shoehorn to generate scaled versions of an image.

    If true, then the package will output image URLs that map to static images on the filesystem and ask Image::Shoehorn to create the new files, or update existing ones.

    Note, however, that the "thumb" (thumbnail) image will be generated regardless of whether or not you are using Apache::Image::Shoehorn. This is actually a feature since you would peg your machine having to create all those thumbnails the first time you loaded an especially large index page.

  • scales

    Array reference containing one, or more, array referece.

    Each of the child arrays should contain (2) elements :

    • name

      A name like "small" or "medium". This name is used as part of the naming scheme for images that have been scaled and their associate HTML pages.

      Names can be pretty much anything you'd like, although the name "thumb" is expected to be used for thumbnails.

    • scale

      These are required whether or not you are going to be generate static images. Even if you are going to render your images on the fly using Apache::Image::Shoehorn, the HTML spec (hi Karl) mandates that you provide height and widgth attributes for your img elements. So...

      Takes arguments in the same form as Image::Shoehorn which are, briefly :

      • n%

      • nxn

      • xn

      • nx

      You must atleast define a "thumb" scale.

  • iptc

    Array reference.

    A list of IPTC fields to read from an image. Fields are presented in the order they are defined.

    For a complete list of IPTC fields, please consult the Image::IPTCInfo.

  • exif

    Array reference.

    A list of EXIF fields to read from an image. Fields are presented in the order they are defined.

    For a complete list of EXIF fields, please consult http://www.ba.wakwak.com/~tsuruzoh/Computer/Digicams/exif-e.html

  • set_styles

    Hash reference.

    Used to override the default CSS for either and "index" page or an individual "image" page.

    Valid hash keys are :

    • index

    • image

    Where each key expects an array ref of hash refs whose keys are :

    • href

    • title

      Default is ""

    • rel

      Default is "stylesheet"

    • media

      Default is "all".

    Styles will be added in the order that they are defined in the array ref.

    The default CSS styles are outlined below.

  • set_filters

    Hash reference

    Define one or more additional filters to be applied to either an "index" or individual "image" page.

    Valid hash keys are :

    • index

    • image

    Filters are applied last, before events are finally handed off to XML::SAX::Writer and in the order that they are defined.

    Example:

    package MySAX;
    use base qw (XML::SAX::Base);
    
    sub start_element {
       my $self = shift;
       my $data = shift;
    
       $self->SUPER::start_element($data);
    
       if ($data->{Name} eq "body") {
          $self->SUPER::start_element({Name=>"h1"});
          $self->SUPER::characters({Data=>"hello world"});
          $self->SUPER::end_element({Name=>"h1"});
       }
    }
    
    package main;
    
    # The following will add <h1>hello world</h1>
    # at the top of all your 'image' pages. Woot!
    
    use Image::Shoehorn::Gallery;
    Image::Shoehorn::Gallery->create({
                                      # ...
    
                                      set_filters => { image => [ MySAX->new() ]},
                                     });
  • set_index_images

    Hash reference.

    Define images to associate with files in a directory listing. Valid keys are :

    • image

      Image to associate with a file whose media type is "image"

      Default is to generate and include a thumbnail, as defined by the "thumb" scale option (see above.)

    • directory

      Image to associate with a directory.

    • file

      Image to associate with a file whose media type is not "image"

      Example :

       # Use the default Apache icons
      
       my %images = (
      	       directory => {
      			     src    => "/icons/dir.gif",
      			     height => "20",
      			     width  => "20",
      			     alt    => "ceci n'est pas un dossier",
      			    },
      	       file => {
      			src    => "/icons/unknown.gif",
      			height => "20",
      			width  => "20",
      			alt    => "ceci n'est pas un fichier",
      		       },
      	       );
      
       Image::Shoehorn::Gallery->create({
      				   # ...
      				   set_index_images => \%images,
      				  });
    • default

      Boolean.

      This is just a shortcut to use the default image handler and the handlers for files and directories example described above.

      If you are not using Apache for your web server and/or have not aliased the Apache icons folder to /icons, it won't do you much good.

    Valid keys arguments are either :

    • hash reference

      Containing key/value pairs for the following image attributes :

      • src

      • height

      • width

      • alt

    • code reference

      The code reference will be passed the absolute path of the current image and is expected to return a hash reference similar to the one described above.

    This is an XML::Filter::XML_Directory_2XHTML-ism. Please consult docs for further details.

  • set_encoding

    String.

    Default is "UTF-8"

  • force

    Int.

    By default neither the scaled version of an image, nor the associate HTML files, will be created unless the source image has a more recent modification date.

    You can use this option to override this check.

    If the value is greater than zero, HTML files will be regenerated.

    If the value is greater than one, images and HTML files will be regenerated.

  • verbose

    Boolean.

NAMING CONVENTIONS

Let's say you've got an image named :

20020603-my-new-toy.jpg

You've defined two "views" to be generated : small and medium. The following files will be created :

20020603-my-new-toy.html
20020603-my-new-toy-thumb.jpg **
20020603-my-new-toy-small.jpg *
20020603-my-new-toy-small.html
20020603-my-new-toy-medium.jpg *
20020603-my-new-toy-medium.html

*  If you are rendering scaled images on the fly, with I<Apache::Image::Shoehorn>, 
   these files not be created until such a time as they are actually viewed

** Thumbnails are always generated, regardless of the I<static> flag. As mentioned 
   earlier, this is a feature. If you have a directory with many images, you will peg
   your web server the first time you have to render all those images for the index
   listing.

The package uses XML::Filter::XML_Directory_2XHTML which, a few steps up the inheritance tree, uses XML::Filter::XML_Directory_Pruner to exclude certain specific files from the directory (index) listing. The exact rule set currently used it :

  $xhtml->exclude(
		  starting => ["\\."],
		  ending   => ["html","tmp","~"],
		  # e.g. ending with "-thumb.jpg","-small.jpg" or "-medium.jpg"
		  matching => ["^(.*)-(".join("|","thumb",@{$views}).")\.([^\.]+)\$"],
		 );

The plan is to, eventually, teach XML::Filter::XML_Directory_Pruner to include and exclude widgets based on media type, at which point we could simply do :

$xhtml->include( media => "image" );

But until then, it is recommended that you make sure your source images don't match the "matching" pattern describe above. Or if you just think I'm an idiot and have a better rule-set, send my a note and I'll probably include it.

CSS

The following CSS classes are defined for the HTML generated by the package.

They are provided as a reference in case you want to specify your own CSS stylesheet.

"index" page

.directory {
            margin-bottom:5px;
            clear:left;
          }

.file      {
            margin-bottom:5px;
            clear:left;
          }

.thumbnail {
            display:block;
            width:100px;float:left;
          }

.file ul   { 
            float:left;
          }

"image" page

 .menu {
        margin-bottom:5px;
        padding:5px;
 }

 .menu-link-previous {
		padding-right : 10px;
 }

 .menu-link-previous img {
		margin-right:15px;
 }

 .menu-link-index {
		   font-weight:600;
                  }

 .menu-link-next {
		  padding-left : 10px;
                 }

 .menu-link-next img {
		     margin-left:15px;
 }

 .content {
          padding-top:20px;
         }

 .image { 
        position:absolute;
        top:auto;
        right:auto;
        left:170px;
        bottom:auto;
 }

 .meta { 
        min-width:150px;
        max-width:150px;
 }  

 .links {
        border: solid thin;
        margin-bottom: 5px;
 }

 .links span {
        display:block;
	padding:3px;
 }

 .iptc { 
        background-color : #fffff0;
        border-top: solid thin; 
        border-left: solid thin;
        border-right: solid thin;
        margin-bottom : 5px;
      }

 .iptc span { 
        display:block; 
        padding:3px;
        border-bottom:solid thin;
 }

 .iptc-field { 
        background-color : #f5f5dc;
        color:#a52a2a;
        border-bottom:solid thin #000;
        }

 .exif { 
        background-color : #f5f5dc;
        border-top: solid thin; 
        border-left: solid thin; 
        border-right: solid thin; 
        margin-bottom : 5px; 
        }

 .exif span { 
        display:block; 
        padding:3px;
        border-bottom:solid thin;
 } 

 .exif-field { 
        color:#a52a2a;
        background-color:#cccc99;
        border-bottom:solid thin #000;
        }

VERSION

0.1

AUTHOR

Aaron Straup Cope

DATE

July 25, 2002

TO DO

  • Add links to "parent" directory, where appropriate; need to determine whether or not this is a XML::Filter::XML_Directory_2XHTML thing.

  • Figure out why I keep getting errors when I try passing STYLESHEET::DATA (or copies of it) to the XSLT munger.

  • Set/get config options using closures.

  • Add hooks to read a conf file - this allow involves hacking Apache::Image::Shoehorn so that it can also read the same conf file

  • Add hooks for generating slides from a "virtual" directory; specifically a list of disparate files.

  • Add hooks for supporting XML::Filter::Sort

  • Consider interactive option that would prompt user for IPTC data as files are being processed.

SEE ALSO

http://www.la-grange.net/2002/07/22.html

http://aaronland.info/weblog/archive/4474

http://perl.aaronland.info/image/shoehorn/gallery/www/example/index.html

REQUIREMENTS

XML::Filter::XML_Directory_2XHTML

XML::Filter::XSLT

XML::SAX::Machines

XML::SAX::Writer

Image::Shoehorn

Image::IPTCInfo

Image::Info

Digest::MD5

LICENSE

Copyright (c) 2002, Aaron Straup Cope. All Rights Reserved.

This is free software, you may use it and distribute it under the same terms as Perl itself.