Silverstripe Image Gallery Tutorial

by frank on June 10, 2010

in Featured, SilverStripe

I have had a few issues installing image gallery modules on Silverstripe 2.4. I’m new to using silverstripe so this is a beginners tutorial, the aim is to install a basic image gallery which fits the following criteria:

  • Allow CMS users to upload photos
  • Add custom fields to be associated with each image (such as title, caption etc.)
  • Display the images using a javascript image gallery of my choice

Another goal of this exercise was to better understand silverstripe – so the solution is simple, but effective and suitable for our needs.

What you will need for this image gallery:

Install SWFUpload

Get the SWFUploadField plugin – I checked out the latest revision from the repository. After that all that is requried is to place the swfupload folder in the root directory of your silverstripe install (the folder that contains the cms, mysite, themes, sapphire folders). Then run a /dev/build – in my instance it didn’t seem like anything was built or at least no database fields were added or changed, don’t worry if this is the case for you.

Note: rename the module folder to “swfupload” before placing in the root dir.

Install DataObjectManager

Again I checked out the latest revision from the repo. Following the same process again, moving the dataobject_manager folder into the root of the silverstripe install then running /dev/build.

Note: rename the module folder to “dataobject_manager” before placing in the root dir.

Create the Image class

This is where we can specify which fields we want to associate with each image in our gallery by creating a class that will represent each image. I have called my class ImageResource – you can call yours what you like as long as there is no naming clash with existing classes (there is already an Image class in ss for example).

<?php 
// /mysite/code/ImageResource.php
class ImageResource extends DataObject
{
    static $db = array (
        'Title' => 'Text',
        'Caption' => 'Text'
    );
 
    static $has_one = array (
        'Attachment' => 'Image', //Needs to be an image
        'GalleryPage' => 'GalleryPage'
    );
 
    public function getCMSFields_forPopup()
    {
        return new FieldSet(
            new TextField('Title'),
            new TextareaField('Caption'),
            new FileIFrameField('Attachment')
        );
    }
}

The fields I have added are Title and Caption – I want each image in the gallery to be able to have a title and a caption. The Attachment is a type of Image, rather than a type of file such as in the DataObjectManager documentation, as noted on this thread.

Create the Gallery Page

This is the type of page you are going to create in the CMS in order to add images to the gallery and display the photos on the website.

<?php
// /mysite/code/GalleryPage.php
class GalleryPage extends Page
{
    static $has_many = array (
        'Images' => 'ImageResource'
    );
    public static $db = array(
    );
    public static $has_one = array(
    );
 
    public function getCMSFields()
    {
        $f = parent::getCMSFields();
        $manager = new ImageDataObjectManager(
            $this, // Controller
            'Images', // Source name
            'ImageResource', // Source class
            'Attachment', // File name on DataObject
            array(
                'Title' => 'Title', 
                'Caption' => 'Caption'
            ), // Headings 
            'getCMSFields_forPopup' // Detail fields
            // Filter clause
            // Sort clause
            // Join clause
        );
        $f->addFieldToTab("Root.Content.Gallery",$manager);
        return $f;
    }
}
 
class GalleryPage_Controller extends Page_Controller {
}

Note that this page has many Images that are types of ImageResource objects. The ImageDataObjectManager takes care of the interface in the CMS which will handle the CRUD for the images. One problem I had when following the documentation was the lack of Controller on the Page classes, so adding the GalleryPage_Controller class sorted out a few issues for me.

Create the Gallery layout view

A basic view to loop over the images and display them on the page:

<!-- /themes/yourtheme/templates/Layout/GalleryPage.ss -->
<% control Images %>
<ul>
	<li>$Title</li>
	<li>$Caption</li>
	<li>$Attachment.SetRatioSize(150,150)</li>
</ul>
<% end_control %>

Build

Now that the gallery page and image classes are set up, run a /dev/build – you should now be able to create a Gallery Page in the CMS. When editing that gallery page there should be a tab in “Main” called Gallery where you should be able to add a number of images at once, cycle through and add a title and/or caption for each. A

fter adding images and publishing the page, view the page on your site and each image should be crudely displayed on screen along with the title and caption if they exist. At this stage you should have a working image gallery, all we need to do is tidy up the html and incorporate some kind of javascript gallery to cycle through the photos.

Adding a jquery gallery plugin

I have had issues adding jquery plugins in the past mostly because of conflicts with multiple libraries declaring the $() function. I avoided these problems in this case, but I’m not sure if adding a form to the gallery page might conflict – the SilverStripeNavigator seems to load fine.

Download fancybox and have a look at the example index.html file to see what files are included and how to invoke the fancybox. Essentially what we need is the fancybox.js file (jquery.fancybox-1.3.1.js), the css file (jquery.fancybox-1.3.1.css), the images (in /fancybox/) and a way to invoke the fancybox on our gallery page ourselves (our own gallery.js script).

I copied the javascript files required into a directory in my themes folder: /themes/yourtheme/js/. I used jquery 1.4.2 which was poached from /sapphire/thirdparty/jquery/. Then I grabbed the js file for fancybox and also created a small script to load the gallery – all together the following files were loaded from the /js/ folder:
jquery.js
fancybox.js
gallery.js

I copied the css file for fancybox to /themes/yourtheme/css/fancybox.css, being sure to replace the references to images in the css file so that the paths are correct. This required changing url(‘ to url(‘../images/fancybox/ throughout the file.

I copied all the images for fancybox to the /themes/yourtheme/iamges/fancybox/ folder.

In order to grab the javascript and css files for the gallery overload the init() method of the GalleryPage_Controller:

class GalleryPage_Controller extends Page_Controller {
    function init() { 
           parent::init();
 
          //Include fancybox Code 
          Requirements::javascript('themes/hula/js/jquery.js'); 
          Requirements::javascript('themes/hula/js/fancybox.js'); 
          Requirements::javascript('themes/hula/js/gallery.js'); 
          Requirements::themedCSS('fancybox'); 
    }
}

Invoking the fancybox

To avoid the conflicts of $() my gallery.js uses noConflict():

$.noConflict();
jQuery(document).ready(function($) {
	// Code that uses jQuery's $ can follow here.
	$("a[rel=example_group]").fancybox({
		'transitionIn'		: 'none',
		'transitionOut'		: 'none',
		'titlePosition' 	: 'over',
		'titleFormat'		: function(title, currentArray, currentIndex, currentOpts) {
			return '<span id="fancybox-title-over">Image ' + (currentIndex + 1) + ' / ' + currentArray.length + (title.length ? ' &nbsp; ' + title : '') + '</span>';
		}
	});
});

As you can see I have pulled this straight from the fancybox example (even preserving the example_group naming :-s). Update the gallery view to something like:

<% control Images %>
  <a rel="example_group" href="$Attachment.URL" title="$Caption">$Attachment.SetRatioSize(150,150)</a>
<% end_control %>

Reloading the gallery page with ?flush=1 should see you viewing a nice fancybox gallery!

Notes

Much of this tutorial is dependent on the work of Uncle Cheese – such as the DataObjectManager and the SWFUploadField modules. Uncle Cheese also has an Image Gallery module, which I had some issues with installing on SilverStripe 2.4 but your mileage might vary. Check out Uncle Cheese’s blog LeftAndMain.

Update:

I had some problems with SWFUpload whereby certain computers could not upload files, continuously getting errors such like:
Error #2044: Unhandled IO Error Event. Error #2038 File I/O Error.
Other computers could upload files fine.

At the root of the problem was an HTTP Status code being returned by the server: 406 Not Acceptable.

The solution for us was this one line in the .htaccess file to turn OFF mod_security:

<IfModule mod_security.c>
SecFilterEngine Off
</IfModule>

If you have the flashblock add on for firefox then make sure to add the domain to your whitelist! You may get an error like: the method ‘admin’ does not exist on ‘ImageDataObjectManager’.

See this silverstripe post for more details
Here is a related SWFUpload issue

If you want to reorder images in the gallery just enable sorting for the data object manager in mysite/_config.php using:

SortableDataObject::add_sortable_class('ImageResource');

Then perform a /dev/build?flush=1 for the DataObjectManager to create the sort columns on the data object ‘ImageResource’.

I am now using the Uploadify module instead of SWFUpload. Switching over is simply a matter of removing the SWFUpload folder and replacing with the Uploadify module.

A web hosting company based in New Zealand had to additionally apply these settings for uploadify (and I suspect swfupload) to work:

suhosin.session.cryptua=off
suhosin.session.encrypt=off

I have created a simple image gallery module which uses much of the same principles from this article, you can download the code from the silverstripe-simplegallery GitHub repository.

Was this article useful?

rss feed icon

Email this article to yourself or...

rss feed icon

Subscribe to the RSS feed for more useful articles and tips.

Share this article with others

  • del.icio.us
  • Twitter
  • Reddit
  • StumbleUpon
  • Facebook
  • Digg
  • Sam

    Hi.
    Thanks for your tutorial.
    It’s more explicit that the SilverStripe documentation.

    But do you know why I get this error :
    Class ‘ImageDataObjectManager’ not found in /opt/lampp/htdocs/www/silverstripe-v2.4/mysite/code/GalleryPage.php on line 20

    i don’t understand why because my dataobject_manager folder is at the root :
    /opt/lampp/htdocs/www/silverstripe-v2.4/dataobject_manager/

  • frank

    PHP might not know what file to look in for that class ImageDataObjectManager. Try explicitly requiring the file which contains that class at the top of GalleryPage.php. If it fixes that particular error, you might need to add the path /opt/lampp/htdocs/www/silverstripe-v2.4/ to your $PATH variable? You need help loading classes in PHP basically, its probably a generic problem and not related to ss or the data object manager specifically…

  • http://allebrum.wordpress.com Senica

    Thanks! I’m not building a gallery, but this helped me out a lot with another problem.

  • Carsten

    hi frank, how can i tell the image control to show only the first 8th images? i havent found the place to subclass the image function! Can you please help?

    Greetings, Carsten.

  • frank

    Do you mean in the view or in the CMS area? In the view you might be able to write a controller method to just return the first 8 images and call that from the view…

  • carsten

    Hi Frank, i have tried to add multiple images to the pages with pagetype “page”. But if i use your example on page.php i get a bad class to singelton(). Do you have an idea what i have to do to get this working?

    Greetings, Carsten.

  • frank

    Hey Carsten,

    Sounds like you are using Page.php instead of GalleryPage.php? I’m not sure what the problem is but in ImageResource under has_one does that have Page => Page instead of GalleryPage => GalleryPage?

  • GiBmo

    Hi Frank, I am not a scripting wizzard. Not even small loading scripts. So can you tell me wherw I can find tyhe gallery.js?

  • GiBmo

    Sorry Frank,

    Do not bother to comment my previous post. I overlooked it!

    Anyway. Thanks for your nice tutorial!

  • frank

    No problem, thanks for the feedback

  • GiBmo

    One more thing however. The gallery works fine but I noticed there are no navigation buttons when using IE8

  • frank

    Only when using IE8? Might be an idea to try another jquery image gallery or download fancybox and try the demo that is usually bundled with the download on all browsers. Make sure the file path to the images used for navigation buttons is correct.

  • William Notowidagdo

    Hi,
    Thanks for this great tutorial.

    However, I’m having an “IO Error” issue when I tried to uload an image.
    I’ve tried to turn off mod_security but it’s now working.

    The image upload function is working fine on my local, but not in my server.

    Is there any workaround for this?

  • frank

    I have just had a similar issue on a web hosting provider, still waiting to hear what they changed at their end. In this case mod_security was not enabled on the server so I’m not sure they had to change, you should question your hosting company about it. If I find out any more I’ll update the article.

  • William Notowidagdo

    Thanks for your quick reply Frank.
    I’ll update my findings.

  • frank

    Hey William, the hosting company had to apply these settings to get rid of the IO error I was having with uploadify:
    suhosin.session.cryptua=off
    suhosin.session.encrypt=off

  • William Notowidagdo

    Hi Frank,

    Where they should apply it? php.ini?
    Thanks.

  • frank

    Not sure, best to ask your hosting company I think.

  • Gullu

    I am helping a non profit organization and new to silverstripe. I am trying to do a photo gallery. It is creating all the folders in assets. When it comes to adding photos inside album it is not showing the upload button. It just has a browse button and a continue button, when I try to browse and hit continue button nothing happens. No errors and no photos are added too. I followed the image gallery video. I have installed dataobject_manager, image_gallery and uplodify modules. Please help.

  • frank

    Can’t help you with the image_gallery module I’m afraid because I haven’t used it. You could follow the tutorial on this page and quickly try out this technique. Make sure your assets folder is writeable by the webserver, try and have a look at the headers being sent back and forth for any other clues and try viewing the apache error logs for clues there. You could get help from the author (Aaron Carlino aka Uncle Cheese) of all those modules here: http://leftandmain.com or try the SilverStripe forums or IRC channel: http://silverstripe.org/forums and http://silverstripe.org/irc-channel/

  • Joseph

    Why all the pages sharing the same gallery?
    for example, I create a new page, but the gallery is always being shared.

  • frank

    @Joseph not sure why that is. I don’t think this method works if you want to have 2 galleries on one page both pointing to the same kinds of DataObjects. But you should be able to create 2 pages with completely seperate galleries fine…

  • Jose Luis

    Hi Frank,

    What about the resized image settings. Where can I config this?

    Thanks for your nice tutorial.

  • frank

    @Jose I just resize images in the template files…

  • Thomas

    Hello

    I’m trying to use your tutorial it works fine exept that I see the image but not the tite and caption (they are not dispyed in html source either)

    Any hint

    Thanks

  • frank

    Perhaps make sure that you are not inside a control for the attachment in the template. The attachment will not have the title and caption but the ImageResource DataObject will. HTH

  • thomas

    Hello

    Thanks for your answer it is working now.
    I wanted also to know if you new a way of adding the drag and drop reordering option for the images ?

    Thanks

    Thomas

  • thomas

    Hello again I found the solution

    you have too add in mysite/_config.php the following :
    SortableDataObject::add_sortable_classes(array(‘ImageResource’));

    Hope it will help

  • flare

    Hi
    I’ve got an issue with the $Attachment.SetRatiosize. If I set it $Attachment the image is displayed. If I use $Attachment.SetRatioSize(150,150) nothing is shown.

    Any ideas ?

    Thanks

  • Katie

    Hi Frank
    Where do I find gallery.js? Do I copy another .js file and amend it?

  • Anonymous

    Yes, you just create your own gallery.js file, you can use content similar to the code under the ‘Invoking the fancybox’ heading above.

  • Anonymous

    Hi flare, maybe make sure that your web server has write permissions on the _resampled folder in your assets folder where the image you are trying to resize lives. What might be happening, the webserver is trying to resize the image and save it to a _resampled folder but doesn’t have permission.

  • Katie

    Using the Uploadify module also works a treat

  • flare

    Hi frankmullenger

    You were correct it was permissions.

    Next query – can the order of the pictures being displayed be determined ? We have added 30 plus photos in one gallery and the last 4 end up on the live page in the middle of the gallery.

    Thanks

  • Anonymous

    @flare you can use this line to make the images sortable in the CMS:
    SortableDataObject::add_sortable_class(‘ImageResource’);

    Do a rebuild and then in the CMS you should be able to drag and drop the images.

  • Rod Dalgety

    Did you ever figure this out? I’m having the same problem.

  • Anonymous

    You might want to try running a /dev/build?flush=1 or something like that

  • Phil

    Hi

    That code allows the images on the gallery tab to be reordered. My problem is in the way the images are displayed on the published page. The order is correct in the gallery tab, but incorrect on the published page.

    Any ideas ?

    Thanks

  • Arunj Reubro

    hi
    pls help me! to add photo gallery with pagination.

  • Anonymous

    Hi Arunj, its a bit late here in NZ, but if you want to show me some of your code happy to take a look in the morning. I just had a quick look on sspaste, is this your problem? : http://sspaste.com/paste/show/4ec0b3457dd02

  • Anonymous

    Hi Arunj, I answered your question about pagination here: http://deadlytechnology.com/silverstripe/bare-bones-silverstripe-image-gallery-module/

    Let me know if that doesn’t work for you.

  • http://customdesigns.co.nz custom designs

    Hi, does this work if the browser does not have javascript enabled?

  • Anonymous

    The javascript stuff won’t work no. But you can still display the images on the page without the need for javascript, the js is just there to pop open a lightbox and display a larger version of the image basically. HTH.

  • http://www.jarleart.dk/ Chris

    Hi, a very useful for someone without skills programming skills :)

    I have one problem though. The fancybox gallery will pop up, but I cant browse the picture or close it again.

    I don’t know how to make it work, has any experienced the same problem?