Codeable info

Query Multiple Taxonomies in WP 3.1

Posted on by in WordPress Tutorials

WordPress 3.1 is out, and it has some really cool new features. One of those new features is particularly useful for developers: querying multiple taxonomies.

Prior to 3.1, whenever we did a database query, and we wanted to limit the results to only posts tagged with “garden”, we were fine. But what if we wanted to display only posts tagged with “garden” AND categorized under “nature”. Well, we were out of luck.

But no more.

Setting it up is pretty simple. There is a new query_posts() parameter called “tax_query”.

Getting Posts with “garden” AND “lake”

1
2
3
4
5
6
7
8
9
10
11
12
13
$myquery['tax_query'] = array(
	array(
		'taxonomy' => 'category',
		'terms' => array('nature'),
		'field' => 'slug',
	),
	array(
		'taxonomy' => 'post_tag',
		'terms' => array('garden'),
		'field' => 'slug',
	),
);
query_posts($myquery);

This will display all posts that are tagged with “garden” and categorized in the “nature” category.

Excluding All Posts Categorized in Either Category

1
2
3
4
5
6
7
8
9
$myquery['tax_query'] = array(
	array(
		'taxonomy' => 'category',
		'terms' => array('nature', 'city'),
		'field' => 'slug',
		'operator' => 'NOT IN',
	),
);
query_posts($myquery);

This will display all posts except those in either the “nature” OR “city” category.

Displaying Posts from One OR the Other

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$myquery['tax_query'] = array(
	'relation' => 'OR',
	array(
		'taxonomy' => 'category',
		'terms' => array('nature'),
		'field' => 'slug',
	),
	array(
		'taxonomy' => 'post_tag',
		'terms' => array('garden'),
		'field' => 'slug',
	),
);
query_posts($myquery);

This will display all posts that are tagged with “garden” OR categorized in “nature”.

These are just a couple of examples of how we can use the new tax_query parameter available in WordPress 3.1. If you’re a developer, have you started using this feature? Do you plan to?

Enjoy!

)
Codeable info

Comments (18)

Comment by xdynx says:

I do not know how to implement in  get_terms
 
$terms = get_terms($myquery);  $count = count($terms); is wrong …
i want count my post with  âہ“gardenâ€Â AND âہ“lakeâ€Â

Comment by Rooter says:

Hello! Nice article! I was able to do what I wanted after a long time.

Here is an example of how to filter with AND and OR at the same time, it works for me:

http://www.therooter.com/2011/07/query_posts-y-tax_query-filtrar-categorias-con-and-y-or-en-wordpress.html

Sorry for my bad english!
Regards from Argentina.

Comment by Samuel Larsson says:

Hi! This isn´t exactly what you are looking for, but maybe you can can up with further ideas from it â€â€ I´ll post a snippet anyway that are using a predefined custom field in admin. I hope this is not spam:

query(‘meta_key=sliderKey&meta_value=ja&post_type=portfolio’);
while($sliderLoop->have_posts()) : $sliderLoop->the_post(); ?>

Comment by Pippin says:

You will have to use two queries for something like that. You may be able to do it with an advanced custom select query. Post a question on Stack Exchange. I expect someone there can help you out.

Comment by xwing says:

I think my brain is going to pop… I’d like to display pages from multiple post types, one of which has a custom taxonomy. But I only want to display posts from certain tags in that taxonomy, not all posts.

For example, I’ve got two custom post types: ‘dogs’ and ‘cats’. Cats has a custom taxonomy: ‘white’, ‘black’, ‘stripy’. I’d like to query all dogs but just white cats. So I’ve got:

$newquery = new WP_Query ( array( ‘post_type’ => array (‘dogs’,’cats’), ‘taxonomy’ => ‘cat-colour’, ‘term’ => ‘white’ ) );

But that query is just empty. Is this possible to do?

Thanks for your help.

Comment by Pippin Williamson says:

Yes you can, though you will set that up when you register the taxonomy.

Comment by dandy says:

Okay. Thats great. Can I have this kind of permalink structure also?

http://example.com/category/nature/gardens/
http://examples.com/category/(category)/(custom-taxonomy)/
?

Thanks for great post.
Best Regards.

Comment by Samuel Larsson says:

Thanks! (I have an snippet for pagination that works with wp_query. I guess i could play around with that)

:)

Comment by Pippin Williamson says:

If you need further help, just ask :)

Comment by Pippin Williamson says:

To limit the number, you could just add this below the tax_query: $myquery[‘posts_per_page’] = 3;

For pagination, it will work fine, but you will need to set up the paged query var, just like with any other custom query.

Comment by Samuel Larsson says:

Thanks! I´m more of a designer than developer but I´m using wordpress alot and I´ve just started to learn about custom taxonomies and post types.

Just one question: How do you limit the number of post shown and does that work with pagination?

Thanks!

Comment by Pippin Williamson says:

Looks awesome! I’m getting ready to build a new filtering system in the coming week, perhaps I use your code :)

Comment by Osu says:

Followed your advice – I ended up removing the first ‘All’ option as I was consistently getting 404’s when the trying to submit the form with no terms set (I believe WordPress 3.1 ignores your taxonomy if you have no terms set).

Here’s the code which is working (needs permalinks on): http://www.pastie.org/1632301

Thanks for the tip – hope this is useful for someone (big thanks to t31os on wordpress.stackexchange.com for his help on this)

osu

Comment by Pippin Williamson says:

Hmm, actually, upon looking at it, it looks like the best way for you to do it would be to simply make the terms fields required, so that users cannot submit the form until they have chosen at least one term.

Comment by Osu says:

Thanks for the tip – do you know the best way to integrate that into my code? Not sure of the best way to conditionally include those terms within an array:

http://www.pastie.org/1628023

Thanks,

osu

Comment by Osu says:

Hi Pippin,

I’m trying to build a custom taxonomy filter using dropdown options from a form. This is to filter some custom posts, so all very custom :)

I’m actually messing around with ‘tax_query’ quite a bit, but coming up against problems where I try to dynamically insert the terms from my custom taxonomies into the query.

Once I’ve got the form working (it breaks when no terms are entered i.e. ‘terms’ => ”, think the solution may be to remove that line of code entirely), then I’ll come back here and post my code as it may be useful to someone.

Nice post by the way,

Cheers,

osu

Comment by Pippin Williamson says:

You might try using an if ( !empty() ) check to determine whether a term was entered, and then only pass it to the query if it’s not empty.

Comment by Peter Mancini says:

I hadn’t looked into the new internals yet. Thanks for that update. I can see that being extremely useful. I’m experimenting with the 960.gs grid system and something like this allows for the ability to put different kinds of posts in various parts of the interface. A lot of people do things with ‘asides’ (functionality exists in TwentyTen theme for example) but clearly one could make a much more nuanced UX with this level of query control.

Codeable info