| Category: | CGI Applications |
| Author/Contact Info | /msg LTjake |
| Description: | This is a pretty simple Photo Gallery using CGI::Application and HTML::Template. Files are simply stored in directories (and don't have to be stored off the document root) and a file with the same name and a .txt entension supplies a caption for said photo. Templates can be modified to suit your purpose. Requires the following modules: CGI::Application, GD (and libs for each format you want supported), and File::Basename |
| This is "for fun" code. Don't run a nuclear powerplant with it or anything =). Any fixes/modifications are welcome and encouraged! (Note: This script has only been tested on a Linux box...) Special thanks to jeffa, vladb, petruchio and jcwren for their help. As far as I can remember, all of the HTML produced is valid XHTML 1.0 Transitional code. Photo directories are the category titles. Ex: /photos/my_baby_pictures results in "my_baby_pictures" being the category title. Instance Script (index.cgi): Put this somewhere off of your document root. example: {Document Root}/photos/index.cgi --- #!/usr/bin/perl -w
# Location of the ImageGallery.pm module
# (if not in the current path)
use lib '/path/to/modules';
use ImageGallery;
my $webapp = ImageGallery->new
(
# Location of templates.
TMPL_PATH => '/path/to/templates/',
PARAMS =>
{
# Full path to images
photos_dir => '/path/to/photos',
# Thumbnail size (s, m or l)
thumb_size => 'm',
# Number of thumbnails per row
thumbs_per_row => 4,
script_name => $0
}
);
$webapp->run();
Main gallery template (photos_index.tmpl): Put this in your templates directory (specified in the instance script) --- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http:/ +/www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <title><TMPL_VAR NAME="title"></title> <meta http-equiv="content-type" content="text/html; charset=iso-88 +59-1" /> </head> <body> <center> <table> <TMPL_LOOP NAME="dir_row"> <tr> <th colspan="5" bgcolor="#E0E0E0"><font size="+3"><TMPL_VA +R NAME="dir"></font></th> </tr> <TMPL_LOOP NAME="file_row"> <tr> <TMPL_LOOP NAME="images"> <TMPL_IF NAME="filename"> <td bgcolor="#F5F5F5"><a href="<TMPL_VAR NAME="script_name +">?r=1&i=<TMPL_VAR NAME="filename">"><img border="0" src="<TMPL_V +AR NAME="script_name">?r=1&i=<TMPL_VAR NAME="filename">&<TMPL +_VAR NAME="thumb_size">" alt="<TMPL_VAR NAME="alt">" /></a></td> <TMPL_ELSE> <td bgcolor="#F5F5F5"> </td> </TMPL_IF> </TMPL_LOOP> </tr> </TMPL_LOOP> <TMPL_UNLESS NAME="__LAST__"> <tr> <td><br /></td> </tr> </TMPL_UNLESS> </TMPL_LOOP> </table> </center> </body> </html> Single photo template (photos_single.tmpl): Put this in your templates directory as well. --- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http:/ +/www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <title><TMPL_VAR NAME="title"></title> <meta http-equiv="content-type" content="text/html; charset=iso-88 +59-1" /> </head> <body> <table width="100%" height="100%"> <tr><td align="center" valign="middle"> <table> <tr> <th><img border="0" src="<TMPL_VAR NAME="script_name">?r=1 +&i=<TMPL_VAR NAME="filename">&f" alt="<TMPL_VAR NAME="alt">" +width="<TMPL_VAR NAME="width">" height="<TMPL_VAR NAME="height">" />< +/th> </tr> <TMPL_IF NAME="caption"> <tr> <td bgcolor="#F5F5F5" align="center"><TMPL_VAR NAME="capti +on"></td> </tr> </TMPL_IF> </table> </td></tr> </table> </body> </html> Main image gallery script (ImageGallery.pm): Put this in your modules directory (specified in the instance script) --- package ImageGallery;
use base 'CGI::Application';
use File::Basename;
use GD;
use strict;
sub setup
{
my $self = shift;
$self->run_modes
(
'0' => 'show_gallery',
'1' => 'show_image',
'AUTOLOAD' => 'show_gallery'
);
$self->start_mode('0');
$self->mode_param('r');
}
sub show_gallery
{
my $self = shift;
my $row_limit = $self->param('thumbs_per_row');
my %ok_ext = map { $_ => 1 } qw(jpg gif png);
my $image_dir = $self->param('photos_dir');
my @dir_row;
while(my $dir = <$image_dir/*>)
{
next unless -d $dir;
my $dir_row = {dir => substr($dir, length($image_dir) + 1)};
my ($i, $j) = (0, 0);
while (my $full = <$dir/*>)
{
my ($file, $ext) = (fileparse($full,keys %ok_ext))[0,2];
next unless $ok_ext{$ext};
push @{$dir_row->{file_row}->[$j]->{images}}, { filename =
+> substr($full, length($self->param('photos_dir'))), alt => $file };
$j++ unless ++$i % $row_limit;
}
for ($i = $i; $i % $row_limit; $i++)
{
push @{$dir_row->{file_row}->[$j]->{images}}, { filename =
+> '', alt => '' };
}
push @dir_row, $dir_row;
}
my $html = $self->load_tmpl('photos_index.tmpl', global_vars => 1)
+;
$html->param(script_name => $self->param('script_name'));
$html->param(thumb_size => $self->param('thumb_size'));
$html->param(title => 'My Photo Gallery');
$html->param(dir_row => \@dir_row);
return $html->output;
}
sub show_image
{
my $self = shift;
my $q = $self->query();
my $image = GD::Image->new($self->param('photos_dir') . $q->param(
+'i'));
my $newimage;
if (defined($q->param('l')))
{
$newimage = resize_image(150, $image);
}
elsif (defined($q->param('m')))
{
$newimage = resize_image(100, $image);
}
elsif (defined($q->param('s')))
{
$newimage = resize_image(50, $image);
}
elsif (defined($q->param('f')))
{
my $type = substr($q->param('i'), length($q->param('i')) - 3);
if ($type eq 'jpg')
{
$self->header_props({-type=>'image/jpeg'});
return $image->jpeg;
}
elsif ($type eq 'png' || $type eq 'gif')
{
$self->header_props({-type=>'image/png'});
return $image->png;
}
}
else
{
my ($width, $height) = $image->getBounds();
my $html = $self->load_tmpl('photos_single.tmpl', global_vars
+=> 1);
$html->param(script_name => $self->param('script_name'));
$html->param(title => 'My Photo Gallery');
$html->param(filename => $q->param('i'));
$html->param(alt => $q->param('i'));
$html->param(width => $width);
$html->param(height => $height);
my $file = $self->param('photos_dir') . substr($q->param('i'),
+ 0, length($q->param('i')) - 4);
open (FH, "<$file.txt");
local $/ = undef;
$html->param(caption => <FH>);
close FH;
return $html->output;
}
$self->header_props({-type=>'image/png'});
return $newimage->png;
}
sub resize_image
{
my $newsize = shift;
my $image = shift;
my ($width, $height) = $image->getBounds();
my $image2 = new GD::Image($newsize, $newsize);
$image2->transparent($image2->colorAllocate(0,0,0));
if ($width > $height)
{
$image2->copyResized($image, 0, int((($newsize - int(($height
+* $newsize / $width) + 0.5)) / 2) + 0.5), 0, 0, $newsize, int(($heigh
+t * $newsize / $width) + 0.5), $width, $height);
}
elsif ($width < $height)
{
$image2->copyResized($image, int((($newsize - int(($width * $n
+ewsize / $height) + 0.5)) / 2) + 0.5), 0, 0, 0, int(($width * $newsiz
+e / $height) + 0.5), $newsize, $width, $height);
}
else
{
$image2->copyResized($image, 0, 0, 0, 0, $newsize, $newsize, $widt
+h, $height);
}
return $image2;
}
1;
|
|
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Photo Gallery using CGI::Application and HTML::Template
by samtregar (Abbot) on Jul 06, 2002 at 21:25 UTC | |
by LTjake (Prior) on Jul 07, 2002 at 19:41 UTC |