Query Multiple Taxonomies in WP 3.1

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!

This article was authored by:

Pippin Williamson is a WordPress developer based in Lawrence, KS. WordPress is his expertise: custom theme / plugin development, e-commerce solutions, content management, and everything else WordPress. His personal site can be found at PippinsPlugins.com. There he publishes frequent WordPress tutorials, tips and tricks. He also host a variety of his own free WordPress plugins. Join the site and receive member only benefits, including exclusive tutorial access and source file downloads.

Pippin Williamson has authored 42 posts.Visit Website

Showing 18 Comments

  • Peter Mancini (Admin)

    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.

    REPLY
  • Osu

    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

    REPLY
  • Pippin (Admin)

    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.

    REPLY
  • Osu

    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

    REPLY
  • Pippin (Admin)

    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.

    REPLY
  • Osu

    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

    REPLY
  • Pippin (Admin)

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

    REPLY
  • 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!

    REPLY
  • 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.

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

    :)

    REPLY
  • If you need further help, just ask :)

    REPLY
  • 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.

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

    REPLY
  • 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.

    REPLY
  • Pippin (Admin)

    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.

    REPLY
  • 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(); ?>

    REPLY
  • 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.

    REPLY
  • xdynx

    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â€Â

    REPLY

Add Your Voice: