thetuningspoon Posted July 3, 2013 Share Posted July 3, 2013 I recently completed a website that had a very large gallery requiring multiple albums (categories) and 100+ images per album with pagination. The solution I developed accomplishes this with just 2 templates (gallery-index and gallery-album) and a single multi-image field for each album, allowing for quick, mass upload of images*. One of the great things about ProcessWire is that you can custom build something like an image gallery with just the tools that the template system and API provide out of the box, without going in search of modules. Once we have the basic templates set up, we will use the excellent FancyBox jQuery script/plugin to add some slick Javascript "lightbox" functionality on top of it. The gallery will still work without FancyBox or with Javascript disabled; it will simply fall back to opening each image in a blank page. So, without further ado... 1. Create a file named gallery-index.php in your site/templates/ folder with the following code. This will be the main page of your gallery. The code simply loops through all of the photo albums that are children of your main gallery page and uses the first image in the album as the cover photo: <? include("./head.inc") ?> <? // Configure thumbnail width/height $thumbWidth = 250; $thumbHeight = 250; // Create an array of the child pages that use the gallery-album template $albums = $page->children('template=gallery-album'); ?> <h2><?= $page->title ?></h2> <div class="gallery"> <ul class="gallery-row row"> <? if(count($albums) > 0) { foreach($albums as $album) { // Grab the first image from the album and create a thumbnail of it $thumb = $album->images->first()->size($thumbWidth, $thumbHeight); ?> <li class="col span4"> <div class="gallery-album photoShadow"> <a href="<?= $album->url ?>" class="gallery-albumThumb" title="<?= $album->title ?>"> <img src="<?= $thumb->url ?>" alt="<?= $thumb->description ?>" /> <h4 class="gallery-albumTitle"><?= $album->title ?></h4> </a> </div><!-- /gallery-album --> </li><!-- /col --> <? } } ?> </ul><!-- /gallery-row --> </div><!-- /gallery --> <? include("./foot.inc") ?> 2. Add the gallery-index template in the ProcessWire admin under Setup->Templates. This template does not require any fields, although you may want to add a body field for outputting additional content to the page. 3. Create a file named gallery-album.php in your site/templates/ folder. This template will be used to both hold and display the images in your albums. Here we will be loading the fancybox plugin as well, so make sure you've downloaded it here: http://fancyapps.com/fancybox/ and uploaded the /fancybox/ folder to your site/templates/scripts/ folder. We are appending the fancybox files to the $config->scripts and $config->styles array before outputting them in our head.inc file so that we're only loading that code on the album pages. So make sure you are outputting those arrays in the <head></head> section of your head.inc file along with your other scripts & styles, like so: <? foreach($config->scripts as $file) { ?><script type="text/javascript" src="<?= $file ?>"></script> <? } ?> <? foreach($config->styles as $file) { ?><link rel="stylesheet" type="text/css" href="<?= $file ?>" /> <? } ?> Please note that you will also have to include jQuery in your head.inc file before your other scripts, if you're not already including it. So here is our gallery-album.php. Notice also that we are calling the FancyBox script and customizing some of its options at the bottom of the file: <? $config->styles->append($config->urls->templates . "scripts/fancybox/jquery.fancybox.css"); $config->styles->append($config->urls->templates . "scripts/fancybox/helpers/jquery.fancybox-thumbs.css?v=1.0.7"); $config->scripts->append($config->urls->templates . "scripts/fancybox/jquery.fancybox.pack.js"); $config->scripts->append($config->urls->templates . "scripts/fancybox/helpers/jquery.fancybox-thumbs.js?v=1.0.7"); // Configure thumbnail width/height & number of photos to display per page $thumbWidth = 150; $thumbHeight = 150; $imagesPerPage = 32; // Make ProcessWire pagination work on the images field (see for full explanation of this) $start = ($input->pageNum - 1) * $imagesPerPage; $total = count($page->images); $images = $page->images->slice($start, $imagesPerPage); // Create a new pageArray to give MarkupPagerNav what it needs $a = new PageArray(); // Add in some generic placeholder pages foreach($images as $unused) $a->add(new Page()); // Tell the PageArray some details it needs for pagination $a->setTotal($total); $a->setLimit($imagesPerPage); $a->setStart($start); include("./head.inc") ?> <?= $a->renderPager() ?> <div class="upOneLevel"><a href="<?= $page->parent->url ?>">← Albums</a></div> <h2><?= $page->title ?></h2> <div class="album"> <ul class="album-row row"> <? if(count($images) > 0) { foreach($images as $image) { $thumb = $image->size($thumbWidth, $thumbHeight); ?> <li class="album-photo darkenOnHover col span3"> <a href="<?= $image->url ?>" rel="fancybox-gallery" class="fancybox" title="<?= $image->description ?>"> <img src="<?= $thumb->url ?>" alt="<?= $thumb->description ?>" /> <!-- Uncomment this line if you want descriptions under images <p class="album-photoDescription"><?= $image->description ?></p>--> </a> </li> <? } } ?> </ul><!-- /album-row --> </div><!-- /album --> <div class="group"><?= $a->renderPager() ?></div> <script type="text/javascript"> $(document).ready(function() { $(".fancybox").fancybox({ prevEffect : 'elastic', nextEffect : 'elastic', loop : false, mouseWheel: true, helpers : { title : { type: 'outside' }, thumbs : { width : 100, height : 60 } } }); }); </script> <? include("./foot.inc") ?> 4. As we did before, add the gallery-album template in the ProcessWire admin. Assign the images field to it, and go into the URLs tab and make sure Page Numbers are allowed. 5. Create a page in the ProcessWire admin for the gallery index using the gallery-index template. You'll probably want to give it a title like "Gallery". 6. Underneath your Gallery page, create child pages that use the gallery-album template, one page for each album you want to create. Name them however you'd like. 7. Go into each album page you created and populate the Images field with your images. Just drag-and-drop. It's as simple as that! If you want to add a description for each image, you can also add it here. If you have more than 32 images (or whatever value you set the $imagesPerPage variable to), the pagination will kick in and split the album into multiple pages. 8. Finally, add in the CSS. The CSS is really up to you, but I'm including a good starting point below. This includes a handy responsive grid system I built for my sites, as well as a .photoShadow class I developed which gives your album covers a cool 3D Polaroid look using pure CSS. /********* Helper Classes **********/ .row:after, .group:after { content: ""; display: block; height: 0; clear: both; visibility: hidden; } .row { ; /* Remove left gutter */ margin-top: 0; margin-right: 0; margin-bottom: 0; padding: 0; zoom: 1; /* IE7 */ position: relative; } .col { display: block; float:left; margin-left: 2%; /* Gutter size */ margin-top: 0; margin-right: 0; margin-bottom: 0; padding: 0; zoom: 1; width: 95.99999999996%; } .span1 {width: 6.33333333333%;} .span2 {width: 14.66666666666%;} .span3 {width: 22.99999999999%;} .span4 {width: 31.33333333332%;} .span5 {width: 39.66666666665%;} .span6 {width: 47.99999999998%;} .span7 {width: 56.33333333331%;} .span8 {width: 64.66666666664%;} .span9 {width: 72.99999999997%;} .span10 {width: 81.3333333333%;} .span11 {width: 89.66666666663%;} .span12 {width: 97.99999999996%;} .photoShadow { position: relative; border: 5px solid #fff; background: #fff; -moz-box-shadow: 0px 0px 2px #ccc; -o-box-shadow: 0px 0px 2px #ccc; -webkit-box-shadow: 0px 0px 2px #ccc; -ms-box-shadow: 0px 0px 2px #ccc; box-shadow: 0px 0px 2px #ccc; } .photoShadow:before { z-index: -1; content: ""; display: block; position: absolute; width: 104%; height: 16px; bottom: -5%; left: -2%; overflow: hidden; border-radius: 50% 50% 0 0; box-shadow: inset 0px 8px 5px #999; } .darkenOnHover { opacity: .8; -webkit-transition: opacity .2s; -moz-transition: opacity .2s; -ms-transition: opacity .2s; -o-transition: opacity .2s; transition: opacity .2s; } .darkenOnHover:hover { opacity: 1; -webkit-transition: opacity .1s; -moz-transition: opacity .1s; -ms-transition: opacity .1s; -o-transition: opacity .1s; transition: opacity .1s; } /********** Blocks **********/ .gallery { } .gallery-album a:hover { text-decoration: none; } .gallery-albumTitle { font-size: 1.1em; text-align: center; margin: .2em ; } .gallery-album { -webkit-transition: all .2s; -moz-transition: all .2s; -ms-transition: all .2s; -o-transition: all .2s; transition: all .2s; } .gallery-album:hover { -webkit-transition: all .2s; -moz-transition: all .2s; -ms-transition: all .2s; -o-transition: all .2s; transition: all .2s; -webkit-box-shadow: 0 0 3px #555; -moz-box-shadow: 0 0 3px #555; -ms-box-shadow: 0 0 3px #555; -o-box-shadow: 0 0 3px #555; box-shadow: 0 0 3px #555; } .album-photo img { margin-bottom: 6px; border: 1px solid #ddd; } .upOneLevel { font-size: 1.1em; margin-bottom: .4em; } .upOneLevel .icon-circle-arrow-left { font-size: 1.5em; margin-right: .4em; } .upOneLevel a:hover { text-decoration: none; } .MarkupPagerNav { margin: 1em 0; font-family: Arial, sans-serif; float: right; } .MarkupPagerNav li { float: left; list-style: none; margin: 0; } .MarkupPagerNav li a, .MarkupPagerNav li.MarkupPagerNavSeparator { display: block; float: left; padding: 2px 9px; color: #fff; background: #2f4248; margin-left: 3px; font-size: 10px; font-weight: bold; text-transform: uppercase; } .MarkupPagerNav li.MarkupPagerNavOn a, .MarkupPagerNav li a:hover { color: #fff; background: #db1174; text-decoration: none; } .MarkupPagerNav li.MarkupPagerNavSeparator { display: inline; color: #777; background: #d2e4ea; padding-left: 3px; padding-right: 3px; } I think that's it! Just make sure you're including the CSS file in your head.inc inside the <head></head> tags and you should be all set. If you come across any issues trying to implement the above (or find any of it confusing) please let me know below. Everyone is coming from different backgrounds and different experience levels. And if you find this tutorial useful, please feel free to let me know as well * I should mention that although it is possible to create galleries in Processwire where each image is represented by its own page (and, as Ryan has mentioned, is often preferable since it is ultimately more scalable), sometimes the ease of using a single image field (which can upload and decompress zip files of images in mass) simply outweighs any drawbacks. If I had to create this gallery with the 1-image-per-page method, it would have taken hours to upload all of the images one-by-one without some sort of additional programming to automate the process. 14 Link to comment Share on other sites More sharing options...
kongondo Posted July 3, 2013 Share Posted July 3, 2013 (edited) Hi, Thanks for this tutorial! Thanks for taking the time to write it. I haven't finished reading it yet, but it looks very comprehensive, thanks . The question about image galleries has been coming up more often recently... Edit: Quick comment as I read...the term "single image field" might confuse some since you are not referring to an image field that only accepts one image (yet you state you uploaded multiple images), but you are stating you used one image field (that accepts multiple images), no? Maybe good to clarify that Finished reading: you give very clear, straightforward instructions. Many thanks! Edited July 3, 2013 by kongondo 2 Link to comment Share on other sites More sharing options...
kongondo Posted July 3, 2013 Share Posted July 3, 2013 Forum is misbehaving and mangling your code! Maybe include the CSS as an attachment? Link to comment Share on other sites More sharing options...
kongondo Posted July 3, 2013 Share Posted July 3, 2013 First question: I am not seeing an implementation of URL segments. Please explain to me (am new to this ) why you need URL segments for this? Thanks. Link to comment Share on other sites More sharing options...
thetuningspoon Posted July 4, 2013 Author Share Posted July 4, 2013 First question: I am not seeing an implementation of URL segments. Please explain to me (am new to this ) why you need URL segments for this? Thanks. You're right, that step should be unnecessary. Enabling page numbers should be enough. And yes, the forum editor behaves very erratically sometimes! Glad you found the tutorial to be user-friendly. Thanks for the feedback! Link to comment Share on other sites More sharing options...
Soma Posted July 4, 2013 Share Posted July 4, 2013 Thanks for writing a new tuto.If you want to have image pages without creating every page manually one by one, you can also use ImagesManager which has upload tool to directly create the pages. So the argument doesnt count ;-) 1 Link to comment Share on other sites More sharing options...
horst Posted July 4, 2013 Share Posted July 4, 2013 (edited) Hi everfreecreative,you have done a very good and useful write up here. Thank you very much.I want to drop two notes / suggestions / additions, - maybe. everfreecreative, on 03 Jul 2013 - 23:53, said:[...]* I should mention that although it is possible to create galleries in Processwire where each image is represented by its own page (and, as Ryan has mentioned, is often preferable since it is ultimately more scalable), sometimes the ease of using a single image field (which can upload and decompress zip files of images in mass) simply outweighs any drawbacks. If I had to create this gallery with the 1-image-per-page method, it would have taken hours to upload all of the images one-by-one without some sort of additional programming to automate the process. I also don't want to upload single images to single pages - but if you once have the need for a more scalable Gallery, you may use Somas ImagesManager to manage the creation of your gallery categories ( = albums) and to do the mass-upload by e.g. selecting up to 50 images at once and drag-drop them onto the upload field. (I don't know if IM supports upload via Zip's) everfreecreative, on 03 Jul 2013 - 23:53, said:[...]The gallery will still work without FancyBox or with Javascript disabled; it will simply fall back to opening each image in a blank browser window. Very good to support noscript, - but personally I don't like the opening in additional browser windows. You also can include a "single image view" to present the single images. With this, a visitor stays in a single window when browsing your galleries and doesn't get cluttered with mass _blank-windows. - But that's only _my_ preference. Many Greets. EDIT: hmm, - yeah, - I have had to do a phonecall during writing the post, - so now Soma has already pointed you to it Edited July 4, 2013 by horst Link to comment Share on other sites More sharing options...
kongondo Posted July 4, 2013 Share Posted July 4, 2013 Thanks for writing a new tuto. If you want to have image pages without creating every page manually one by one, you can also use ImagesManager which has upload tool to directly create the pages. So the argument doesnt count ;-) @Soma, Maybe it's time to put IM in the modules directory? Link to comment Share on other sites More sharing options...
thetuningspoon Posted July 4, 2013 Author Share Posted July 4, 2013 Hi everfreecreative, you have done a very good and useful write up here. Thank you very much. I want to drop two notes / suggestions / additions, - maybe. I also don't want to upload single images to single pages - but if you once have the need for a more scalable Gallery, you may use Somas ImagesManager to manage the creation of your gallery categories ( = albums) and to do the mass-upload by e.g. selecting up to 50 images at once and drag-drop them onto the upload field. (I don't know if IM supports upload via Zip's) Very good to support noscript, - but personally I don't like the opening in additional browser windows. You also can include a "single image view" to present the single images. With this, a visitor stays in a single window when browsing your galleries and doesn't get cluttered with mass _blank-windows. - But that's only _my_ preference. Many Greets. EDIT: hmm, - yeah, - I have had to do a phonecall during writing the post, - so now Soma has already pointed you to it Oh yes, the images don't open in additional browser windows. They open in the current window in a blank page. But I was having a hard time coming up with a way to word that--Fixed. Thanks to all who suggested ImagesManager. I didn't realize that was one of its features, so I'll have to check it out. But it is still an additional module, so I think my point is still at least partially valid Link to comment Share on other sites More sharing options...
Soma Posted July 4, 2013 Share Posted July 4, 2013 I think the point "without additional" coding or a module is a bit strange seeing all the code you needed to make this gallery... In that time you can code an simple upload module twice Link to comment Share on other sites More sharing options...
Soma Posted July 4, 2013 Share Posted July 4, 2013 Ohh I just got an idea for a module. What if you have a gallery type page you upload the images as usual to an images field. Then when saving the page there would be children created for each image and the ones removed from the gallery page. This would be very simple few lines of code. Sorry to hijack your thread. Nothing against the method to have one images field you store a gallery. If theres no metadata needed with no multilang and so on it is a pretty good and simple way to a simple gallery. I use it myself too. 7 Link to comment Share on other sites More sharing options...
kongondo Posted July 4, 2013 Share Posted July 4, 2013 One issue I foresee with the "one-image-per-page" approach is editing. If I have hundreds of images and I wanted to delete some and I could only tell them apart by actually looking at the images, it could take quite some trawling to find and delete them in the admin.... Btw, @everfreecreative, your "one-page-per-album" could play nice with a recent tweak that Soma created for a forum member that allows multiple images on a page to be displayed in a multiple grid rather than in a single column/vertical grid. I can't find the post at the moment. Another btw (sorry). There was a question recently about finding and displaying a limited number of images from various albums and displaying those in a gallery page. I'm not sure whether that was answered. I'm just thinking out loud here whether your approach could also solve that issue. Anyway, I digress... Link to comment Share on other sites More sharing options...
thetuningspoon Posted July 4, 2013 Author Share Posted July 4, 2013 Actually, kongondo, there's an app... err, module for that too. I dont remember what it's called, but it can show thumbnails next to your pages in the list. Link to comment Share on other sites More sharing options...
kongondo Posted July 4, 2013 Share Posted July 4, 2013 (edited) What I meant is this: You know when you view a page with images, they are normally displayed vertically on the page and if there's multiple images, it means lots of vertical scrolling. The solution I am talking about would arrange the images on a 3x3 grid on the page..Is that what you mean as well? Edit: Here's the post I refer to http://processwire.com/talk/topic/3919-individual-image-field-widths-float-display-inline/ Edited July 4, 2013 by kongondo Link to comment Share on other sites More sharing options...
thetuningspoon Posted July 4, 2013 Author Share Posted July 4, 2013 No, my reply was in regard to your first paragraph about being able to identify and delete/edit images easily when using one page per image. Having a grid instaed of just a single column in the admin could be very helpful, I agree. 1 Link to comment Share on other sites More sharing options...
kongondo Posted July 4, 2013 Share Posted July 4, 2013 I get you now. Thanks. Link to comment Share on other sites More sharing options...
alan Posted March 4, 2014 Share Posted March 4, 2014 Thanks for the tut everfreecreative, very good write-up and super-helpful Link to comment Share on other sites More sharing options...
thetuningspoon Posted March 5, 2014 Author Share Posted March 5, 2014 Thanks for the tut everfreecreative, very good write-up and super-helpful Thanks. Glad you think so! Link to comment Share on other sites More sharing options...
OrganizedFellow Posted March 20, 2014 Share Posted March 20, 2014 VERY well written and easy to follow! I've bookmarked it for a future project. Thank you! Link to comment Share on other sites More sharing options...
PhotoWebMax Posted March 30, 2014 Share Posted March 30, 2014 Nice to see this... Say, is there a live site we can this in action? Link to comment Share on other sites More sharing options...
Marty Walker Posted March 30, 2014 Share Posted March 30, 2014 Ohh I just got an idea for a module. What if you have a gallery type page you upload the images as usual to an images field. Then when saving the page there would be children created for each image and the ones removed from the gallery page. This would be very simple few lines of code. Sorry to hijack your thread. Nothing against the method to have one images field you store a gallery. If theres no metadata needed with no multilang and so on it is a pretty good and simple way to a simple gallery. I use it myself too. Go on then! Currently I'd use Batcher or CSV Import to do that. You way sounds much quicker. 2 Link to comment Share on other sites More sharing options...
PhotoWebMax Posted April 19, 2014 Share Posted April 19, 2014 Sorry, I tried this but no images or thumbs show on my page... I get this message: Error: Call to a member function first() on a non-object (line 24 of /Applications/MAMP/htdocs/ProcessWire-SREP/site/templates/gallery-index.php) This error message was shown because you are logged in as a Superuser. Error has been logged. Link to comment Share on other sites More sharing options...
thistimj Posted April 21, 2014 Share Posted April 21, 2014 Hey PhotoWebMax, did you figure this out? It may be that you have your images field set to hold only one image. I think I've had this problem before. If you go into the admin, under the image field, click on details and change the maximum files allowed to 0 (if you want unlimited) or whatever number you want that's higher than 1. I think that should cause the "first()" function to kick in. Link to comment Share on other sites More sharing options...
PhotoWebMax Posted April 21, 2014 Share Posted April 21, 2014 No, sorry, I decided to back out of trying it this way. I had several templates and test gallery pages that were not working so I scrapped them all and started over from scratch. I created this thread of my journey to image gallery success here: https://processwire.com/talk/topic/6158-photography-galleries-best-solution/ *** I am quite a ways from reaching success though... Link to comment Share on other sites More sharing options...
thetuningspoon Posted April 21, 2014 Author Share Posted April 21, 2014 Sorry, I tried this but no images or thumbs show on my page... I get this message: Error: Call to a member function first() on a non-object (line 24 of /Applications/MAMP/htdocs/ProcessWire-SREP/site/templates/gallery-index.php) This error message was shown because you are logged in as a Superuser. Error has been logged. Hi PhotoWebMax. The error you're getting is where the first image from each album is grabbed to create an album thumbnail. Since I don't have any error checking here (oops) I think you might get this error if you have no albums, have empty albums, or your albums aren't using a template with the name gallery-album (as described in my setup instructions). To be sure, I'd need to see the site you're working on. Here is a site that uses this gallery system: http://www.maranathafamilyministries.org/photo-gallery/ Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now