How to Build a Filterable Portfolio in Wordpress Using jQuery Isotope

Check out my other posts and tutorials on Web Development!

Get Your License

First things first. If you haven’t done so already, pick up your Isotope license. If you are using Isotope for a non-commercial, personal, or open-source project then Isotope is free to use and falls under the terms of the MIT license. For commercial uses you have two options:

Developers License ($25): This is a per-developer fee for use in commercial projects.

Organization License ($90): This license covers a team of developers using Isotope for commercial projects.

Add jQuery Links

WordPress comes with jQuery included but we are going to load our own from Google’s CDN to speed things up a bit. Place the following in functions.php.

if (!is_admin()) add_action( 'wp_enqueue_scripts', 'add_jquery_to_my_theme' );

function add_jquery_to_my_theme() {
    // scrap WP jquery and register from google cdn - load in footer
    wp_deregister_script('jquery');
    wp_register_script('jquery', "http" . ($_SERVER['SERVER_PORT'] == 443 ? "s" : "") . "://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js", false, null, true );    
    // load jquery
    wp_enqueue_script('jquery');
}

Next, download the jQuery Isotope library and embed it into your theme; placing the following in functions.php. Make sure to change the path to your isotope script.

if (!is_admin()) add_action( 'wp_enqueue_scripts', 'load_isotope' );

function load_isotope() {
    // script will load in footer
	wp_enqueue_script( 'isotope-js',  get_stylesheet_directory_uri() . '/path/to/jquery.isotope.min.js', true );
}

Building the Portfolio Custom Post Type

Register the Custom Post Type

The following code should be placed in functions.php.

/*
 * Add a portfolio custom post type.
 */
add_action('init', 'create_redvine_portfolio');
function create_redvine_portfolio() 
{
  $labels = array(
    'name' => _x('Portfolio', 'portfolio'),
    'singular_name' => _x('Portfolio', 'portfolio'),
    'add_new' => _x('Add New', 'portfolio'),
    'add_new_item' => __('Add New Portfolio Item'),
    'edit_item' => __('Edit Item'),
    'new_item' => __('New Item'),
    'view_item' => __('View Item'),
    'search_items' => __('Search Items'),
    'not_found' =>  __('No items found'),
    'not_found_in_trash' => __('No items found in Trash'), 
    'parent_item_colon' => ''
  );
  $args = array(
    'labels' => $labels,
    'public' => true,
    'show_ui' => true, 
    'query_var' => true,
    'rewrite' => true,
    'capability_type' => 'post',
    'hierarchical' => false,
    'menu_position' => 20,
    'supports' => array('title','editor','thumbnail')
  ); 
  register_post_type('portfolio',$args);
}

Add Categories for Filtering

register_taxonomy( "portfolio-categories", 
	array( 	"portfolio" ), 
	array( 	"hierarchical" => true,
			"labels" => array('name'=>"Creative Fields",'add_new_item'=>"Add New Field"), 
			"singular_label" => __( "Field" ), 
			"rewrite" => array( 'slug' => 'fields', // This controls the base slug that will display before each term 
			                    'with_front' => false)
		 ) 
);

Add a Custom Icon For the Dashboard

<?php 
/*
Add in a custom icon for the dashboard
*/
add_action( 'admin_head', 'portfolio_icons' );
function portfolio_icons() {
    ?>
    <style type="text/css" media="screen">
        #menu-posts-portfolio .wp-menu-image {
            background: url(<?php bloginfo('template_url') ?>/images/your_image.png) no-repeat 6px -17px !important;
        }
		#menu-posts-portfolio:hover .wp-menu-image, #menu-posts-portfolio.wp-has-current-submenu .wp-menu-image {
            background-position:6px 7px!important;
        }
    </style>
 
 
<?php } ?>

The Portfolio Page Structure

Create a Portfolio Page Template

Open your text editor and create a file named “page-portfolio.php”.

Your template structure will depend on what your current site layout looks like. My advice is to copy your page.php file, add in the required template comment at the top of the page (as seen below), and replace the page loop with the portfolio custom post loop we are going to write in the next section.

Your portfolio template should follow this general structure:

<?php  
/* 
Template Name: Portfolio 
*/ 
get_header(); ?>

<!-- Insert Beginning Page Wrappers -->

<!-- Portfolio Filter Categories Loop -->

<!-- Portfolio Custom Post Loop -->

<!-- Insert Closing Page Wrappers -->

<?php get_footer(); ?>

Adding Filters

Next we add in our category filters. The following loop displays our portfolio categories that we registered with our Portfolio Custom Post Type. Isotope uses the data-filter attribute to link to the corresponding class of each category.

<ul id="filters">
    <?php
        $terms = get_terms('portfolio-categories');
        $count = count($terms);
            echo '<li><a href="javascript:void(0)" title="" data-filter=".all" class="active">All</a></li>';
        if ( $count > 0 ){
 
            foreach ( $terms as $term ) {
 
                $termname = strtolower($term->name);
                $termname = str_replace(' ', '-', $termname);
                echo '<li><a href="javascript:void(0)" title="" data-filter=".'.$termname.'">'.$term->name.'</a></li>';
            }
        }
    ?>
</ul>

The Portfolio Page Loop

We begin by using WP Query to pull our portfolio posts. I have set ‘posts_per_page’ to -1, which will pull all posts since Isotope does not support pagination. You can change this to your desired amount if you’d like to add in pagination but keep in mind Isotope will only filter the items on the current page. Next we are summoning the chosen categories linked to each unique post using the post ID. We’ll use this to link each individual portfolio post with the corresponding filter. Finally we output our post with the category assigned as a class to our containing div tag. It is up to you to choose what you’d like to display and in what order for each post. Here we are pulling the thumbnail, title and excerpt since that is what we instructed our Portfolio Custom Post Type to support. Feel free to remove the title and excerpt if they are not necessary and adjust the post permalink as needed.

<div id="portfolio">
 
  <?php
  /* 
  Query the post 
  */
  $args = array( 'post_type' => 'portfolio', 'posts_per_page' => -1 );
  $loop = new WP_Query( $args );
  while ( $loop->have_posts() ) : $loop->the_post(); 
 
     /* 
     Pull category for each unique post using the ID 
     */
     $terms = get_the_terms( $post->ID, 'portfolio-categories' );	
     if ( $terms && ! is_wp_error( $terms ) ) : 
 
         $links = array();
 
         foreach ( $terms as $term ) {
             $links[] = $term->name;
         }
 
         $tax_links = join( " ", str_replace(' ', '-', $links));          
         $tax = strtolower($tax_links);
     else :	
	 $tax = '';					
     endif; 
 
     /* Insert category name into portfolio-item class */ 
     echo '<div class="all portfolio-item '. $tax .'">';
     echo '<a href="'. get_permalink() .'" title="'. the_title_attribute() .'">';
     echo '<div class="thumbnail">'. the_post_thumbnail() .'</div>';
     echo '</a>'; 
     echo '<h2>'. the_title() .'</h2>';
     echo '<div>'. the_excerpt() .'</div>';
     echo '</div>'; 
  endwhile; ?>
 
</div>

The End Result

All said and done, your Portfolio Page Template should look something like this:

<?php 
/*
Template Name: Portfolio
*/
get_header(); ?>
 
  <div id="page">
 
    <ul id="filters">
        <?php
            $terms = get_terms("portfolio-categories");
            $count = count($terms);
                echo '<li><a href="javascript:void(0)" title="" data-filter=".all" class="active">All</a></li>';
            if ( $count > 0 ){
 
                foreach ( $terms as $term ) {
 
                    $termname = strtolower($term->name);
                    $termname = str_replace(' ', '-', $termname);
                    echo '<li><a href="javascript:void(0)" title="" data-filter=".'.$termname.'">'.$term->name.'</a></li>';
                }
            }
        ?>
    </ul>
 
    <div id="portfolio">
 
       <?php 
       $args = array( 'post_type' => 'portfolio', 'posts_per_page' => -1 );
       $loop = new WP_Query( $args );
       while ( $loop->have_posts() ) : $loop->the_post(); 
 
          $terms = get_the_terms( $post->ID, 'portfolio-categories' );						
          if ( $terms && ! is_wp_error( $terms ) ) : 
 
              $links = array();
 
              foreach ( $terms as $term ) {
                  $links[] = $term->name;
              }
 
              $tax_links = join( " ", str_replace(' ', '-', $links));          
              $tax = strtolower($tax_links);
          else :	
	      $tax = '';					
          endif; 
 
          echo '<div class="all portfolio-item '. $tax .'">';
          echo '<a href="'. get_permalink() .'" title="'. the_title_attribute() .'">';
          echo '<div class="thumbnail">'. the_post_thumbnail() .'</div>';
          echo '</a>';
          echo '<h2>'. the_title() .'</h2>';
          echo '<div>'. the_excerpt() .'</div>';
          echo '</div>'; 
      endwhile; ?>
 
   </div><!-- #portfolio -->
 
  </div><!-- #page -->
 
<?php get_footer(); ?>

The Portfolio Single Page Structure

Create a Portfolio Single Template

In order to pull your single custom posts, open your text editor and create a file named single-(post-type).php. So in this case our single page would be named “single-portfolio.php”.

Your template structure will depend on what your current site layout looks like. My advice is to copy your single.php file and restyle it accordingly.

The jQuery

Below is the required jQuery to make our Filterable Portfolio We’ve calculated the column width here so our projects actively resize when we change the width of the browser. Be sure to alter the columnWidth to your desired amount of columns.

(function($){
 
    var $container = $('#portfolio');
 
    // create a clone that will be used for measuring container width
    $containerProxy = $container.clone().empty().css({ visibility: 'hidden' });   
 
    $container.after( $containerProxy );  
 
    // get the first item to use for measuring columnWidth
    var $item = $container.find('.portfolio-item').eq(0);
    
    $container.imagesLoaded(function(){
        $(window).smartresize( function() {
 
            // calculate columnWidth
            var colWidth = Math.floor( $containerProxy.width() / 2 ); // Change this number to your desired amount of columns
 
            // set width of container based on columnWidth
            $container.css({
                width: colWidth * 2 // Change this number to your desired amount of columns
            })
            .isotope({
 
                // disable automatic resizing when window is resized
                resizable: false,
 
                // set columnWidth option for masonry
                masonry: {
                    columnWidth: colWidth
                }
            });
 
        // trigger smartresize for first time
        }).smartresize();
    });
 
    // filter items when filter link is clicked
    $('#filters a').click(function(){
        
        var selector = $(this).attr('data-filter');
        $container.isotope({ filter: selector, animationEngine : "css" });
        $('#filters a.active').removeClass('active');
        $(this).addClass('active');
        return false;
 
    });
 
} ) ( jQuery );

The CSS

The following CSS is used for Isotope transitions. It has been slightly altered from the default CSS required for Isotope Filtering under the Isotope Documentation in order to fix a bug that causes the portfolio items to assume a single column and slightly overlap when resizing the browser.

Add the following CSS into your theme’s stylesheet.

/**** Isotope Filtering ****/

.isotope-item {
  z-index: 2;
}

.isotope-hidden.isotope-item {
  pointer-events: none;
  z-index: 1;
}

/**** Isotope CSS3 transitions ****/

.isotope,
.isotope .isotope-item {
  -webkit-transition-duration: 0.8s;
     -moz-transition-duration: 0.8s;
      -ms-transition-duration: 0.8s;
       -o-transition-duration: 0.8s;
          transition-duration: 0.8s;
}

.isotope {
  -webkit-transition-property: height;
     -moz-transition-property: height;
      -ms-transition-property: height;
       -o-transition-property: height;
          transition-property: height;
}

.isotope .isotope-item {
  -webkit-transition-property: -webkit-transform, opacity;
     -moz-transition-property:    -moz-transform, opacity;
      -ms-transition-property:     -ms-transform, opacity;
       -o-transition-property:      -o-transform, opacity;
          transition-property:         transform, opacity;
}

/**** disabling Isotope CSS3 transitions ****/

.isotope.no-transition,
.isotope.no-transition .isotope-item,
.isotope .isotope-item.no-transition {
  -webkit-transition-duration: 0s;
     -moz-transition-duration: 0s;
      -ms-transition-duration: 0s;
       -o-transition-duration: 0s;
          transition-duration: 0s;
}

102 Responses to How to Build a Filterable Portfolio in WordPress Using jQuery Isotope

    • I’d recommend placing a hook in functions.php to link all scripts and style sheets. For more info on how to do that, check out the WordPress codex for enqueuing scripts and styles.

      Or, if you prefer, placing scripts just above your closing body tag should do the trick!

      Reply
    • That looks like an oversight on my part. Though you should find little difference with using page vs post, ideally post should be listed as our capability type and, when removed completely, is set as the default. I’ve amended this in the code above.

      Thanks, great catch!

      Reply
  1. Saeed Akhtar says:

    Hi Please help me when i create some category. when i click all that show me all post but when i click another category like (web) that time all hide

    NOTE: when i create portfolio post and add in web category.

    Reply
  2. Thanks for this tutorial, it’s just what I needed. However, I can’t seem to get it working correctly. When I click on a category all posts disappear. Similar to what Saeed mentions in the above comment.

    Reply
    • Hi, I’d be happy to lend a hand. To better diagnose the issue I’d have to take a look at your code. Are you hosting your project on the web by chance?

      Reply
    • Hi Scott, thanks for sending the link to your project. It appears as though you currently have the #portfolio div inside of your post loop. The #portfolio div acts as our container for the items that are to be sorted, so try placing it outside of your loop to see if that solves the problem.

      Reply
  3. I have the it working for my first portfolio item. I think there is a problem in my loop. When I look at my source it looks like this:

    myimageItem Title

    myimageItem Title

    myimageItem Title

    I notice my #portfolio div is being repeated but I can’t figure out how to fix it.

    Reply
      • Hi, it sounds like you have the #portfolio div placed within your post loop. Since we’re using that as our container here, you want to place it outside of the query so you only loop through the individual portfolio posts. Try making that change and see how it works. If you do not have any luck, you can send me your code at corey@redvinestudio.com!

        Reply
  4. Quick question. Following this method, the “All” link doesn’t have an active class by default, and isnt highlightable. How do you go about adding adding the active class to the All tag on load.

    Reply
  5. Hi guys,
    awesome tutorial,
    it works pretty well.

    I just have a problem about filtering.
    If I set a category name like “ouvrages d’art”, the filtering doesn’t work,
    When I renamed it “ouvrages” it works.
    Do you have an idea about this problem ?

    Best
    Damien

    Reply
    • Hi,

      I tested “ouvrages d’art” and it is working fine for me. Make sure you have this line in your portfolio loop:

      $tax_links = join( ” “, str_replace(‘ ‘, ‘-‘, $links));

      The important part here is the str_replace function, which you will also find in the filters loop. We are using this to replace the space between “ouvrages” and “d’art” with a hyphen, that way the two words are not mistaken for being two different classes. If you view your page source your filter should appear like this:

      [a href=”javascript:void(0)” title=”” data-filter=”.ouvrages-d’art””]ouvrages d’art[/a]

      and your portfolio item should look like this:

      [div class=”all portfolio-item ouvrages-d’art”]…..content……[/div]

      If you are not seeing this hypen, check your code to make sure your loops match what is shown in this example. Let me know if you are still having trouble!

      Reply
  6. Next, download the jQuery Isotope library and embed it into your theme; placing the link underneath your jQuery link.

    how to embed the jquery at this download link many files are there and no ‘jquery.isotope.min.js’ file found…

    <script type="text/javascript" src="/js/jquery.isotope.min.js”>

    then where i can find ‘jquery.isotope.min’.js… i didn’t have this!!..

    Reply
    • Hi,

      I am not seeing any links on the page you provided.

      If you are having trouble making your portfolio items filter try taking a look at your page source to see what is being pulled. Remember, the value in your data-filter for each filter link should match the class of the corresponding portfolio items that link is supposed to be filtering.

      Reply
  7. I want to add a hash to my URL so I can get straight to a category from another page. Is that possible?

    Reply
  8. Hi Corey

    You’ve written a very clear and detailed tutorial and I thank you for that. I’m not a developer by trade just a guy who likes to do it mostly myself.

    I have been trying to implement an isotope filtering portfolio for pictures of my work into the wordpress site that I am building for myself and having problems figuring it out. I can get it working in plain html + bootstrap but when I try to pull that into the wordpress with bootstrap template that I am using I run into problems. I can’t seem to make the filtering work in wordpress. Your tutorial comes closest to anything that I’ve seen out there except that you are filtering posts and I only want to filter pictures, a gallery. Seems that would be simpler than what you have done.

    I’ve got a couple of page templates in the site under the “About” tab, Gallery is furthest along and Gallery Test as kind of a backup. I have the lightbox that I want to use working and can create individual galleries but I just cant seem to figure out how to make the filter animation work. Been wrestling with this for a couple of months now. Any insight would be appreciated VERY much.

    Thanks again for your tutorial and taking the time to read this.

    Reply
  9. I finally got a simplified photo gallery only working by repeatedly looking at your examples and code. Thanks again for your time and effort and sharing your knowledge.

    Best to you and yours

    Reply
  10. I tried following every part of your tutorial, but its not working for me :/
    The only link that has an active class is the “All” and when i click other filters nothing happends and all still stays as an active class .. i didnt know where to add the jquery from the last code box, so i just made a js file named isotope.js and called it through header.php in the head tag where im also calling the jquery.isotope and jquery from..

    Reply
  11. oh well, somehow i just got it working by copying and pasting your code.. but i have one question though .. how does the content of the ‘. the_title() .’ appear outside the defined tags? in this case its inside “h2” tags .. but they are appearing outside the h2 tags .. and same for the other strings..

    Reply
  12. Where do I have to put the “Add a Custom Icon For the Dashboard” code into the Theme? I am using twentyhirteen

    Reply
  13. Corey, I should have thanked you sooner for this post. I’ve used your technique to great effect on a few sites and they worked perfectly until a couple of days ago.

    I’ve noticed in Chrome the isotope doesn’t behave properly anymore: when resizing window and also the filter. I’m looking into fixing my issues at the moment but if you ever have the time could you take a look at your demo and if you find a solution maybe update the post, please? (i see the weird behaviour in your demo, too)

    Regardless, this original post of yours was a saviour! Thanks again

    Reply
    • Hi,

      I’m so glad you found this post useful!

      I just tested the demo (as well as a few other isotope installs) in Chrome and I have not seen any issues so far. Are you still experiencing strange behavior?

      Reply
  14. Hi,

    thanks for the tutorial. It’s working just fine on my local page right now.
    I am not an expert and I am trying to get a few things working:

    1. How can I add a hover effect to thumbnails.

    2. Click on thumbnail opens expanded view with more informations.

    I followed this tutorial: http://tympanus.net/codrops/2013/03/19/thumbnail-grid-with-expanding-preview/
    and got it working as well. I now need a combination of your tutorial and hers..

    My site isn’t online yet, but here is an example of what I am trying to achieve:
    http://www.kriesi.at/themes/angular/

    Thanks

    Reply
  15. Hi Corey, thanks for this tutorial. It’s working fine except for the same issue than Suleiman user said.
    the content of the ‘. the_title() .’ appear outside the defined tags. Can you help us?
    Best to you

    Reply
  16. Hi Corey,

    Thanks for this great post. It helped me a lot!!

    Do you think there is a possiblity, that there is one category already selected by default when I open the portfolio, instead of showing all posts. I just can’t get it working and would be really thankful if you would have a hint!

    Thanks, Cara

    Reply
  17. Hi, I managed to solve it.
    At this part of the isotope code I added the filter value:

    $container.imagesLoaded(function () {
    $container.isotope({
    itemSelector: ‘.item’,
    layoutMode: ‘fitRows’,
    filter:’.my_category_name’
    });

    Reply
  18. Hi Corey,

    I am able to display only 10 or less than 10, portfolio items in “ALL” section.
    Do u know where the error might be?

    Thanks,
    kajone

    Reply
    • Hi,

      After viewing your page source, it appears as though your jquery.isotope.min.js link is broken so isotope is not being called. Try double checking that link.

      Reply
  19. Hi, Below it jquery code. how can i add previous and next button.

    (function ($) {
    var container = $(‘section.content-posts’);

    container.isotope( { itemSelector : ‘article.post’ } ); // specify container

    container.isotope( { filter : “article.post[page~=’1′]” } ); // starting filter

    $(‘article.goto-page a’).click(function(){
    var selector = $(this).attr(‘page’); // make selector equal to the value we put in ‘page’

    container.isotope( { filter : selector });
    return false;
    })
    } )(jQuery);

    (function($){

    var $container = $(‘#portfolio’),
    // create a clone that will be used for measuring container width
    $containerProxy = $container.clone().empty().css({ visibility: ‘hidden’ });

    $container.after( $containerProxy );

    // get the first item to use for measuring columnWidth
    var $item = $container.find(‘.portfolio-item’).eq(0);
    $container.imagesLoaded(function(){
    $(window).smartresize( function() {
    // calculate columnWidth
    var colWidth = Math.floor( $containerProxy.width() / 4 );
    // set width of container based on columnWidth
    $container.css({
    width: colWidth * 4
    })
    .isotope({
    // other options…
    // disable automatic resizing when window is resized
    resizable: false,
    // set columnWidth option for masonry
    masonry: {
    columnWidth: colWidth
    }
    });
    // trigger smartresize for first time
    }).smartresize();
    });
    // filter buttons
    // filter items when filter link is clicked
    $(‘#filters a’).click(function(){
    $(‘#filters a.active’).removeClass(‘active’);
    var selector = $(this).attr(‘data-filter’);
    $container.isotope({ filter: selector, animationEngine : “css” });
    $(this).addClass(‘active’);
    return false;

    });

    $(“a[href^=javascript:void(0)]”).on(“click”, function(e) {
    e.preventDefault();
    history.pushState({}, “”, this.href);
    });

    } ) ( jQuery );

    Reply
  20. Hi Corey,

    Great tutorial, I have the template-portfolio.php functioning correctly my question is about the single-portfolio.php. Every time i click on a ‘Project item’ it loads the index.php and not the single-portfolio.php?

    Any suggestions on this?

    Cheers

    Reply
  21. Hi, thank you so much, great tutorial! It helped me a lot 🙂
    I have a question, how to add a permalink to the_title() or the_post_thumbnail() ?
    Thanks,
    Natalie

    Reply
    • Hi,

      Since you are placing the link within the post loop, simply wrap the desired item with the permalink:

      [a href=”[php the_permalink() ?]”] [php the_title(); ] [/a]

      Reply
  22. Great Tutorial Corey

    Quick Question, how would I go about using terms for filtering instead of taxonomies/categories, I’ve got your version working fine, I’m halfway there : This is showing my term “mediums”

    <?php

    $terms = get_terms('mediums','');
    $count = count($terms);
    echo 'All‘;
    if ( $count > 0 ){

    foreach ( $terms as $term ) {

    $termname = strtolower($term->name);
    $termname = str_replace(‘ ‘, ‘-‘, $termname);
    echo ‘‘.$term->name.’‘;
    }
    }
    ?>

    But my loop only shows the one term name for the item, i;’m not finished with it yet but this is it.

    have_posts() ) : while ( $query->have_posts() ) : $query->the_post(); ?>

    ID,’mediums’);
    if ( $terms && ! is_wp_error( $terms ) ) :

    $links = array();

    foreach ( $terms as $term ) {
    $links[] = $term->name;
    }

    $tax_links = join( ” “, str_replace(‘ ‘, ‘-‘, $links));
    $tax = strtolower($tax_links);
    else :
    $tax = ”;
    endif; ?>

    <div class="all arts-item “>

    <img src="” />

    You’ll see I’ve changed the item class and the wrapper div class too, I have changed it in my jQuery, the jQuery is working but at the moment hides everything because the item classes are wrong is all. I’m a bit new to custom post types and terms and that.

    Any helpers?

    Reply
  23. Hi Corey,
    I can’t get it working properly maybe because i’m doing it in a child theme. Filters don’t do nothing when i click them. But the source code looks ok

    I have this in my functions.php file, call files i put in /bigbenny/js and bigbenny/css in my child theme folder.

    function portfolio_scripts() {
    wp_enqueue_script( ‘isotope’, get_stylesheet_directory_uri() . ‘/bigbenny/js/jquery.isotope.min.js’, array(), ‘1.5.25’, true );
    wp_enqueue_script( ‘portfolio-script’, get_stylesheet_directory_uri() . ‘/bigbenny/js/portfolio-script.js’, array(), ‘2.0.0’, true );
    wp_enqueue_style( ‘portfolio-css’, get_stylesheet_directory_uri() . ‘/bigbennyy/css/portfolio.css’, array(), ‘0.1’, true );
    }
    add_action( ‘wp_enqueue_scripts’, ‘portfolio_scripts’ );

    When i check the source code i can see that the script appear correctly, before the end body tag.

    But it just don’t do anything

    Reply
  24. Hi, is there any way of hiding the images until all loaded? there seems to be a small 1 second load showing all the images jumbled.

    Reply
  25. Hi
    Great tutorial
    But I have a problem. If I copy The JQuery in the functions.php I become an error
    Parse error: syntax error, unexpected ‘$’, expecting ‘&’ or variable (T_VARIABLE)

    Reply
  26. My portfolio thumbnail images arent linking. Does the_post_thumbnail() need to be wrapped with an anchor tag and the_permalink() to get the images to link properly to the post? Or is what else is a likely reason why the featured images on the template-portfolio page do not link anyweher?

    Reply
    • Hi Mark,

      Correct, you should wrap the desired post item (thumbnail, title, etc.) with a link pointing to the_permalink().

      Reply
  27. My work is on my local server otherwise Id post a link to it. The jquery, isotope.js and css files enqueued properly in the right order, and my filter li’s and thumbnails are displaying, but when I click on a filter li nothing happens. All the href’s are outputing href=”javascript:void(0)”

    Help!

    Reply
    • Do the data-filters on your filter links match the corresponding post classes? ie. a filter link with data-filter=”.yellow” will filter posts with class of “yellow”.

      Reply
  28. This is the most comprehensive and easy to follow tutorial on this that I have found after searching for several days. However, I still am unable to get it to work – probably because I am so new to WordPress and web design. My issue is the in script I believe. Everything is outputting onto the page but not in two columns and nothing changes when the links are clicked. I’m pretty sure the script is not loading properly because the css isn’t working. There is an error on the script console “Uncaught TypeError: undefined is not a functionisotope-portfolio.js?ver=4.1:14 (anonymous function)isotope-portfolio.js?ver=4.1:49 (anonymous function)” and it is highlighting the imagesloaded function (line 14 or so). My scripts have been enqueued in the functions file – but I’m not clear if it has been ‘hooked’ yet (I did try them in the footer but that didn’t resolve the issue). Also – for the JS provided above I was unsure where to add that so I made a new .js file and enqueued that (isotope-portfolio.js). My theme is called ‘beyond’. The scripts do show up in the head of the HTML. Sorry I am not able to get the site online yet to give you a better idea. Any suggestions would be much appreciated. Thank you in advance. The enqueuing is shown below. Could it be an issue with the $ sign and jQuery in WordPress?

    function beyond_scripts() {
    wp_enqueue_script( ‘isotope-pkgd-min’, get_template_directory_uri() .’/js/isotope.pkgd.min.js’, array( ‘jquery’ ), ”, false );
    wp_enqueue_script( ‘isotope-portfolio’, get_template_directory_uri() . ‘/js/isotope-portfolio.js’, array( ‘isotope-pkgd-min’ ), ”, false );
    }
    add_action( ‘wp_enqueue_scripts’, ‘beyond_scripts’ );

    Reply
    • I finally did solve my issue above by using “true” instead of “false” so that the script draws in the footer. THanks again for this excellent tutorial. Have used it on 3 sites now.

      Reply
  29. Hi, great tutorial. Has anyone tried to adjust the column number based on screen width/media queries? How would the code adjust to show 2 columns on tablet device (< 768) and 1 column on mobile (< 320)?

    Thanks

    Reply
    • I would also like to know of a way to adjust this for responsive. Anyway you have a moment to suggest an additional code to the js, Corey? I have it working for mobile – by adjusting the width to 100% in the CSS but the columns won’t flow to 2 columns at the tablet width (like 768px as mentioned above).

      Reply
  30. Wondering is there is a way to do the following:
    My single portfolio pages have all projects for a given client (web, email, print, etc.)
    When you have filtered the portfolio to print (for example) is there a way to add #print (the current category) to the end of the url for each project so that when click on that item you are going to that client’s page but also jumping to the anchor that shows the print work?

    Reply
  31. Hi Corey,

    thanks for this great tutorial!

    Isotope is the greatest for portfolio presenting on WordPress but I cant make it to work 🙁 I’ve did exactly like you described in your tutorial, the only difference is that isotope is updated and I’m using v1.5.25 that can be found in the download link.

    My portfolio items are being shown but it looks like isotope is not loading at all, although I see it under dev tools scripts. Any advices?

    Thanks

    Reply
  32. _martinCx says:

    I’m also trying to have two different portfolios but my second one doesn’t filter my items. I have duplicated every bit of code that I think is responsible for the whole thing, the custom Posts, the new taxonomies, etc, but, while on my second portfolio, when I click a filter other than “SHOW ALL”, my items disappear.

    If anybody has tried to do this or can point me in the right direction, please leave a comment! Thanks!!!

    Reply
  33. Great article, I’ve been trying to implement it in a twenty twelve child theme during a few days with no success. I didn’t know where to put “The jQuery” section code.

    Then I realized that It must go into a .js (javascript) file. I put it in portfolio.js file into child theme’s “js” directory.

    Then I call to the 3 script from footer.php (just above closing body tag):

    <script src="/js/jquery.isotope.min.js” type=”text/javascript”>
    <script src="/js/portfolio.js” type=”text/javascript”>

    Then everything works!!

    Thanks a lot!!

    Reply
  34. Hi Corey, great tutorial. I was wonder if I could use tags instead of Categories. I would like to share some taxonomies between my works, i.e If I have a project where I applied design and wordpress development techniques, I would like to use both taxonomies in this case, a non-hierarchy taxonomy. Is it possible? Many thanks

    Reply
  35. That’s a really great tuts. Currently trying out Isotopes to bring something a little more to my portfolio and this has made it a little easy. Nice one Corey.

    Reply
  36. Thanks so much for a great tutorial! I’m curious to know how difficult it would be to add an infinite scroll to the portfolio page. I see that there is already a demo on the Isotope page, I’m just not sure how to integrate it…thoughts?

    Reply
  37. So its loading my images, but the whole filtering option is not working. there no mistakes with the code, and everything is loaded in properly. What could be the cause of this?

    Reply
    • Hi Lucas,

      It appears as though you may have a syntax error somewhere in your code which is why your link, thumbnail and title are not displaying correctly. A few other issues I see are that you’re loading 3 different versions of jQuery on your page and I’m not seeing the required javascript to initialize your Isotope portfolio. Resolving these issues should solve your problem.

      I hope this helps!

      Corey

      Reply
    • Lucas, I’m having same problem as you. Everything works fine i only have issues outputting the columns. Could you tell me your solution

      Reply
  38. Hi Corey,

    I re did the entire portfolio coding but the error persist. Here is the code for my page-portolio.php:

    ‘portfolio’, ‘posts_per_page’ => -1 );
    $loop = new WP_Query( $args );
    while ( $loop->have_posts() ) : $loop->the_post();

    $terms = get_the_terms( $post->ID, ‘portfolio-categories’ );
    if ( $terms && ! is_wp_error( $terms ) ) :

    $links = array();

    foreach ( $terms as $term ) {
    $links[] = $term->name;
    }

    $tax_links = join( ” “, str_replace(‘ ‘, ‘-‘, $links));
    $tax = strtolower($tax_links);
    else :
    $tax = ”;
    endif;

    echo ”;
    echo ‘‘;
    echo ”. the_post_thumbnail() .”;
    echo ‘
    ‘;
    echo ”. the_title() .”;
    echo ”. the_excerpt() .”;
    echo ”;
    endwhile; ?>

    I also loaded the script through the functions.php with the below:
    function beyond_scripts() {
    wp_enqueue_script( ‘isotope-pkgd-min’, get_template_directory_uri() .’/js/isotope.pkgd.min.js’, array( ‘jquery’ ), ”, true );
    wp_enqueue_script( ‘isotope-portfolio’, get_template_directory_uri() . ‘/js/portfolio.js’, array( ‘isotope-pkgd-min’ ), ”, true );
    }
    add_action( ‘wp_enqueue_scripts’, ‘beyond_scripts’ );

    Any ideas as to what might be wrong? I would really appreciate any help you can give me.

    Reply
    • Hi Lucas,

      From your code it appears as though you are enqueuing your scripts in the footer, however I do not see them there which makes me wonder if you are not using the wp_footer() hook in your theme. I also see that you are loading jquery.isotope.min.js in your header which appears to be a different script than your code shows you are trying to load. Further, you are loading an old version of jQuery on your page. I would recommend updating to a more recent version. You can view my post about loading jQuery in WordPress here.

      Hope this helps!

      Reply
  39. Hi Corey,

    You were correct! I was missing the wp_footer() and i found a small error on my script on functions.php as well. The portfolio now loads side by side as it should but the style and sorting are still not working properly.

    Is there any way you could take a look at the code for me?

    Reply
    • Glad that worked!

      The next issue I see is that you haven’t given your filter list the id of “filters” which is attached to the click event in your js. It looks like there is still some type of syntax error in your loop that is causing the elements to output strangely, but you can see the responsive nature of isotope working when you resize the browser.

      Reply
  40. Thanks, Corey!

    Silly mistake on my part to forget the “filters” ID, that fixed the sorting issue. Not sure what is causing the strange output since i copied the code directly from the tutorial but I will keep look.

    I did use the inspect tool on Chrome and it seems as if the link for the thumbnail and title are outputting outside of their HTML tags.

    Reply
    • Lucas, I’m getting the same issue with the thumbnail link and title outputting outside of the html tags. And I copied the code directly from the tutorial as well. Did you solve this?

      Reply
  41. Wow this is an awesome tutorial, I learned a lot and was able to make modifications. One question, on the single portfolio page, I have a “Back” button, is there any way to send the user back to the portfolio page and sort with the filter they had been on? (i.e. if someone clicked on “Red” and went to a single portfolio page clicking the back button takes them to “All”, is there a way to make it go to “Red”?

    Reply
  42. thenewguyduh says:

    So none of you had any trouble with the $post var? I had to define $post = $loop and it started working. no one had this issue? is it cause i am using this in a plugin?

    Reply
  43. Mandar Khamkar says:

    Hey,

    Thanks for sharing this code… it works…

    Now i want to convert HTML Dropdown menu into WordPress Dropdown Menu. So do u have any reference for the same?

    Reply

Leave a Reply

Contact Us

Subscribe

Subscribe to our blog to receive latest news and tutorials on Web Design, Development, SEO, and more!