Listings 16-1 to 16-19 contain the complete listings for the templates and the main programs.
Listing 16-1: generate.pl
01: #!/usr/bin/perl -w 02: # generate.pl 03: use strict; 04: use Image::Info qw(image_info dim); 05: use File::Basename; 06: use File::Find; 07: use File::Copy; 08: use Imager; 09: use DBI; 10: my $info; 11: my $album_name = shift || die "What album name?"; 12: my $album_id = time(); 13: ### Begin user modifications 14: my $relative_dir = "/photos"; 15: my $album_dir = "/var/www/html/photos"; 16: my @SIZES = qw(100 640 800); 17: ### End of user modifications 18: $album_name =~ s/ /\_/g; 19: $album_dir .= "/$album_name"; 20: my $rel_dir = "$relative_dir/$album_name"; 21: mkdir ($album_dir) || die "Can’t mkdir $!" unless –e $album_dir; 22: my $source_dir = shift(@ARGV)|| (‘.’); 23: my $dbh = DBI->connect("DBI:mysql:photoalbum","bookuser","testpass") 24: or die("Cannot connect: $DBI::errstr"); 25: my @EXIF = qw(width height resolution Flash Model 26: Make MaxApertureValue FNumber DateTime 27: ISOSpeedRatings ExposureTime FocalLength); 28: Add_Album(); 29: find({wanted => \&Wanted, follow => 1}, @ARGV); 30: print "\nDone generating new album...\n\n"; 31: sub Add_Album { 32: my $sql = qq{INSERT INTO album 33: (album_id, name, comments) 34: VALUES (?,?,?)}; 35: my $sth_album = $dbh->prepare($sql); 36: $sth_album->execute($album_id, $album_name, ‘’) 37: or die("ERROR! $DBI::errstr"); 38: } 39: sub Update_Database { 40: my $photo = shift; 41: my $p_dir = "$rel_dir/$photo"; 42: my $sql1 = qq{INSERT INTO photo 43: (img_id, width, height, resolution, flash, 44: model, make, aperture, fnumber, img_date, 45: iso_speed, exposure, focal_length, 46: img_title, img_location, album_id, comments) 47: VALUES 48: (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)}; 49: my $sth_photo = $dbh->prepare($sql1); 50: my $id = $info->{DateTime}; 51: $id =~ s/[ \:]//g; 52: $id .= time(); 53: $sth_photo->execute($id, @$info{@EXIF}, ‘untitled’, 54: $p_dir, $album_id, ‘’) 55: or die("ERROR! $DBI::errstr "); 56: print "Record inserted into database...\n"; 57: } 58: sub Massage_Data { 59: my @RATIONAL = qw(FNumber FocalLength); 60: for(@RATIONAL) { 61: $info->{$_} = Rational($info->{$_},1); 62: } 63: $info->{‘MaxApertureValue’} 64: = sprintf("%.1f", (1.4142 ** $info->{‘MaxApertureValue’})); 65: } 66: sub Rational { 67: my ($in, $dec) = @_; 68: my ($num, $denom) = split(‘/’, $in); 69: my $fmt = ‘%.’ . $dec . ‘f’; 70: return($denom == 0 ? "Err" : sprintf($fmt, $num/$denom)); 71: } 72: sub Img_Copy { 73: my $source_file = shift; 74: $source_file =~ /^([\w\-\/]+)\.(\w{1,4})$/; 75: my $dest_file = $1 . ‘.’ . $2; 76: copy($source_file, "$album_dir/" . basename($dest_file)) or die "Cannot copy $!"; 77: print "Done writing $dest_file...\n"; 78: } 79: sub Resize { 80: my ($file, $xfac) = @_; 81: my $extn; 82: my $img = Imager->new(); 83: $img->open(file => $file) or die $img->errstr(); 84: $file =~ /^([\w\-\/]+)\.(\w{1,4})$/; 85: $file = $1; 86: $file = basename($file); 87: $extn = $2; 88: $xfac =~ /^([\w]+)$/ || die "Oops!"; 89: $xfac = $1; 90: my $newimg = $img->copy(); 91: $newimg = $img->scale(xpixels => $xfac); 92: $newimg->write(file => "$album_dir/$file.$xfac.$extn") 93: or die $img->errstr(); 94: print "Done writing $file.$xfac.$extn...\n"; 95: } 96: sub Wanted { 97: if( (/\.jpg|\.jpeg$/i) ) { 98: my $file = $_; 99: $info = undef; 100: $info = image_info($File::Find::fullname); 101: die "Can’t parse image info: $info->{error}\n" 102: if($info->{error}); 103: for(@SIZES) { 104: Resize ($File::Find::fullname, $_); 105: } 106: Massage_Data (); 107: Img_Copy ($File::Find::fullname); 108: Update_Database ($file); 109: print "\n"; 110: } 111: }
Listing 16-2: index.cgi
01: #!/usr/bin/perl -wT 02: # index.cgi Photo Album Script 03: use strict; 04: use DBI; 05: use CGI qw(:standard); 06: use lib qw(.); 07: use BasicSession; 08: our $sess; 09: my %item; 10: $sess = Get_Session(); 11: tie %item, ‘BasicSession’; 12: my $album = param(‘album’); 13: my $photo = param(‘photo’); 14: my $size = param(‘size’); 15: my $sizes = Make_Sizes(qw(640 800 orig)); 16: $size ? ($item{‘size’} = $size) : ($size = $item{‘size’}); 17: my $dbh = DBI->connect("DBI:mysql:photoalbum","bookuser","testpass") 18: or die("Cannot connect: $DBI::errstr"); 19: if($photo) { 20: Show_Photo($photo, $album); 21: exit; 22: } 23: elsif($album) { 24: Show_Album($album); 25: exit; 26: } 27: else { 28: List_Albums(); 29: exit; 30: } 31: sub Make_Sizes { 32: my @sizes = @_; 33: my $string = ‘’; 34: for my $size (@sizes) { 35: $string .= 36: qq(<a href="?photo=$photo&album=$album&size=$size">$size</a> ); 37: } 38: return($string); 39: } 40: sub List_Albums { 41: my $sql = qq{SELECT * FROM album}; 42: my $sth = $dbh->prepare($sql); 43: $sth->execute(); 44: Print_Page("./templates", "header.tmpl"); 45: Print_Page("./templates", "list_top.tmpl"); 46: while(my $p = $sth->fetchrow_hashref){ 47: Print_Page("./templates", "list_row.tmpl", $p); 48: } 49: Print_Page("./templates", "list_end.tmpl"); 50: Print_Page("./templates", "footer.tmpl"); 51: } 52: sub Show_Album { 53: my $cols = 3; 54: my $sql_p = qq{SELECT * FROM photo WHERE album_id = ?}; 55: my $sql_a = qq{SELECT * FROM album WHERE album_id = ?}; 56: my $sth_p = $dbh->prepare($sql_p); 57: my $sth_a = $dbh->prepare($sql_a); 58: $sth_p->execute($album); 59: $sth_a->execute($album); 60: Print_Page("./templates", "header.tmpl"); 61: while(my $p = $sth_a->fetchrow_hashref){ 62: $p->{cols} = $cols; 63: Print_Page("./templates", "album_top.tmpl", $p); 64: } 65: my $counter = 1; 66: while(my $p = $sth_p->fetchrow_hashref){ 67: $p->{img_location} = get_image($p->{img_location}, 100); 68: print "<tr>" if($counter == 1); 69: Print_Page("./templates", "album_row.tmpl", $p); 70: print "</tr>" if($counter == $cols); 71: $counter++; 72: $counter = 1 if($counter > $cols); 73: } 74: print "</tr>" unless($counter == 1); 75: Print_Page("./templates", "album_end.tmpl",{‘cols’ => $cols}); 76: Print_Page("./templates", "footer.tmpl"); 77: } 78: sub Get_Photo_List { 79: my ($photo, $album) = @_; 80: my ($index, @photos); 81: my $count = 0; 82: my $sql = qq{SELECT img_id FROM photo WHERE album_id = ?}; 83: my $sth = $dbh->prepare($sql); 84: my @all; 85: $sth->execute($album); 86: while(my @tmp = $sth->fetchrow_array){push @all, $tmp[0];} 87: for(@all) { 88: $index = $count if(/$photo/); #Get index of photo we want 89: $count++; 90: } 91: unless($index) { 92: @photos = @all[0, 1]; 93: unshift @photos, ‘’; 94: } 95: else { 96: @photos = @all[($index-1)..($index+1)]; # Get photos next to it 97: } 98: return (@photos); 99: } 100: sub Show_Photo { 101: my ($photo, $album) = @_; 102: my @photos = Get_Photo_List($photo, $album); 103: my $ptr = Get_Details(@photos); 104: $ptr->{img_location} = get_image($ptr->{img_location}, $size); 105: $ptr->{image_sizes} = $sizes; 106: Print_Page("./templates", "header.tmpl"); 107: Print_Page("./templates", "photo_main.tmpl", $ptr); 108: Print_Page("./templates", "photo_footer.tmpl", $ptr); 109: } 110: sub Get_Details { 111: my @photos = @_; 112: my ($p, %tmp); 113: my %hsh = (‘prev’ => 0, ‘curr’ => 1, ‘next’ => 2); 114: my $sql1 = qq{SELECT img_id, img_location FROM photo WHERE img_id = ?}; 115: my $sql2 = qq{SELECT * FROM photo WHERE img_id = ?}; 116: my $sth1 = $dbh->prepare($sql1); 117: my $sth2 = $dbh->prepare($sql2); 118: for(keys %hsh){ 119: if(/curr/) { 120: $sth2->execute($photos[$hsh{$_}]); 121: $p = $sth2->fetchrow_hashref; 122: } 123: else { 124: $sth1->execute($photos[$hsh{$_}]) or die("Error!\n"); 125: my $data = $sth1->fetch; 126: $tmp{$_ . "_thumb_id"} = $data->[0]; 127: $tmp{$_ . "_thumb_location"} = get_image($data->[1], 100); 128: } 129: } 130: while(my($k,$v) = each %tmp) { $p->{$k} = $v; } 131: return($p); 132: } 133: sub get_image { 134: my ($photo, $size) = @_; 135: if(($size ne "orig") and (!$size eq "")){ 136: $photo =~ s/\.jpg$/\.$size\.jpg/; 137: } 138: return($photo); 139: }
Listing 16-3: admin.cgi
01: #!/usr/bin/perl -wT 02: # admin.cgi Photo Album Admin Script 03: use strict; 04: use DBI; 05: use CGI qw(:standard); 06: use lib qw(.); 07: use BasicSession; 08: our $sess; 09: my %item; 10: $sess = Get_Session(); 11: tie %item, ‘BasicSession’; 12: my $album = param(‘album’); 13: my $photo = param(‘photo’); 14: my $size = param(‘size’); 15: my $sizes = Make_Sizes(qw(640 800 orig)); 16: $size ? ($item{‘size’} = $size) : ($size = $item{‘size’}); 17: my $dbh = DBI->connect("DBI:mysql:photoalbum","bookuser","testpass") 18: or die("Cannot connect: $DBI::errstr"); 19: if($photo) { 20: Show_Photo($photo, $album); 21: exit; 22: } 23: elsif($album) { 24: Show_Album($album); 25: exit; 26: } 27: else { 28: List_Albums(); 29: exit; 30: } 31: sub Make_Sizes { 32: my @sizes = @_; 33: my $string = ‘’; 34: for my $size (@sizes) { 35: $string .= 36: qq(<a href="?photo=$photo&album=$album&size=$size">$size</a> ); 37: } 38: return($string); 39: } 40: sub List_Albums { 41: my $sql = qq{SELECT * FROM album}; 42: my $sth = $dbh->prepare($sql); 43: $sth->execute(); 44: Print_Page("./templates", "header.tmpl"); 45: Print_Page("./templates", "list_top.tmpl"); 46: while(my $p = $sth->fetchrow_hashref){ 47: Print_Page("./templates", "admin_list_row.tmpl", $p); 48: } 49: Print_Page("./templates", "list_end.tmpl"); 50: Print_Page("./templates", "footer.tmpl"); 51: } 52: sub Update_Data { 53: my $type = shift; 54: my ($title, $id, $sql); 55: if($type eq "photo") { 56: $title = param(‘img_title’); 57: $id = $photo; 58: $sql = qq{UPDATE photo SET img_title=?, comments=? WHERE img_id = ?}; 59: } 60: elsif($type eq "album") { 61: $title = param(‘title’); 62: $id = $album; 63: $sql = qq{UPDATE album SET name=?, comments=? WHERE album_id = ?}; 64: } 65: else { 66: return 0; 67: } 68: my $comments = param(‘comments’); 69: return unless($title or $comments); 70: my $sth = $dbh->prepare($sql); 71: $sth->execute($title, $comments, $id); 72: } 73: sub Show_Album { 74: Update_Data("album"); 75: my $cols = 3; 76: my $sql_p = qq{SELECT * FROM photo WHERE album_id = ?}; 77: my $sql_a = qq{SELECT * FROM album WHERE album_id = ?}; 78: my $sth_p = $dbh->prepare($sql_p); 79: my $sth_a = $dbh->prepare($sql_a); 80: $sth_p->execute($album); 81: $sth_a->execute($album); 82: Print_Page("./templates", "header.tmpl"); 83: my $alb = $sth_a->fetchrow_hashref; 84: $alb->{cols} = $cols; 85: Print_Page("./templates", "admin_album_top.tmpl", $alb); 86: my $counter = 1; 87: while(my $p = $sth_p->fetchrow_hashref){ 88: $p->{img_location} = get_image($p->{img_location}, 100); 89: print "<tr>" if($counter == 1); 90: Print_Page("./templates", "admin_album_row.tmpl", $p); 91: print "</tr>" if($counter == $cols); 92: $counter++; 93: $counter = 1 if($counter > $cols); 94: } 95: print "</tr>" unless($counter == 1); 96: Print_Page("./templates", "admin_album_end.tmpl", $alb); 97: Print_Page("./templates", "footer.tmpl"); 98: } 99: sub Get_Photo_List { 100: my ($photo, $album) = @_; 101: my ($index, @photos); 102: my $count = 0; 103: my $sql = qq{SELECT img_id FROM photo WHERE album_id = ?}; 104: my $sth = $dbh->prepare($sql); 105: my @all; 106: $sth->execute($album); 107: while(my @tmp = $sth->fetchrow_array){push @all, $tmp[0];} 108: for(@all) { 109: $index = $count if(/$photo/); # Get index of photo we want 110: $count++; 111: } 112: unless($index) { 113: @photos = @all[0, 1]; 114: unshift @photos, ‘’; 115: } 116: else { 117: @photos = @all[($index-1)..($index+1)]; # Get photos next to it 118: } 119: return (@photos); 120: } 121: sub Show_Photo { 122: my ($photo, $album) = @_; 123: Update_Data("photo"); 124: my @photos = Get_Photo_List($photo, $album); 125: my $ptr = Get_Details(@photos); 126: $ptr->{img_location} = get_image($ptr->{img_location}, $size); 127: $ptr->{image_sizes} = $sizes; 128: Print_Page("./templates", "header.tmpl"); 129: Print_Page("./templates", "admin_main.tmpl", $ptr); 130: Print_Page("./templates", "admin_footer.tmpl", $ptr); 131: } 132: sub Get_Details { 133: my @photos = @_; 134: my ($p, %tmp); 135: my %hsh = (‘prev’ => 0, ‘curr’ => 1, ‘next’ => 2); 136: my $sql1 = qq{SELECT img_id, img_location FROM photo WHERE img_id = ?}; 137: my $sql2 = qq{SELECT * FROM photo WHERE img_id = ?}; 138: my $sth1 = $dbh->prepare($sql1); 139: my $sth2 = $dbh->prepare($sql2); 140: for(keys %hsh){ 141: if(/curr/) { 142: $sth2->execute($photos[$hsh{$_}]); 143: $p = $sth2->fetchrow_hashref; 144: } 145: else { 146: $sth1->execute($photos[$hsh{$_}]) or die("Error!"); 147: my $data = $sth1->fetch; 148: $tmp{$_ . "_thumb_id"} = $data->[0]; 149: $tmp{$_ . "_thumb_location"} = get_image($data->[1], 100); 150: } 151: } 152: while(my($key,$val) = each %tmp) { $p->{$key} = $val; } 153: return($p); 154: } 155: sub get_image { 156: my ($photo, $size) = @_; 157: if($size ne "orig") { 158: $photo =~ s/\.jpg$/\.$size\.jpg/; 159: } 160: return($photo); 161: }
Listing 16-4: admin_album_end.tmpl
01: <!-- Begin admin_album_end.tmpl --> 02: <tr> 03: <td colspan="%%cols%%" align="center"> 04: <a href="?">Main Album List</a><br /> 05: </td> 06: </tr> 07: <tr> 08: <td colspan="%%cols%%" align="center"> 09: Album Comments:<br /> 10: <textarea rows="2" cols="40" wrap="physical" name="comments">%%comments%%</textarea><br /> 11: <input type="submit" value="Submit Changes"> 12: </td> 13: </tr> 14: </table> 15: </form> 16: <!-- End admin_album_end.tmpl -->
Listing 16-5: admin_album_row.tmpl
01: <td align="center" width="200"> 02: <a href="/cgi-bin/admin.cgi?photo=%%img_id%%&album=%%album_id%%"><img src="/books/2/889/1/html/2/%%img_location%%" border="0"></a> 03: <br> 04: %%img_title%% 05: </td>
Listing 16-6: admin_album_top.tmpl
01: <!-- Begin admin_album_top.tmpl --> 02: <hr width="50%"> 03: <form> 04: <input type="hidden" name="album" value="%%album_id%%"> 05: <table align="center" border="1" cellspacing="0"> 06: <tr> 07: <td colspan="%%cols%%" align="center"> 08: Album Title: <input type="text" name="title" value="%%name%%"> 09: </td> 10: </tr> 11: <!-- End admin_album_top.tmpl -->
Listing 16-7: admin_footer.tmpl
01: <tr> 02: <td colspan="3" align="center"> 03: <a href="?">Main Album List</a> 04: <input type="submit" value="Submit Data"> 05: <a href="?album=%%album_id%%">This Album Main</a> 06: </td> 07: </tr> 08: </table> 09: </form> 10: </body> 11: </html>
Listing 16-8: admin_list_row.tmpl
01: <!-- Begin admin_list_row.tmpl --> 02: <tr> 03: <td> 04: <a href="/cgi-bin/admin.cgi?album=%%album_id%%">%%name%%</a> 05: </td> 06: <td> %%comments%%</td> 07: </tr> 08: <!-- End admin_list_row.tmpl -->
Listing 16-9: admin_main.tmpl
01: <form> 02: <input type="hidden" name="photo" value="%%img_id%%"> 03: <input type="hidden" name="album" value="%%album_id%%"> 04: <table border="1" cellspacing="0" align="center"> 05: <tr> 06: <td colspan="3" align="center"> 07: <img src="/books/2/889/1/html/2/%%img_location%%"> 08: </td> 09: </tr> 10: <tr> 11: <td width="100" valign="top"> 12: <a href="?photo=%%prev_thumb_id%%&album=%%album_id%%"> 13: <img src="/books/2/889/1/html/2/%%prev_thumb_location%%" border="0"> 14: </a> 15: </td> 16: <td> 17: <table border="1" cellspacing="0" align="center" width="100%"> 18: <tr> 19: <td><b>Image Title:</b></td> 20: <td><input type="text" name="img_title" value="%%img_title%%"></td> 21: </tr> 22: <tr> 23: <td><b>Image Date:</b></td> 24: <td>%%img_date%%</td> 25: </tr> 26: <tr> 27: <td><b>Flash:</b></td> 28: <td>%%flash%%</td> 29: </tr> 30: <tr> 31: <td><b>Focal Length:</b></td> 32: <td>%%focal_length%%mm</td> 33: </tr> 34: <tr> 35: <td><b>Aperture:</b></td> 36: <td>f/%%aperture%%</td> 37: </tr> 38: <tr> 39: <td><b>ISO Speed:</b></td> 40: <td>%%iso_speed%%</td> 41: </tr> 42: <tr> 43: <td><b>Shutter Speed:</b></td> 44: <td>%%exposure%% sec.</td> 45: </tr> 46: <tr> 47: <td><b>Camera Make:</b></td> 48: <td>%%make%%</td> 49: </tr> 50: <tr> 51: <td><b>Camera Model:</b></td> 52: <td>%%model%%</td> 53: </tr> 54: <tr> 55: <td><b>Comments:</b></td> 56: <td> 57: <textarea name="comments" rows="2" cols="40" wrap="physical">%%comments%%</textarea> 58: </td> 59: </tr> 60: <tr> 61: <td><b>Image Sizes:</b></td> 62: <td>%%image_sizes%%</td> 63: </tr> 64: </table> 65: </td> 66: <td width="100" valign="top"> 67: <a href="?photo=%%next_thumb_id%%&album=%%album_id%%"> 68: <img src="/books/2/889/1/html/2/%%next_thumb_location%%" border="0"> 69: </a> 70: </td> 71: </tr>
Listing 16-10: album_end.tmpl
01: <!-- Begin album_end.tmpl --> 02: <tr> 03: <td colspan="%%cols%%" align="center"> 04: <a href="?">Main Album List</a> 05: </td> 06: </tr> 07: </table> 08: <!-- End album_end.tmpl -->
Listing 16-11: album_row.tmpl
01: <td align="center" width="200"> 02: <a href="/cgi-bin/index.cgi?photo=%%img_id%%&album=%%album_id%%"><img src="/books/2/889/1/html/2/%%img_location%%" border="0"></a> 03: <br> 04: %%img_title%% 05: </td>
Listing 16-12: album_top.tmpl
01: <!-- Begin album_top.tmpl --> 02: <hr width="50%"> 03: <table align="center" border="1" cellspacing="0"> 04: <tr> 05: <td colspan="%%cols%%" align="center"> 06: <font >%%name%%</font> 07: </td> 08: </tr> 09: <!-- End album_top.tmpl -->
Listing 16-13: footer.tmpl
01: </body> 02: </html>
Listing 16-14: header.tmpl
01: <html><head><title>Perl Photo Album</title> 02: <style type="text/css"> 03: <!-- 04: td { background: #e0e0e0; 05: color: #000000; 06: font-family: Lucida, Verdana, Helvetica, Arial; 07: font-size: 12pt} 08: a:link { color: #4444ff } 09: a:visited { color: #333377 } 10: a:active { color: #0000dd } 11: b 12: { font-family: Lucida, Verdana, Helvetica, Arial; 13: font-size: 10pt; 14: color: #000000 } 15: .small 16: { font-family: Lucida, Verdana, Helvetica, Arial; 17: font-size: 10pt; 18: color: #000000 } 19: .medium 20: { font-family: Lucida, Verdana, Helvetica, Arial; 21: font-size: 12pt; 22: color: #000000 } 23: .big_error 24: { font-family: Lucida, Verdana, Helvetica, Arial; 25: font-size: 14pt; 26: font-weight: bold; 27: color: #ff0000 } 28: .big 29: { font-family: Lucida, Verdana, Helvetica, Arial; 30: font-size: 14pt; 31: color: #000000 } 32: .large 33: { font-family: Lucida, Verdana, Helvetica, Arial; 34: font-size: 20pt; 35: color: #000000 } 36: .big2 37: { font-family: Lucida, Verdana, Helvetica, Arial; 38: font-size: 24pt; 39: color: #000000 } 40: --> 41: </style> 42: </head> 43: <body> 44: <div align="center"> 45: <img src="/books/2/889/1/html/2//images/album/perl_photo_album.jpg"> 46: <div>
Listing 16-15: list_end.tmpl
01: <!-- Begin albums_end.tmpl --> 02: </table> 03: <!-- End albums_end.tmpl -->
Listing 16-16: list_row.tmpl
01: <!-- Begin list_row.tmpl --> 02: <tr> 03: <td> 04: <a href="/cgi-bin/index.cgi?album=%%album_id%%">%%name%%</a> 05: </td> 06: <td> %%comments%%</td> 07: </tr> 08: <!-- End list_row.tmpl -->
Listing 16-17: list_top.tmpl
01: <!-- Begin list_top.tmpl --> 02: <hr width="50%"> 03: <table align="center" border="1" cellspacing="0"> 04: <tr> 05: <td colspan="2" align="center"> 06: <font >Available Albums</font> 07: </td> 08: </tr> 09: <tr> 10: <td><b>Album Name</b></td> 11: <td><b>Comments</b></td> 12: </tr> 13: <!-- End list_top.tmpl -->
Listing 16-18: photo_footer.tmpl
01: <tr> 02: <td colspan="3" align="center"> 03: <a href="?">Main Album List</a> 04: <a href="?album=%%album_id%%">This Album Main</a> 05: </td> 06: </tr> 07: </table> 08: </body> 09: </html>
Listing 16-19: photo_main.tmpl
01: <table border="1" cellspacing="0" align="center"> 02: <tr> 03: <td colspan="3" align="center"> 04: <img src="/books/2/889/1/html/2/%%img_location%%"> 05: </td> 06: </tr> 07: <tr> 08: <td width="100" valign="top"> 09: <a href="?photo=%%prev_thumb_id%%&album=%%album_id%%"> 10: <img src="/books/2/889/1/html/2/%%prev_thumb_location%%" border="0"> 11: </a> 12: </td> 13: <td> 14: <table border="1" cellspacing="0" align="center" width="100%"> 15: <tr> 16: <td><b>Image Title:</b></td> 17: <td>%%img_title%%</td> 18: </tr> 19: <tr> 20: <td><b>Image Date:</b></td> 21: <td>%%img_date%%</td> 22: </tr> 23: <tr> 24: <td><b>Flash:</b></td> 25: <td>%%flash%%</td> 26: </tr> 27: <tr> 28: <td><b>Focal Length:</b></td> 29: <td>%%focal_length%%mm</td> 30: </tr> 31: <tr> 32: <td><b>Aperture:</b></td> 33: <td>f/%%aperture%%</td> 34: </tr> 35: <tr> 36: <td><b>ISO Speed:</b></td> 37: <td>%%iso_speed%%</td> 38: </tr> 39: <tr> 40: <td><b>Shutter Speed:</b></td> 41: <td>%%exposure%% sec.</td> 42: </tr> 43: <tr> 44: <td><b>Camera Make:</b></td> 45: <td>%%make%%</td> 46: </tr> 47: <tr> 48: <td><b>Camera Model:</b></td> 49: <td>%%model%%</td> 50: </tr> 51: <tr> 52: <td><b>Comments:</b></td> 53: <td>%%comments%% </td> 54: </tr> 55: <tr> 56: <td><b>Image Sizes:</b></td> 57: <td>%%image_sizes%%</td> 58: </tr> 59: </table> 60: </td> 61: <td width="100" valign="top"> 62: <a href="?photo=%%next_thumb_id%%&album=%%album_id%%"> 63: <img src="/books/2/889/1/html/2/%%next_thumb_location%%" border="0"> 64: </a> 65: </td> 66: </tr>