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 terms
foreach ( $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 terms
foreach ( $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 PHP
itemSelector : '.item',
layoutMode : 'masonry'
});
//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;
});
});
- 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!
Hi Alicia
It works for me, thanks a lot. But I have a little problem, the first subcategory listed don’t shows the content, I change the first subcategory for another one and is allways empty (only for the first). The other subcategories works fine for listing and filter. I don’t understand what is the problem, I think it’s all as you explained.
Thanks.
Hi again Alicia.
Solved!! In this line:
$the_query = new WP_Query( 'posts_per_page=50&cat='.$terms_ID_string );
I’d written the category number after cat= and it causes the problem.Thanks a lot again for the tutorial.
Hi Alicia,
Your post Integrate Isotope with WordPress, Part 2 (Categories) is excellent! It helped me getting that working. I have one question, I tried to edit your code to change the layoutmode to “cellsByRow” and it did not work. When I did that all the posts ended up on top of one another.
Do you have any advice?
Thanks!
Rocio
It’s hard to tell without looking at your code, but make sure that the item divs don’t have margins. I had a problem with that once.
Thanks so much for this. It works perfectly!
Just one question though.. is it possible to have 2 instances of the above code on the same page? I’m trying to add a second category and I duplicated the JavaScript making sure to use different variable names but the filtering won’t work for the second instance. Any advice you can give would be awesome!
I once did one with 4 at the same time (RRC Design Open House). You just have to initialize Isotope twice in your JavaScript. Without looking at your code, I can’t tell what’s wrong (you may want to try StackOverload), but you are welcome to look at the code in the site I just mentioned.
You’re a life saver!
Alicia,
Thank you!
Some details of your explanation made my job easier.