A few months ago I wrote a post on how to integrate Isotope with WordPress. Since then, I’ve received some requests on showing how to limit it to one category. In this tutorial I will show how to add the Isotope code and scripts to a template, filtering the posts that belong to one category by it’s sub-categories.
You will notice that most steps are the same as with the original tutorial, but I have left them here, so people won’t have to go back and forth between articles. I’ll highlight the lines of code that differ from the first article.
- Download the script from the Isotope repository, and upload it to your theme’s folder (for example /js/libs/jquery.isotope.min.js)
- Add a list of sub-categories of my category 37 (here’s a tutorial on how to find the ID for your category). This list will serve as filters (following the filtering instructions in istotope):
<ul id="filters"><li><a href="#" data-filter="*">Everything</a></li><?php$terms = get_terms('category', array('parent' => 37)); // you can use any taxonomy, instead of just 'category'$count = count($terms); //How many are they?if ( $count > 0 ){ //If there are more than 0 termsforeach ( $terms as $term ) { //for each term:echo "<li><a href='#' data-filter='.".$term->slug."'>" . $term->name . "</a></li>\n";//create a list item with the current term slug for sorting, and name for label}}?></ul>
- Make a custom loop to load all the posts that match the sub-categories. Each blog posts must share a class (in my case, I used ‘item’), and additional classes to filter (from the list of categories from Setp 2):
<?php$terms_ID_array = array();foreach ($terms as $term){$terms_ID_array[] = $term->term_id; // Add each term's ID to an array}$terms_ID_string = implode(',', $terms_ID_array); // Create a string with all the IDs, separated by commas$the_query = new WP_Query( 'posts_per_page=50&cat='.$terms_ID_string ); // Display 50 posts that belong to the categories in the string?><?php if ( $the_query->have_posts() ) : ?><div id="isotope-list"><?php while ( $the_query->have_posts() ) : $the_query->the_post();$termsArray = get_the_terms( $post->ID, "category" ); //Get the terms for this particular item$termsString = ""; //initialize the string that will contain the termsforeach ( $termsArray as $term ) { // for each term$termsString .= $term->slug.' '; //create a string that has all the slugs}?><div class="<?php echo $termsString; ?> item"> <?php // 'item' is used as an identifier (see Setp 5, line 6) ?><h3><?php the_title(); ?></h3><?php if ( has_post_thumbnail() ) {the_post_thumbnail();} ?></div> <!-- end item --><?php endwhile; ?></div> <!-- end isotope-list --><?php endif; ?>
- Go check. At this point your page should have a list with all your categories, and a bunch of posts. View the page source to make sure the blog posts have the proper classes (‘item’, plus all the categories it belongs to).
- Create a file with the necessary JavaScript to launch and set up Isotope, and place it in your theme folder (for example, /js/isotope.js):
jQuery(function ($) {var $container = $('#isotope-list'); //The ID for the list with all the blog posts$container.isotope({ //Isotope options, 'item' matches the class in the PHPitemSelector : '.item',layoutMode : 'masonry'});//Add the class selected to the item that is clicked, and remove from the othersvar $optionSets = $('#filters'),$optionLinks = $optionSets.find('a');$optionLinks.click(function(){var $this = $(this);// don't proceed if already selectedif ( $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;});});
- There is some optional, but recommended CSS that you should add to animate the filtering. Place a CSS file with the code in your theme folder (for example /css/isotope.css). Feel free to add additional styles to make your posts look nice:
/* Start: Recommended Isotope styles *//**** 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, width;-moz-transition-property: height, width;-ms-transition-property: height, width;-o-transition-property: height, width;transition-property: height, width;}.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;}/* End: Recommended Isotope styles */
- In functions.php, load the scripts and CSS:
function add_isotope() {wp_register_script( 'isotope', get_template_directory_uri().'/js/libs/jquery.isotope.min.js', array('jquery'), true );wp_register_script( 'isotope-init', get_template_directory_uri().'/js/isotope.js', array('jquery', 'isotope'), true );wp_register_style( 'isotope-css', get_stylesheet_directory_uri() . '/css/isotope.css' );wp_enqueue_script('isotope-init');wp_enqueue_style('isotope-css');}add_action( 'wp_enqueue_scripts', 'add_isotope' );
That’s it!