John Lennon wall in Prague

Simple automatic PHP image gallery with Bootstrap, SASS and Lightbox integration

05/03/2015

General concept

This is a simple PHP script that scans the content of a directory for files with certain extensions (for example .jpg, .png etc.) and automatically generates a image gallery allocated in Bootstrap responsive, scalable grid. Images can be smoothly previewed thanks to lightbox javascript. CSS stylesheet is generated from SASS .scss file and hence more readable.

Features:

  • PHP loop that automatically scans for every image in given folder - just put all files in one place, edit CSS / navigation links and it’s done!
  • exif data (date, comment) integration in picture’s caption
  • bootstrap framework - grid system and navigation fixed menu
  • lightbox javascripts for image preview and slideshow
  • SASS integration for CSS for faster deployment
The project is available in my github repo mDfRg/php-autogallery under MIT license.

The code

<?php
class Gallery {
    public $path; //this will be later set as a variable in index.php
    public function setPath($path) {
        $this->path = $path;
    }

    private function getDirectory($path) {
        return scandir($path);
    }
    public function getImages($extensions = array()) {
        $images = $this->getDirectory($this->path); //list all files
        
        
        foreach($images as $index => $image) {
            $explode = explode('.', $image);
            $extension = end($explode);
            if(!in_array($extension, $extensions)) { //check if files extensions meet the criteria set in index.php
                unset($images[$index]);
            } else {
                $images[$index] = array( //make an array of images and corresponding miniatures
                    'full' => $this->path . '/' . $image,
                    'thumb' => $this->path . '/thumbs/' . $image  
                    );
            }
           
        }
        return (count($images)) ? $images : false;   
    }   
}
?>

Variables included before the HTML document

<?php
require 'gallery.php';
$gallery = new Gallery();
$gallery->setPath('img'); //path to the image folder
$images = $gallery->getImages(array('JPG','PNG')); //array of possible image extensions (useful if you have mixed galleries)
$row_counter = 0; //don't change that
$img_no_caption = " "; //default caption for image that don't have one

$page_title="Scandinavia"; //changes the <title> attribute AND the logo in top left corner
$no_images_warning="Ooops! No images in gallery!"; //Display the text when $gallery->setPath directory is empty.
$col_md_x = 6; //Bootstrap - choose either 2,3,4 or 6 to have 6,4,3 or 2 pics per line respectively
//----------------------------------------------

$row_x = 12 / $col_md_x; ?>

HTML structure

The head

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title><?php echo $page_title; ?></title>
    <link href="bootstrap/css/bootstrap.min.css" rel="stylesheet">
    <link href="lightbox/css/lightbox.css" rel="stylesheet" />
    <link rel="stylesheet" href="css/style.css">
 
    <script src="lightbox/js/jquery-1.11.0.min.js"></script>
    <script src="bootstrap/js/bootstrap.min.js"></script>
    <script src="lightbox/js/lightbox.min.js"></script>
  </head>

The navigation

<nav class="navbar navbar-default navbar-fixed-top"  role="navigation">
  <div class="container-fluid">
    <!-- Brand and toggle get grouped for better mobile display -->
    <div class="navbar-header">
      <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
        <span class="sr-only">Toggle navigation</span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
      <a class="navbar-brand" href="#"><?php echo $page_title; ?></a>
    </div>

    <!-- Collect the nav links, forms, and other content for toggling -->
    <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
   <!--   <ul class="nav navbar-nav">
        <li><a href="#">Link</a></li>
        <li><a href="#">Link</a></li>
       
      </ul>-->
      
      <ul class="nav navbar-nav navbar-right">
        <li class="dropdown">
          <a href="#" class="dropdown-toggle" data-toggle="dropdown">Other Galleries <span class="caret"></span></a>
          <ul class="dropdown-menu" role="menu">
            <li><a href="#">Action</a></li>
            <li><a href="#">Another action</a></li>
            <li><a href="#">Something else here</a></li>
            <li class="divider"></li>
            <li><a href="#">Separated link</a></li>
          </ul>
        </li>
      </ul>
    </div><!-- /.navbar-collapse -->
  </div><!-- /.container-fluid -->
</nav>

The body

<body>
<?php include 'navigation.php'; ?>
<br />
<div class="container">
  <div class="row">
 
	<?php if($images): ?>

	    <?php foreach($images as $image):
	    
		    $img_caption = exif_read_data($image['full'], 0, true)['COMPUTED']['UserComment'];
		    $img_date = exif_read_data($image['full'], 0, true)['IFD0']['DateTime'];
		 
		    (!$img_caption) ? $img_caption = $img_no_caption : true;	    
		    $row_counter++;
		    ?>
		    <div class="col-md-<?php echo $col_md_x; ?>">
		      <div class="picture_card">
		    	<a href="<?php echo $image['full']; ?>" data-lightbox="roadtrip" 
            data-title="<?php echo $img_caption; ?>"><img title="<?php echo $img_caption; ?>" 
            src="<?php echo $image['thumb']; ?>"></a>
		    	<br />
			      	<div class="picture_card_description">
			    	<span class="glyphicon glyphicon-time"></span>&nbsp;<span 
            class="picture_card_description_date"><?php echo $img_date; ?></span>
			    	<br />
			    
				    <?php if ($img_caption == $img_no_caption) {
				      echo "";
				    } else {
				      echo $img_caption;
				    }?>
			      	</div>
		      </div>
		    </div>
		    <?php
		    if ($row_counter % $row_x == 0) {
		    echo '</div><br /><div class="row">';
		    }  
		    endforeach; ?>
	    
		<?php else: ?>
		<div id=no_images><?php echo $no_images_warning; ?></div>

	<?php endif; ?>
	
  </div>	
</div>
<br />
</body>
</html>

Known drawbacks

  • The code might be optimized by including only the most necessary parts of bootstrap code (grid system, navigation).
  • Date formats should be converted to more common forms.
  • In recent version, file extensions must be used with capital letters.

Acknowledgments and License

This project is a upgraded version of the one included in tutorials provided by codecademy. Bootstrap and lightbox have their own licenses. PHP gallery is licensed under MIT license. The pictures available in the preview are my property. All rights reserved.