UniteGallery + OctoberCMS = Happy Photographer
February 11, 2019

UniteGallery + OctoberCMS = Happy Photographer

Yesterday I integrated UniteGallery into my girlfriend's website and I'm quite pleased with the results. I may end up writing an OctoberCMS plugin to this end, but for now I'd just like to make some notes on how this was done.

Note that if you do a cursery breeze on GitHub, you'll see that there are many many javascript-based lightbox and gallery plugins out there, and UniteGallery is not on the top of the list. But it has many things going for it:

  • It is not only a full-blown photo-viewer (with mobile/swipe support) but it also creates your galleries for you, and you can choose from various gallery themes!
  • It is open-source with an MIT licence
  • It is based on jQuery
  • It has a great demo page where  you can try out all the options
  • Speaking of options there are many, enabling you to customize it to your needs (you can even develop a skin or a theme for it)
  • I've emailed with the author and he is quick to respond and very helpful

There is not much to getting UniteGallery working on OctoberCMS if you just want to hardcode pitcure paths, and really all the instructions you need are included in UniteGallery's own documentation. However I don't like to hardcode, instead I wanted to write a function that would iterate through a folder and dynamically load all of the images into UniteGallery. Additionally, I didn't want to have to manually generate thumbnails. Luckily we already have some great OctoberCMS plugins just for that purpose. I ended up using Matthew Pawley's October Image Resizer plugin. It's nice because it doesn't have any dependencies and can optionally compress your files using TinyPng.com.

To the point

Preparations

  • Install Matthew Pawley's October Image Resizer plugin in your site /backend
  • Download UniteGallery and upload it somewhere in your site (I put it under assets/js/unitegallery which may arguably not be the best place, but this way if I switch or update themes I won't lose my unitegallery js) OR  use a CDN if you can find one
  • Create a new "gallery" page somewhere under pages and add the Image Resizer plugin component to it (just drag & drop somewhere).
  • Open the Media page in your OctoberCMS backend and create a subfolder under to hold all of your galleries, I called this folder galleries
  • Create a subfolder under your galleries folder for each gallery you will have, for example galleries/cute-cat-pics and galleries/ufo-sightings and galleries/my-bombisha-collection etc.
  • Resize your photos to a size appropriate for web viewing
  • Upload your photos into the above galleries
  • Jot down the extensions of your photos (mine were all jpg or jpeg, you may have gif or png etc.)

Step 1 – Add URL Parameters

The code will expect to receive the folder name of your gallery as a URL parameter. To set this up, update the URL of your gallery page in the backend to follow this example:

/gallery/:gallery_code|^cute-cat-pics|ufo-sightings|my-bombisha-collection$

So if your page's URL code is "gallery", then add "/:gallery_code" to it. This tells OctoberCMS that you are expecting a gallery code in the link to the page.

The second part is for security, it is a regular expression that ensures that someone can't just pass any arbitrary expression to your page. In our example we are allowing three galleries named "cute-cat-pics", "ufo-sightings", and "my-bombisha-collection."

You can read more about URL parameters in the official docs.

Step 2 – Place the following into the "Code" part of your page:

function onStart()
{
    // Options:
    $mediaPath = storage_path() . "/app/media";
    $mediaSubDir = "galleries";
    $extensions = array("jpg", "jpeg");
    $maxImages = 100;
    $validGalleryNames = array("cute-cat-pics", "ufo-sightings", "my-bombisha-collection");
    // end of options!    
    
    $galleryName = $this->param('gallery_code');
    $galleryPath = @"{$mediaPath}/{$mediaSubDir}/{$galleryName}/";
    if (!in_array($galleryName, $validGalleryNames) || !File::isDirectory($galleryPath)) {
        $this["images"] = array();
        return;
    }
    // Using Glob would arguably be a better alternative as it is native php
    //  - see http://php.net/manual/en/function.glob.php
    // But we stick to Laravel's File interface
    //$fils = glob(@"{$mediaPath}/{$galleryDirName}/*.jpg"); or glob( themes_path( $theme_dir ) . '/*.{yaml,png}', GLOB_BRACE ) 
    $files     = File::allFiles($galleryPath);
    $images     = [ ];
    $i = 1;
    foreach ($files as $file) {
        if ($file->isFile() && $file->isReadable() && in_array ($file->getExtension(), $extensions)) {
            // List of methods available: http://php.net/manual/en/splfileinfo.getfilename.php
            $images[] = str_replace(@"{$mediaPath}/", '', $file->getPathname());
        }
        if ($i > $maxImages) break;
        $i++;
    }    
    $this["images"] = $images; 
}

The above code basically searches through all files in a given directory, finds any files that match any of the given extensions in $extensions and dumps the relative paths into $this["images"].

You can update the $mediaSubDir variable to match the directory you created to hold all of your galleries in step 1, and limit the number of images you wish to show in $maxImages.

As an added security measure, we also add all valid directory names into the $validGalleryNames array. We already validate the gallery names using OctoberCMS's parameter validation technique, but it doesn't hurt to double-check!

Step 3 – Set Your Page Markup

Now add something along these lines to your page markup:

{% put styles %}
	<link rel="stylesheet" href="{{ 'assets/js/unitegallery/dist/css/unite-gallery.css' | media }}" type="text/css" /> 
{% endput %}
{% put scripts %}
    <script type="text/javascript" src="{{ 'assets/js/unitegallery/dist/js/unitegallery.min.js' | media }}"></script> 
	<script type="text/javascript" src="{{ 'assets/js/unitegallery/dist/themes/tiles/ug-theme-tiles.js' | media }}"></script> 
{% endput %}

<div id="gallery" style="display:none;">

    {% for image in images %}
        <img alt="" src="{{ image | media | resize(280, false,  { mode: 'portrait', quality: '90', extension: 'png' }) }}"
		data-image="{{ image | media }}"
		data-description="">
    {% endfor %}

</div>
<div style="height: 55px;"></div>

{% put scripts %}
<script type="text/javascript"> 
    // UniteGallery: https://github.com/vvvmax/unitegallery/
	jQuery(document).ready(function(){ 
		jQuery("#gallery").unitegallery({
		    // Options: http://unitegallery.net/index.php?page=tiles-columns-options
		    tiles_col_width: 280,                   //column width - exact or base according the settings
		    tiles_exact_width: true,                //exact width of column - disables the min and max columns
		    tiles_include_padding: false,           //include padding at the sides of the columns, equal to current space between cols
		    tiles_space_between_cols: 10,			//space between images
			tiles_space_between_cols_mobile: 10,     //space between cols for mobile type
			tiles_min_columns: 1,					//min columns
			
			tile_enable_image_effect:false,		//enable tile image effect
			tile_image_effect_type: "blur",		//bw, blur, sepia - tile effect type
			
			//lightbox options:
			lightbox_show_numbers: false,					//show numbers on the right side
			lightbox_type: "wide",							//compact / wide - lightbox type
			lightbox_show_textpanel: false,						//show the text panel
		}); 
	}); 

</script>
{% endput %}

The {% put styles %}...{% endput %} part just makes sure that the required js and css files are loaded. You should have downloaded these from the UniteGallery github page and uploadet them somewhere into your site as part of the preparations. You will need to update these links.

The <div id='gallery'...></div> part is where you generate the links to your gallery images. The onStart function you placed into the page code tab ensures that there is an images array that you can iterate over – this is what the {% for image in images %} part does. The {{ image | media | resize(280, false,  { mode: 'portrait', quality: '90', extension: 'png' }) }} twigly-doo takes your image, properly qualifies it (see |media filter), and uses the |resize twig extension provided by the Image Resizer Plugin (that you dropped into your page back in the preparations section, right?).

The {% put scripts %}...{% endput %} part fires up UniteGallery. You can set various options to your heart's desire as described in the UniteGallery documentation.

And finally you can now add some links to your galleries into your menu or wherever.

My links look like this:

<a href="{{ 'galeriak/galeria'|page({ gallery_code:"cute-cat-pics" }) }}">
   <img src="/storage/app/media/welcome/a-cute-cat.jpg"/>
   <div class="welcome-img-caption">Cute Cats</div>
</a>
<a href="{{ 'galeriak/galeria'|page({ gallery_code:"ufo-sightings" }) }}">
   <img src="/storage/app/media/welcome/encounters-of-the-3rd-kind.jpg"/>
   <div class="welcome-img-caption">I saw a UFO!</div>
</a>

As you can see, you should pass the name of the directory of the gallery you wish to show in the gallery_code URL parameter.

This is what one of the galleries looks like on my gf's new homepage:

Live long and prosper!

UniteGallery + OctoberCMS = Happy Photographer
Share this