Skip to main content

The Cheeky Monkey Media Blog

A few words from the apes, monkeys, and various primates that make up the Cheeky Monkey Super Squad.

Rick Bjarnason - Owner and CEO, Cheeky Monkey Media - "Sucking at something is the first step to becoming sorta good at something"

Using WordPress to Query Multiple Taxonomies

I recently was working on a project that required a page to show the content from a blog post that belonged to a specific category, as well as some custom post types that belonged to a custom taxonomy.

My initial reaction was that I would need to write a custom SQL query to do this, but upon a bit more investigation I found that this is totally possible with a standard Wordpress query. Well, 'standard' might be a stretch but see what I mean.

 

How To Query Multiple Post Types

If all you need to do is query multiple custom posts you can do that with plain old query_posts.

Standard Query Posts
  1. array('post','custom post type')
  2. 	);
  3. 	query_posts($arg)
  4. ?>

Note: In case you are not aware, always break your queries into an array if you can as it is much quicker for Wordpress to process.

But what if you need to grab posts only from one category and from specific taxonomies? Then you would have to get a bit creative because the above code could not handle that, instead you need to turn to tax_query.

 

How to Query Multiple Taxonomies

tax_query is a new query function, which is really an array of arrays that specifies what to pull out of the database. Since that is a bit hard to understand by itself an example is probably helpful.

Let's say you want to pull all posts in a category of "cheese" and all the custom post types "dairy" with a taxonomy of "yogurt" you could write something like this:

Querying the wrong way
  1. <!--?php 
  2. $myquery['tax_query'] = array(
  3. 	array(
  4. 		'taxonomy' =--> 'category',
  5. 		'terms' => array('cheese'),
  6. 		'field' => 'slug',
  7. 	),
  8. 	array(
  9. 		'taxonomy' => 'dairy',
  10. 		'terms' => array('yogurt'),
  11. 		'field' => 'slug',
  12. 	),
  13. );
  14. query_posts($myquery);
  15.  
  16. ?>

One thing is that this will not work! You see by default the relationship in Wordpress is "AND" so all these parameters have to be true. Instead, the correct version is to change the relationship to an "OR" , you can do that like this:

Querying with a Relation
  1. <!--?php 
  2. $myquery['tax_query'] = array(
  3. 	'relation' =--> 'OR',
  4. 	array(
  5. 		'taxonomy' => 'category',
  6. 		'terms' => array('cheese'),
  7. 		'field' => 'slug',
  8. 	),
  9. 	array(
  10. 		'taxonomy' => 'dairy',
  11. 		'terms' => array('yogurt'),
  12. 		'field' => 'slug',
  13. 	),
  14. );
  15. query_posts($myquery);
  16.  
  17. ?>

This simple change is immensely powerful because you are not limited to categories or post types; you can also add tags.

Adding more variables
  1. <!--?php 
  2. $myquery['tax_query'] = array(
  3. 	'relation' =--> 'OR',
  4. 	array(
  5. 		'taxonomy' => 'category',
  6. 		'terms' => array('cheese'),
  7. 		'field' => 'slug',
  8. 	),
  9. 	array(
  10. 		'taxonomy' => 'dairy',
  11. 		'terms' => array('yogurt'),
  12. 		'field' => 'slug',
  13. 	),
  14. 	array(
  15.           'taxonomy' => 'post_tag',
  16.           'terms' => array('bar'),
  17. 	      'field' => 'slug',
  18. 	    ),
  19. );
  20. query_posts($myquery);
  21.  
  22. ?>

You can also add a negative match instead; for this you will use the operator parameter:

Querying with a Relation
  1. <!--?php 
  2. $myquery['tax_query'] = array(
  3. 	'relation' =--> 'OR',
  4. 	array(
  5. 		'taxonomy' => 'category',
  6. 		'terms' => array('cheese'),
  7. 		'field' => 'slug',
  8. 	),
  9. 	array(
  10. 		'taxonomy' => 'dairy',
  11. 		'terms' => array('yogurt'),
  12. 		'field' => 'slug',
  13. 	),
  14. 	array(
  15.           'taxonomy' => 'post_tag',
  16.           'terms' => array('bar'),
  17. 	      'field' => 'slug',
  18. 	      'operator' => 'NOT IN',
  19. 	    ),
  20. );
  21. query_posts($myquery);
  22.  
  23. ?>

 

What About Pagination?

So after finding the right query, I was a bit miffed when I discovered that Wordpress would actually not support pagination for this method. The thing is that with WordPress as soon as you run a $query_posts it will overwrite all the original page code that would be there by default (the $query_string). Without that information, WordPress cannot paginate correctly. So what you want to do is retain some of this information, I did it with wp_parse_args():

Retaining Pagination
  1. <!--?php
  2. global $query_string;
  3. $myquery = wp_parse_args($query_string);
  4. $myquery = array(
  5. 	'paged'=-->$paged,
  6. 	'numberposts'=>-1,
  7. 	'tax_query' => array(
  8. 		'relation' => 'OR',
  9. 		array(
  10. 			'taxonomy' => 'category',
  11. 			'terms' => array('blog'),
  12. 			'field' => 'slug',
  13.  
  14. 		),
  15. 		array(
  16. 			'taxonomy' => 'custom_post_type_1',
  17. 			'terms' => array('custom_taxonomy_1'),
  18. 			'field' => 'slug',
  19. 		),
  20. 		array(
  21. 			'taxonomy' => 'custom_post_type_2',
  22. 			'terms' => array('custom_taxonomy_2'),
  23. 			'field' => 'slug',
  24.  
  25. 		),
  26. 	),
  27.  );
  28. query_posts($myquery);
  29.  
  30.  
  31. ?>

 

Hope this helps you with some future projects!

The Wordpress design & development team at Cheeky Monkey Media is available to help you out with your Wordpress projects. The best part? You get all the credit! Give us a call.

Web Development

Would you like to know more about what we do?

View Our Services

Graphic Design Cheeky Monkey

Have a look at some our client work

View Our Work

Cheeky Monkey Discovery

Learn more about Cheeky Monkey Media

About Us

Comments