MegaGallery, Part 4: Automation with PHP

The next step in our MegaGallery project is to use the power of PHP to automate much of the work for us. With a gallery of 5-10 images, setting up each of the links to the images would not take a lot of work, but with a gallery of 20, 50, or more, you would spend hours just setting up the links and thumbnails.

For this part of the project, we will use FastTemplate to help us put everything together quickly. There are better PHP template frameworks out there, like SMARTY, but SMARTY is overkill for this project. (While writing this post, I could not get a connection to the SMARTY homepage. Not sure what that is all about.)

Weberdev.com has a good tutorial on FastTemplate.

Loading the Filenames

While thinking about how I wanted to automate the process of collecting the images, I searched the PHP documentation, and decided on a function named scandir(). You pass a folder path to scandir() and it returns an array containing the names of the files in the folder. You can also pass a parameter to the function to sort the filenames, but we will not use that here, but it could come in handy in other applications. By default the sort order is alphabetical in ascending order.

Revising getComment() and createThumbnail()

In part 2, we used the getComment() and createThumbnail() functions to just echo out content. To make them act like true functions, we need them to return a value instead. I revised the two functions, replacing the echo with return. I also placed them in their own file, which I named image-proc.php. Having them in their own file will make it easier to use them in later projects, or add more image processing functions in a central library.

The image-proc.php file looks like this:

< ?php
/**
 *
 * @param string $image - the path to the image
 * @return string - base64 encoded thumbnail wrapped in an <img> tag or string saying no thumbnail available
 */
function createThumbnail($image) {
 $image = exif_thumbnail($image, $width, $height, $type);
 if ($image !== false) {
 return "<img   width='$width' height='$height' src='data:image/gif;base64,".base64_encode($image)."'/>";
 }
 else {
 return "No thumbnail available!";
 }
}

/**
 *
 * @param string $image - the path to the image
 * @return string - the string containing the comment or an empty string if no info available
 */
function getComment ($image) {
 $exif = exif_read_data($image, 'COMMENT');
 if ($exif !== false) {
 return $exif['COMMENT'][0];
 }
 else {
 return " ";
 }
}
?>

Creating the Templates

We will need three templates for our project.

main.tpl

The first template contains the entire XHTML document we used before minus the unordered lists and list items that contain our images. We will be moving them to our other two templates. We replace them with a FastTemplate placeholder: {IMAGES}

The body section of our main template now looks like this:

<div id="container">
<h1>MegaGallery</h1>
<div id="gallery">
{IMAGES}</div>
</div>

I named the file main.tpl and placed it in a folder named /tpl (for templates). All 3 templates will go into this folder.

ul.tpl

The next template is just a frame for an unordered list with a placeholder for a list.

<ul>
{LIST}</ul>

li.tpl

The li.tpl is a pattern for how each of the list items will look.

	<li>
<a href="{IMAGE}" rel="lightbox-show" title="{COMMENTS}">
{THUMB}
</a></li>

The li.tpl contains 3 placeholders:

  1. {IMAGE} – the filepath to the image
  2. {COMMENTS} – the comments for the image, the return of calling getComment()
  3. {THUMB} – the thumbnail, the return of calling createThumbnail()

The Main Script

The main script in the index.php file is where we pull everything together and make it work for us. We need to include the FastTemplate file and the image-proc.php file.

include ("./class/cls_fast_template.php");
include ("image-proc.php");

Next, we need to create an instance of the FastTemplate object and define our templates.

$tpl = new FastTemplate("./tpl/");
$tpl->define( array(
 "main" => "main.tpl",
 "images" => "ul.tpl",
 "list" => "li.tpl"));

In line 1, we create an instance of the FastTemplate object. It takes one parameter: the path to our template files. In the following lines, we define our template files. This is done by creating an array using the array() function in PHP. It is an associative array, with the key as a name for the template and the value as the template file itself. Notice we have defined all three of our template files.

Variable Assignments

We assign three variables that will help us make short work of our tasks.

$i = 1; // counter
$dir    = './pix'; // path to images
$files = scandir($dir); // get image filenames in an array

We will use $i as a counter to know when we need to create a new row of images. $dir is the path to the image files. $files is our array of images filename we get by calling scandir().

The Processing Loop

foreach ($files as $file) {
 if ((trim($file) !== ".") && (trim($file) !== "..")) {
 $fullPath = $dir . "/" . $file;
 $tpl->assign (array (
 "IMAGE" => $fullPath,
 "COMMENTS" => getComment($fullPath),
 "THUMB" => createThumbnail($fullPath)));
 $tpl->parse("LIST", ".list");
 $i++;
 } // end if $file not a directory

 // Once we have retrieved 4 images, we need to start over with a new list
 if ($i > 4) {
 $tpl->parse("IMAGES", ".images");
 $tpl->clear("LIST");
 $i = 1;
 } // end if $i > 4
} // end foreach

The real work is done in the foreach loop. The start of the loop is saying, for each of the elements in the array $files use it as the variable $file. This allows us to easily work with each of the elements by simply addressing the variable $file.

We start with an if statement. In a directory listing there will normally be at least two listings that are nothing more than a reference to the current directory “. ” and the parent directory “..” Our if statement makes sure that our current file is either of these. If it is not either of these then we need to process it, because it is the name of one of our image files.

The variable $fullpath is a concatenation of the image directory and the image filename, creating a full path to the image file.

Next, we assign values to the template object ($tpl) using the FastTemplate assign() function. The assign() function takes an array of placeholder/value pairs. Remember, we set up three placeholders in our li.tpl file. The IMAGE placeholder is just assigned the full path to the image. We assign a value to the COMMENTS placeholder using our getComment() function, and THUMB using the createThumbnail() function.

Once the values are assigned, we parse them to the LIST placeholder using FastTemplates parse() function, and increment our counter ($i) by 1.

When $i is greater than 4 (the number of images in a row), we need to add the current list to the images and start a new unordered list. This is accomplished by parsing the list to the IMAGES placeholder, using the FastTemplate clear() function to clear out the list, and setting the counter back to 1.

Note that when we use the parse() function, we use a “.” to add to the current placeholder rather than over-writing it, as in “.list”.

Make Sure the Last Row Gets Displayed

If the images are not evenly divisible by 4, we run into a problem with the last row — it doesn’t get processed. We solve the problem with a quick if statement after the the foreach loop.

if ($i != 1) {
 $tpl->parse("IMAGES", ".images");
}

If the new row of images was processed by the loop, the counter, $i, will have a value of 1. If the value of $i is not 1, we process the row of images.

Process MAIN Template and Output Page

$tpl->parse("MAIN", "main");
$tpl->FastPrint("MAIN");

Parsing MAIN will plug all our information into the main template. FastPrint() outputs the XHTML document to the browser.

We are done, and have automated the formating of much main body of the document. Completed Project Sample

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s