WordPress Query object is very powerful, and it allows you to filter posts with all sorts of criteria. One of the most important filters are taxonomy terms. You can filter using one or more taxonomies and one or more terms for each taxonomy. This tutorial will show you how.

Taxonomies terms filtering can be done only for taxonomies that are registered as public, and have set query variable. Query variable is the same as taxonomy name by default, but it can be registered to be anything as long as it is clean and URL safe (query variables are used in URL, so they can’t contain empty spaces or special characters). For instance, default WP taxonomies – category and post tags have query variables – category_name and tag.

URL Query

Taxonomies query variables can be used in URL like this:

// archive for category with name 'news' //

http://www.example.com/?category_name=news

// archive for category with name 'news' and post tag with name 'latest' //

http://www.example.com/?category_name=news&tag=latest

You can use more taxonomies in the URL like this, and you can even specify multiple terms separated by comma. But, the more terms you try to filter, number of posts will be smaller, and if you specify filter that gives no results, you will be redirected to 404 page (or to empty archive with no posts message).

Override the WP Query

It is useful to be able to override already prepared query and add filters for terms. This way you can modify query for archives by adding additional conditions. To do this, you need to use ‘pre_get_posts’ action, and to modify query arguments with function attached to that hook. Here is the example.

add_action('pre_get_posts', 'example_pre_get_posts_simple'));
function example_pre_get_posts_simple($query) {
  $query->set('tag', 'latest,wordpress,video');
  $query->set('category_name', 'news');
}

This example will expand query with filters for 3 terms belonging to post tags (comma separated strings: latest, wordpress and video) and one term belonging to category. Based on this Query class will generate tax_query object that contains elements that will be used to filter posts by taxonomies you have set and taxonomies that were already in the Query object before you hooked into it with pre_get_posts action. You can even modify tax_query with this hook, but that is not recommended because parsing taxonomies will be done once again after pre_get_posts. Still, it can be done, but you need to make sure you preserve old tax_query variable before adding your own. Tax_query elements are much more complicated than the example above, and you can specify relations for the terms and you can specify terms with ID’s or name, not only slug. Third method bellow shows how to get posts using custom tax_query array.

Using get_posts function

This function has many different ways to filter using terms. Function get_posts has an array of arguments, and there is a long list of parameters you can use with it, so you can specify posts count, post type, tags, categories, post ID’s and much more. First few examples are simple ways to specify terms:

//use category ID:
$posts = get_posts(array('category' => 1));

//use category slug with category query variable:
$posts = get_posts(array('category_name' => 'news'));

//use category slug and post tags slugs for 3 terms:
$posts = get_posts(array('category_name' => 'news', 'tag' => 'latest,wordpress,video'));

You can add more things here including custom taxonomies, using query variables for those custom taxonomies. Full list of parameters you can use can be found here: WP Query Parameters.

Another thing you can do is to specify terms using tax_query array. This allows more flexibility in specifying terms. Tax query is actually array of arrays. Each array is to specify the taxonomy terms and it is in form of array that has few parameters of its own. Each tax_query array can have 5 parameters:

  • taxonomy: name of the taxonomy, actual name, not query variable
  • field: it can be slug or ID, and it is used to define what is used to specify terms
  • terms: single ID or slug, or array with slugs or ID’s based on field parameter
  • include_children: should the children of terms be included, only for hierarchical taxonomies, and by default is set to true
  • operator: what operator to use in SQL query to link the specified terms: ‘IN’, ‘NOT IN’, ‘AND’

So, here is the example with two taxonomies:

$args = array(
  'tax_query' => array(
    array(
      'taxonomy' => 'post_tag',
      'field' => 'slug',
      'terms' => 'latest,wordpress,video'
    ),
    array(
     'taxonomy' => 'category',
     'field' => 'id',
     'terms' => 1
    )
  )
);
$posts = get_posts($args);

This will filter posts using 3 terms for post tags, specified by slugs, and by one category specified by ID.

There are a lot of possibilities to filter posts by multiple taxonomies and multiple terms. You need to choose method which works best for you, depending on what you need to do and how to filter posts, and be careful with listing multiple terms: more terms in the filter, the less posts you will get, or you will get no posts due to number of filter rules, and you can get to 404 page with no results.

3 Responses to “Expand WP Query: Taxonomies Terms”

  1. Rowan | April 7, 2012 at 12:14 pm

    Good post.

    How would you use WP Query to order a custom post by taxonomy terms? So for instance if your custom post is ‘listings’ and you have taxonomy ‘listing-type’, which is either ‘standard’ or ‘premium’, how would you construct a query to first show all ‘premium’ listings and afterwards show ‘standard’ listings?

    • MillaN | April 10, 2012 at 11:04 am

      No, WP_Query can’t sort by taxonomy without changing SQL query through filters. I have posted in the forum more info on this.

  2. Kenth Hagström | March 19, 2013 at 8:19 pm

    Something that’s also very useful is the relation parameter, like this:

    array(
    ‘taxonomy’ => ‘post_tag’,
    ‘field’ => ‘slug’,
    ‘terms’ => ‘latest,wordpress,video’,
    ‘relation’ => ‘OR’
    ),
    array(
    ‘taxonomy’ => ‘category’,
    ‘field’ => ‘id’,
    ‘terms’ => 1
    )

Leave a Reply

Dev4Press Plugins Pack

Dev4Press Plugins Pack

Personal$99.00
Business$249.00
Developer$499.00
GD bbPress Toolbox

GD bbPress Toolbox

Personal$30.00
Business$90.00
Developer$180.00
GD Custom Posts And Taxonomies Tools

GD Custom Posts And Taxonomies Tools

Personal$35.00
Business$105.00
Developer$210.00
GD Press Tools

GD Press Tools

Personal$40.00
Business$120.00
Developer$240.00
GD Products Center

GD Products Center

Personal$40.00
Business$120.00
Developer$240.00
xScape Theme Club

xScape Theme Club

Standard$149.00