Last month, I showed you how to create a portfolio site on WordPress using a custom post type, a new “projects” query, and a few new templates.
In this post, I will show you how to add filters to your portfolio page using the Isotope.js library.
If you haven’t already, go into your WordPress site, create a few categories, and assign them to the items in your portfolio. If you read the first article, I am using a CPT called ‘Projects’ again, so for each project added to my WordPress site, I will need to make sure that a category gets assigned. On my site, my projects are going to be categorized as either “New Construction” or “Renovations.”
Once you have assigned a category to each of your projects, it is time to add the JavaScript that will do the fancy filtering work for you.
Isotope.js is a layout library developed by David DeSandro. It is free for open source and personal use, however, for commercial use, you must purchase a license. Please review the license page for more information and pricing.
So, let’s add the isotope.js file to your site. Ideally, you would add this to a directory called /js/ in your child theme to ensure that updates never delete it.
You also need to create one more file and add it to your /js/ directory. This file will contain the jQuery needed to target your projects. In my example, I named this file projects.js.
Paste the following code into that file and save it. The key things to note in this file are the #projects, .project-item, and #filters. This is the file where you could also change layoutMode: to masonry, packery, cellsByColumn, and more. In this tutorial, I’m using the grid mode.
jQuery(function ($)
// initialize Isotope after all images have loaded
var $container = $('#projects').imagesLoaded( function() //The ID for the list with all the blog posts
$container.isotope( //Isotope options, 'item' matches the class in the PHP
itemSelector : '.project-item',
grid:
columnWidth: 200
);
);
 
//Add the class selected to the item that is clicked, and remove from the others
var $optionSets = $('#filters'),
$optionLinks = $optionSets.find('a');
$optionLinks.click(function()
var $this = $(this);
// don't proceed if already selected
if ( $this.hasClass('selected') )
return false;
var $optionSet = $this.parents('#filters');
$optionSets.find('.selected').removeClass('selected');
$this.addClass('selected');
//When an item is clicked, sort the items.
var selector = $(this).attr('data-filter');
$container.isotope( filter: selector );
return false;
);
);
Once you have added this code to your site, it is time to enqueue the files. If your child theme’s functions.php already has a function declared to do this, you will just need to add a line of code to it like the one below.
Note, get_stylesheet_directory_uri() always refers to the current active theme. In the case of a custom theme, or the scenario where you are altering a theme without a child theme, you would likely use get_template_directory_uri() in place of get_stylesheet_directory_uri() If your child theme doesn’t already have a function for enqueuing your script, you will need to add one. Use the following to enqueue your isotope.js file.
One last note here, you should make sure that your theme has already enqueued jQuery. If it hasn’t, you will need to add wp_enqueue_script('jquery'); but as of WordPress 3.8, jQuery is packaged with the WordPress core in /wp-includes/js/jquery/jquery.js.
Finally, save your functions.php file.
Now, go back to your projects-page.php file and add the code that will display your filters, as well as get the number of categories and the category name of each project.
Paste the following code in just above where your portfolio starts. Like the last tutorial, I am using Bootstrap and in the HTML below, I am setting my filter row to be full width of the container. By default, my filters will align to the left of the column. If you aren’t using Bootstrap, you may want to start and end with the <ul> tags.
&amp;lt;div id="filter-row" class="row"&amp;gt;
&amp;lt;div id="project-page" class="col-lg-12"&amp;gt;
&amp;lt;ul class="nav navbar-nav navbar-left" id="filters"&amp;gt;
&amp;lt;?php
$terms2 = get_terms("project_categories"); // This will go get all the categories
$count = count($terms2); //This counts the number of categories
echo '&amp;lt;li&amp;gt;&amp;lt;a href="javascript:void(0)" title="" data-filter=".all" class="active"&amp;gt;Show All&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;';
if ( $count &amp;gt; 0 )
foreach ( $terms2 as $term )
$termname = strtolower($term-&amp;gt;name); $termname = str_replace(' ', '-', $termname);
echo '&amp;lt;li style="list-style:inline;"&amp;gt;&amp;lt;a href="javascript:void(0)" title="" class="" data-filter=".'.$termname.'"&amp;gt;'.$term-&amp;gt;name.'&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;';
// in the above foreach loop, the code will return all the values stored in $terms2 array.
?&amp;gt;
&amp;lt;/ul&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
The next step is to get the category for each project and place it into the project container as a class.
&amp;lt;?php
/*
Get the category for each unique post using the post ID
*/
$terms = get_the_terms( $post-&amp;gt;ID, 'project_categories' );
if ( $terms &amp;amp;&amp;amp; ! is_wp_error( $terms ) ) :
$links = array();
foreach ( $terms as $term )
$links[] = $term-&amp;gt;name;
$tax_links = join( " ", str_replace(' ', '-', $links));
$tax = strtolower($tax_links);
else :
$tax = '';
endif;
$terms = get_the_terms( $post-&amp;gt;ID, 'project_categories' );
?&amp;gt;
&amp;lt;?php echo '&amp;lt;div class="project col-sm-6 col-md-4 all project-item '. $tax .'"&amp;gt;';?&amp;gt;
In the code above, all, project-item, and $tax get added to each project container. $tax will be the category that you assigned to it in the wp-admin. Adding “all” allows you to reset the portfolio page any time a user clicks the “all” filter.
In the end, each project should have a class called “all” and in my case, each project will also have either “new-construction” or “renovations.” Now, when a user clicks on one of the categories, the page will elegantly reformat to display only the category that has been selected, all while maintaining the portfolio’s grid layout.
In conclusion, Isotope.js is a very powerful jQuery plugin that can be implemented on any WordPress site. Once installed, it can be used to sort and filter catalogue, gallery, or portfolio layouts. In addition, there are multiple layout options that you can use. Check out all the options here.
In the end, here is what my projects-page.php looks like when finished:
And with that, you’ll have a fully functioning, content filtering portfolio page!
WordPress plugins you’ll love
Download this ebook for a list of our most recommended plugins for developers! We’ve found all of these plugins to be straightforward to use, not too performance heavy on your site, and just downright reliable.
To provide the best experiences, we use technologies like cookies to store and/or access device information. Consenting to these technologies will allow us to process data such as browsing behavior or unique IDs on this site. Not consenting or withdrawing consent, may adversely affect certain features and functions.
Functional
Always active
The technical storage or access is strictly necessary for the legitimate purpose of enabling the use of a specific service explicitly requested by the subscriber or user, or for the sole purpose of carrying out the transmission of a communication over an electronic communications network.
Preferences
The technical storage or access is necessary for the legitimate purpose of storing preferences that are not requested by the subscriber or user.
Statistics
The technical storage or access that is used exclusively for statistical purposes.The technical storage or access that is used exclusively for anonymous statistical purposes. Without a subpoena, voluntary compliance on the part of your Internet Service Provider, or additional records from a third party, information stored or retrieved for this purpose alone cannot usually be used to identify you.
Marketing
The technical storage or access is required to create user profiles to send advertising, or to track the user on a website or across several websites for similar marketing purposes.