Scope's portfolio page is a perfect example of
Isotope exquisiteness. Only thing that I missed was the possibility to link directly to a specific portfolio type (eg. link from
Homepage directly to
Photos in my
Portfolio, sending link to a friend..). The only way I found to do this, was to link directly to the post type page (/portfolio-type/photos/), but you were not able to see animated list of the other portfolio types there anymore...
So, how to solve this problem without breaking no-javascript compatibility? And wouldn't it be even cooler, if you had hash history and bookmarkable links, too?
Ben Alman’s
jQuery BBQ plugin allows you to do just that.
jQuery BBQ leverages the HTML5 hashchange event to allow simple, yet powerful bookmarkable #hash history.
I'll guide you step by step through the solution I've come up with.
1. Adjust portfolio type links
Instead of setting the portfolio type with
data-filter
attribute, you can add the option in the
href
for each link (you can combine these two methods), changing the link from
/portfolio-type/photos/
to
/portfolio-type/photos/#filter=.photos
This will also provide the basic functionality, if JavaScript is turned off in the user's web browser.
To do this, you just have to modify the
Portfolio_Walker()
class located in
theme-functions.php
(/wp-content/themes/scope/functions/theme-functions.php) on line 459.
Modify the line to look like this:
$link = '<a href="' . esc_attr( get_term_link($category) ) . '#filter=.'.$category->slug.'" ';
2. Download and link BBQ plugin to the theme
You can find the BBQ plugin on Ben Alman's page here
http://benalman.com/projects/jquery-bbq-plugin/. Save the .js file to the Scope JS directory (/wp-content/themes/scope/js/).
Now you have to link the .js file to the theme on the portfolio page. You can do this by adjusting the
functions.php
file (/wp-cotent/scope/functions.php).
Add this code
wp_register_script('bbq', get_template_directory_uri() . '/js/jquery.ba-bbq.min.js', 'jquery', '1.2.1', TRUE);
on the line 165 or so. This will register the .js file with the theme. Next, you have to load the file on the portfolio page, by calling
wp_enqueue_script('bbq');
on the line 187 (within
if( is_page_template( 'template-portfolio.php' ) )
condition).
While you are at it, you can also add
.no-transition
class to
div#primary
in
theme-portfolio.php:22
. This will help you to disable animation on the first page load. Items will animate from their current position after clicking the link without window scroll jumping to the top or animation from the top left corner of Isotope container.
3. Modify isotope initialization
Last but not least, you have to modify the Isotope plugin initialization, which can be found in
jquery.custom.js
(/wp-content/themes/scope/js/jquery.custom.js) on the lines 43-68 enclosed in
if( jQuery().isotope )
condition.
New code is going to be little bit longer that the original, but don't worry.
$(function(){
var $container = $('.isotope'),
// object that will keep track of options
isotopeOptions = {},
// defaults, used if not explicitly set in hash
defaultOptions = {
filter: '*',
sortBy: 'original-order',
itemSelector : '.isotope-item',
layoutMode: 'fitRows',
animationEngine: 'css'
};
// ensure no transforms used in Opera
if ( $.browser.opera ) {
defaultOptions.transformsEnabled = false;
}
var setupOptions = defaultOptions;
var $optionSets = $('#sort-by');
// switches selected class on buttons
function changeSelectedLink( $elem ) {
// remove selected class on previous item
$elem.parents('#sort-by').find('.active').removeClass('active');
// set selected class on new item
$elem.addClass('active');
}
$optionSets.find('a').click(function(){
var $this = $(this);
// don't proceed if already selected
if ( $this.hasClass('active') ) {
return false;
}
changeSelectedLink( $this );
// get href attr, remove leading # and everything before it
var href = $this.attr('href').replace( /.*#/, '' );
// convert href into object
// i.e. 'filter=.inner-transition' -> { filter: '.inner-transition' }
option = $.deparam( href, true );
// apply new option to previous
$.extend( isotopeOptions, option );
// set hash, triggers hashchange on window
$.bbq.pushState( isotopeOptions );
linkClicked = true;
return false;
});
//add active class to selected link, selected by data-filter attribute
var initHashOptions = window.location.hash ? $.deparam.fragment( window.location.hash, true ) : {};
if(initHashOptions.filter){
var activeLinkClass = initHashOptions.filter.replace(/\./, '');
if(activeLinkClass != ''){
changeSelectedLink($('#sort-by a[data-filter="'+activeLinkClass+'"]'));
}
}
var linkClicked = false;
$(window).bind('hashchange', function( event ){
if(linkClicked){
$container.removeClass('no-transition');
}
// get options object from hash
var hashOptions = window.location.hash ? $.deparam.fragment( window.location.hash, true ) : {},
// apply defaults where no option was specified
options = $.extend( {}, defaultOptions, hashOptions);
// apply options from hash
$container.isotope( options );
// save options
isotopeOptions = hashOptions;
})
// trigger hashchange to capture any hash data on init
.trigger('hashchange');
});
}
This sets up the Isotope plugin to work with BBQ. Now any filter buttons that are clicked will update the URL hash, so these options can be bookmarked or shared. It will also highlight the correct filter button.
I'm sure there is some other way to achieve the same thing. If you know one, let me know in the comments.
Have a nice day!
p.
thanks for share!