Pinterest-like gallery tutorial

After two post demos Pinterest-like galleries demo 1 and Pinterest-like galleries demo 2 infinite scroll and a lot of work, the Pinterest-like gallery tutorial is here. Just like any good food recipe I will start by listing the items needed; this will also allow me to give credit to the scripts used in the tutorial.

The List

jQuery library (included with WordPress )
ajax.php file
pinterest.js file
Masonry jQuery Plugin
ColorBox jQuery Plugin (included with Image Store)
Image Store WordPress Pluign ( version 3.0.4 or higher)

Image Store Hooks

We will start by adding a few hooks to modify the default Image Store’s short-code display, add the comment count bellow the images, load the Masonry jQuery plugin and add the javascript variables to support ajax calls.

Add the following code to your theme’s functions.php file. This will load the Masonry script. This will load the scripts to the single post page, if you want to load it throughout the site remove “if ( is_single( ) )“. Modify the file path as needed.

function print_mansory_theme_scripts( ){
	if ( is_single(  ) )
		wp_enqueue_script( 'masonry', get_template_directory_uri() . '/_js/jquery.masonry.min.js', array( 'jquery' ), '2.1.03', true );
	//this line may not be required if you have already a javascript file where to load the javascript functions.
	wp_enqueue_script( 'pinterest', get_template_directory_uri() . '/_js/pinterest.js', array( 'jquery', 'masonry' ), '1.0.0',true );
}add_action( 'wp_print_scripts', 'print_mansory_theme_scripts' );

We need ajax support, create a new file called ajax.php and save it on the root of your theme’s folder. Don’t add any code, just leave it blank will come back to it. We will add a variable to the Image Store’s javascript localize object. Add the following code to your functions.php file.

function add_ajaxurl_to_ims_object( $options ){
	$options['wpajaxurl'] =  get_template_directory_uri() . "/ajax.php";
	$options['imsajaxnonce'] = wp_create_nonce("imsajaxnonce");
	return $options;
}add_filter('ims_localize_js', 'add_ajaxurl_to_ims_object');

The following function is a bit long, but all it does is add the latest 3 comments at the bottom of each image and displays the current comment count that links back to the comments form.

function shortcode_after_ims_image( $string, $image, $atts ){
	if( $atts['layout'] != 'pinterest' ) //make sure we are only adding this code to the 'pinterest' layout
		return $string;

	$parent = wp_get_post_parent_id( $image->ID );
	$num_comments = get_comments_number( $image->ID );

	//get the right comment count display
	if( $num_comments == 0 )
		$comment_count =  __('No comments');
	elseif( $num_comments > 1)
		$comment_count =  $num_comments. __(' Comments');
	else $comment_count = $num_comments. __(' Comment') ;

	//list the latest 3 comments on the image
	$comments = get_comments( array('number'=> 3, 'post_id' => $image->ID, 'status' => 'approve'));
	if( !empty( $comments ) ){
		$clist .= '<ul id="ims-comments-'.$image->ID.'" class="ims-commentlist">';
		foreach( $comments as $comment ){
			$GLOBALS['comment'] = $comment;
			$clist .= '<li id="li-comment-'.$comment->ID.'"><article id="comment-'.$comment->ID.'" class="comment">';
			$clist .= '<div class="comment-author vcard">' . get_avatar( $comment, 30 ) . '</div>';
			$clist .= '<div class="comment-content">' . get_comment_text( $comment->ID ) .'</div>';
			$clist .= '</article></li>';
		}
		$clist .= '</ul>';
	}

	return '<div class="img-metadata img-data-'. $image->ID .'" >'.$clist . get_post_reply_link( array( 'reply_text' => $comment_count ), $image ) . '</div>';

}add_filter( 'ims_shortcode_after_image', 'shortcode_after_ims_image',10, 3);

Short-code

Now create a new post and add the following short-code, be sure to replace the gallery id with one from your site. Notice that gallery layout is ‘pinterest’ our previous php function is looking for this value. To learn more about Image Store’s short-code, view the usage page.

[ims-gallery id=THEGALLERYIDNEEDSTOBECHANGE caption=true size=preview layout=pinterest]

Styles

If you preview your newly created post, you will see the gallery is displaying with the caption and comment count, we just need to adjust the layout. Ads the following style rules to your theme’s style.css file. Additional changes maybe required depending on your theme and desired display.

.ims-gallery .ims-img .gallery-caption{ text-align:center; padding:0 1em; font-size:.8em; min-height:5.2em; line-height:120%}

.post .ims-gallery{ margin-right:-14px}
.post .ims-gallery .ims-img{ float:left; width:29%; max-width:29%; margin:0 0 15px 15px; padding:0;
-o-box-shadow:0 1px 5px #aaa; -moz-box-shadow:0 1px 5px #aaa;-khtml-box-shadow:0 1px 5px #aaa; box-shadow:0 1px 5px #aaa;border:solid 1px #fff}
.post .ims-gallery .ims-img img{ width:100%; height:auto; border:none;-o-box-shadow:none; -moz-box-shadow:none;-khtml-box-shadow:none; box-shadow:none}
.post .ims-gallery .ims-img a.ims-pinterest{ padding:10px 10px 0; background:#fff; display:block}
.post .ims-gallery .ims-img .comment-reply-link{ display:block; clear:both; text-align:center}
.post .ims-gallery .ims-img .gallery-caption{ color:#999; padding:.5em; font-size:.8em; line-height:120%; text-align:center; height:auto; min-height:inherit}

.ims-gallery .ims-img .ims-commentlist img{ width:auto; height:auto}
ul.ims-commentlist{ margin:0; padding:0; background:#f6f6f6; }
ul.ims-commentlist li{ padding:0; margin:0; padding:5px; list-style:none; font-size:12px; min-height:30px; border-bottom:solid 1px #ccc; border-top:solid 1px #fff}
ul.ims-commentlist li .vcard{ float:left}
ul.ims-commentlist li .comment-content{ margin-left: 40px; line-height:130%}

Javascript

Here comes the fun part, adding the javascript functions. First create a new file called “pinterest.js” save it in YOUR-THEME-DIRECTORY/_js/pinterest.js. If you changed the file path in the “hooks” section be sure to save it on the right location. Open the file and will star working on it.

The first thing we need to do is check if the page and Masonry plugin is loaded.

 jQuery(document).ready(function($){
	if( jQuery.Mason ){

	}
});

Lets add some default values and target the image store galleries.

 jQuery(document).ready(function($){
	if( jQuery.Mason ){
		var current = time = 0;
		var selector	= '.ims-img';
		var $container 	= $('.single-post #content .ims-gallery');
		var count 	= $container.find( selector ).length;
	}
});

Now we’ll call the Masonry function. Since I have a dynamic layout on my page I want to be sure that it displays properly on all devices. If the width of the main column is less the 350px display 2 columns else 3 columns. To learn more about the setting view the Masonry options page.

 jQuery(document).ready(function($){
	if( jQuery.Mason ){
		var current = time = 0;
		var selector	= '.ims-img';
		var $container 	= $('.single-post #content .ims-gallery');
		var count 	= $container.find( selector ).length; 

		$container.imagesLoaded( function(){
		  $container.masonry({
			 isAnimated: true,
			 itemSelector: selector,
			 columnWidth: function( containerWidth ) {
				//if page container width is less than 350 display 2 columns
				if (  containerWidth < 350)
					return containerWidth / 2;
				//else display 3 columns
				else return containerWidth / 3;
			  },
			  animationOptions: {
			  	complete: function() {
					time = false;
				}
			  }
		  });
		});
	}
});

The following will bind the Colorbox function the galleries.

 jQuery(document).ready(function($){
	if( jQuery.Mason ){

		var current = time = 0;
		var selector	= '.ims-img';
		var $container 	= $('.single-post #content .ims-gallery');
		var count 	= $container.find( selector ).length; 

		$container.imagesLoaded( function(){
		  $container.masonry({
			 isAnimated: true,
			 itemSelector: selector,
			 columnWidth: function( containerWidth ) {
				//if page container width is less than 350 display 2 columns
				if (  containerWidth < 350)
					return containerWidth / 2;
				//else display 3 columns
				else return containerWidth / 3;
			  },
			  animationOptions: {
			  	complete: function() {
					time = false;
				}
			  }
		  });
		});

		if( jQuery.colorbox ){
			cbOptions = { photo:true, preloading: true }
			$container.find( '.ims-pinterest').colorbox( cbOptions );
		}
	}
});

If you like the infinite scroll demo here is where we make things happen; just add the following code. If you have a footer or any content bellow your gallery adjust the “offset” variable. Ignore the fallowing section if you don’t want the infinite scroll.

 jQuery(document).ready(function($){
	if( jQuery.Mason ){

		var current = time = 0;
		var selector	= '.ims-img';
		var $container 	= $('.single-post #content .ims-gallery');
		var count 	= $container.find( selector ).length; 

		$container.imagesLoaded( function(){
		  $container.masonry({
			 isAnimated: true,
			 itemSelector: selector,
			 columnWidth: function( containerWidth ) {
				//if page container width is less than 350 display 2 columns
				if (  containerWidth < 350)
					return containerWidth / 2;
				//else display 3 columns
				else return containerWidth / 3;
			  },
			  animationOptions: {
			  	complete: function() {
					time = false;
				}
			  }
		  });
		});

		if( jQuery.colorbox ){
			cbOptions = { photo:true, preloading: true }
			$container.find( '.ims-pinterest').colorbox( cbOptions );
		}

		$(window).scroll(function(){
			offset = 500;
 			 if ( $(window).scrollTop() >= $(document).height() - $(window).height() - ($('#colophon').height() + offset ) ){
				if( count > 0 && !time ){
					current += count;
					id =  $container.attr('id').replace('ims-gallery-','')
					time = setTimeout( $.post(  imstore.wpajaxurl, {
						'action':'ims_iscroll',
						'ajaxnonce': imstore.imsajaxnonce,
						'current': current,
						'count': count,
						'galleryid': id
					}, function( data ){
						if( data != 0 ){
							var content = $( data ).find( '.ims-img' )
							if( jQuery.colorbox )
								content.find('.ims-pinterest').colorbox( cbOptions );
							$container.append( content ).masonry( 'reload' );
						  }else $container.masonry( 'reload' );
					}), 50 );
				}
			}
		});
	}
});

Ajax for Infinite Scroll

if you are implementing the infinite scroll you will notice that we are making ajax calls this is where our “ajax.php” comes into play. Located the file and add the following code be sure that the file is in the right location or it will not work.

<?php
//dont cache file
header( 'Last-Modified:'.gmdate( 'D,d M Y H:i:s').' GMT' );
header( 'Cache-control:no-cache,no-store,must-revalidate,max-age=0' );

//load wp
require_once '../../../wp-load.php';
function ajax_ims_iscroll( ) {

	if( !wp_verify_nonce( $_POST['ajaxnonce'], 'imsajaxnonce' ))
		die( );

	global $ImStore;
	require_once( IMSTORE_ABSPATH . '/_store/shortcode.php' );

	$count = $_POST['count'];
	$current = $_POST['current'];

	$shortcode = new ImStoreShortCode();

	$shortcode->attachments = array();
	$shortcode->galid  = $_POST['galleryid'];
	$shortcode->limit  = "$current, $count";
	$shortcode->order = $ImStore->opts['imgsortorder'];
	$shortcode->sortby = $ImStore->opts['imgsortdirect'];

	$shortcode->get_galleries( );
	if( !empty($shortcode->attachments) )
		echo $shortcode->display_galleries( array('layout'=>'pinterest', 'caption'=>true) );
	die();
 }
 if( isset( $_POST['action'] ) && $_POST['action'] == 'ims_iscroll' )
 	ajax_ims_iscroll( );
die();

That is it now, your site is ready to display galleries just like Pinterest. If you have any question please leave a comment and if you liked the tutorial please share it.

6 Comments on “Pinterest-like gallery tutorial

  1. Quiteria Guardado Baeza says:

    I will immediately snatch your rss feed as I can not to find your email subscription hyperlink or e-newsletter service. Do you

  2. Gabi says:

    I have this problem:

    Warning: call_user_func_array() [function.call-user-func-array]: First argument is expected to be a valid callback, ‘shortcode_after_image’ was given in /home/gabinerds/gabitardivo.com/pio/wp-includes/plugin.php on line 170

    :/

  3. Hax says:

    Sorry, there was a mistake on the tutorial replace
    add_filter( 'ims_shortcode_after_image', 'shortcode_after_image',10, 3);
    with
    add_filter( 'ims_shortcode_after_image', 'shortcode_after_ims_image',10, 3);
    The mistake was in the hooks section code just before the shortcode section. I fixed it and is good now.

  4. Laura says:

    Hi there,
    Most of the gallery worked, but for some reason the pictures I have aren’t lining up like they’re supposed to right underneath one another.

  5. Hax says:

    if the elements aren’t aligning there must be some sort of error in your javascript, or the gallery can’t be found by the javacript.

Comments are closed.