How to add links to Scope portfolio types

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.
Published 10.01.2012 by Peter Pech

  1. thanks for share!

Leave a Reply