Create A Gallery From A Directory



How To Build An Auto-Populating Gallery With Lightbox In PHP

Galleries are absolutely everywhere. From failbork to the oldest of websites, they're a very important part of the web.

We'll start with a basic HTML template using the Bulma framework. Save it with a .php extension as we'll be writing some PHP in it.

<!DOCTYPE html>
<html>

  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Galleree</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.2/css/bulma.min.css">
  </head>

  <body>
    <section class="hero is-fullheight is-black">
      <div class="hero-body">
        <div class="container">
          GALLERY FUNCTION WILL GO HERE
        </div>
      </div>
    </section>
  </body>

</html>

Next we need to write a function to go grab all the images from a given directory. We can do this with glob.

<?php
function gallery()
{
    $dirname = "images/";
    $images = glob($dirname . "*.{jpg,JPG,jpeg,JPEG,png,PNG}", GLOB_BRACE);
    foreach ($images as $image) {
      echo $image;
    }
}
?>

That should print out a long line of all the images in the /images/ directory (I suggest you create it and add some image to it if you haven't already).

Let's use the CSS framework to show the images and make it look a bit better and we'll sort the images by date. Change the gallery() function to this...

<?php
function gallery()
{
    $dirname = "images/";
    $images = glob($dirname . "*.{jpg,JPG,jpeg,JPEG,png,PNG}", GLOB_BRACE);

    usort($images, function ($a, $b) {
        return filemtime($b) - filemtime($a);
    });

    echo "<div id='gallery' class='columns is-multiline is-mobile'>";

    foreach ($images as $image) {
        echo "<div class='column is-3-desktop is-6-touch'>
                <figure class='image is-square'>
                  <a href='$image'><img src='$image'></a>
                </figure>
              </div>";
    }
    echo "</div>";
}
?>

And add this CSS just before the </head> tag. Some of these CSS classes will be used later for the lightbox.

<style>
@media only screen and (min-width : 768px) {
  * {
    overflow: hidden !important;
  }
}
.page-count {
  position: fixed;
  top: 10px;
  left: 10px;
  font-size: 14px;
}
.is-square img {
  object-fit: cover;
}
.sl-overlay {
  background: #000 !important;
}
.sl-counter, .sl-prev, .sl-next, .sl-close {
  color: #fff !important;
}
</style>

If all has went well we should have something that resembles this.

Now let's have a think about what we're doing here. It's not a good idea to load hundreds of images on a single page. We can use pagination to limit the amount of images per page.

<?php
function gallery()
{
    $dirname = "images/";
    $files = glob($dirname . "*.{jpg,JPG,jpeg,JPEG,png,PNG}", GLOB_BRACE);

    usort($files, function ($a, $b) {
        return filemtime($b) - filemtime($a);
    });

    $image_count = 8;
    $total_pages = ceil(count($files)/$image_count);

    if (isset($_GET['page'])) {
        $page = $_GET['page'];
    } else {
        $page = 1;
    }

    $offset = ($page-1)*$image_count;
    $images = array_slice($files, $offset, $image_count);

    echo "<div id='gallery' class='columns is-multiline is-mobile'>";

    foreach ($images as $image) {
        echo "<div class='column is-3-desktop is-6-touch'>
                <figure class='image is-square'>
                  <a href='$image'><img src='$image'></a>
                </figure>
              </div>";
    }

    echo "</div>
    <div class='columns is-mobile'>
      <div class='column is-6'>";

    if ($total_pages > 1) {
        if ($page != 1) {
            echo '<a class="button is-dark is-fullwidth" href="./?page='.($page-1).'">Prev</a>';
        }
        echo "</div>
        <div class='column is-6'>";

        if ($page != $total_pages) {
            echo '<a class="button is-dark is-fullwidth" href="./?page='.($page+1).'">Next</a>';
        }
    }
    echo "</div>
      </div>
    </div>";
}
?>

Yey for good old pagination.

Now we'll add the lightbox so the user can fullscreen the images and slide through them.

Add this inside the <head> next to the other CSS.

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/simplelightbox/1.15.1/simplelightbox.min.css">

And this just before the </body> tag.

<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/simplelightbox/1.15.1/simple-lightbox.min.js"></script>
<script>
$(function() {
  var lightbox = $('#gallery a').simpleLightbox();
});
</script>

That's as simple as it can get.

The full source code for your copying pleasure.

<?php
function gallery()
{
    $dirname = "images/";
    $files = glob($dirname . "*.{jpg,JPG,jpeg,JPEG,png,PNG}", GLOB_BRACE);

    usort($files, function ($a, $b) {
        return filemtime($b) - filemtime($a);
    });

    $image_count = 8;
    $total_pages = ceil(count($files)/$image_count);

    if (isset($_GET['page'])) {
        $page = $_GET['page'];
    } else {
        $page = 1;
    }

    $offset = ($page-1)*$image_count;
    $images = array_slice($files, $offset, $image_count);

    echo "<div id='gallery' class='columns is-multiline is-mobile'>";

    foreach ($images as $image) {
        echo "<div class='column is-3-desktop is-6-touch'>
                <figure class='image is-square'>
                  <a href='$image'><img src='$image'></a>
                </figure>
              </div>";
    }

    echo "</div>
    <div class='columns is-mobile'>
      <div class='column is-6'>";

    if ($total_pages > 1) {
        if ($page != 1) {
            echo '<a class="button is-dark is-fullwidth" href="./?page='.($page-1).'">Prev</a>';
        }
        echo "</div>
        <div class='column is-6'>";

        if ($page != $total_pages) {
            echo '<a class="button is-dark is-fullwidth" href="./?page='.($page+1).'">Next</a>';
        }
    }
    echo "</div>
      </div>
    </div>";
}
?>

<!DOCTYPE html>
<html>

  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Galleree</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.2/css/bulma.min.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/simplelightbox/1.15.1/simplelightbox.min.css">
    <style>
    @media only screen and (min-width : 768px) {
      * {
        overflow: hidden !important;
      }
    }
    .page-count {
      position: fixed;
      top: 10px;
      left: 10px;
      font-size: 14px;
    }
    .is-square img {
      object-fit: cover;
    }
    .sl-overlay {
      background: #000 !important;
    }
    .sl-counter, .sl-prev, .sl-next, .sl-close {
      color: #fff !important;
    }
    </style>
  </head>

  <body>
    <section class="hero is-fullheight is-black">
      <div class="hero-body">
        <div class="container">
          <?php gallery(); ?>
        </div>
      </div>
    </section>

    <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/simplelightbox/1.15.1/simple-lightbox.min.js"></script>
    <script>
    $(function() {
      var lightbox = $('#gallery a').simpleLightbox();
    });
    </script>

  </body>

</html>

This is all quick and dirty. I don't recommend using any of it under any circumstance.

Thanks for reading. x

Resources