Advertisement
  1. Code
  2. PHP

WP_Query Arguments: Taxonomies

Scroll to top
This post is part of a series called Mastering WP_Query.
WP_Query Arguments: Categories and Tags
WP_Query Arguments: Custom Fields

So far in this series, you've learned how WP_Query is structured and what its properties and methods are. Now we're looking at the various arguments you can use with WP_Query and how you code them.

WP_Query has a large number of possible arguments, which makes it extremely flexible. As you can use it to query just about anything held in your wp_posts table, it has arguments for every permutation of query you might want to run on your content.

In this tutorial, I'll look at arguments for querying taxonomy terms.

A Recap on How Arguments Work in WP_Query

Before we start, let's have a quick recap on how arguments work in WP_Query. When you code WP_Query in your themes or plugins, you need to include four main elements:

  • the arguments for the query, using parameters which will be covered in this tutorial
  • the query itself
  • the loop
  • finishing off: closing if and while tags and resetting post data

In practice, this will look something like the following:

1
<?php
2
3
$args = array(
4
    // Arguments for your query.

5
);
6
7
// Custom query.

8
$query = new WP_Query( $args );
9
10
// Check that we have query results.

11
if ( $query->have_posts() ) {
12
13
    // Start looping over the query results.

14
    while ( $query->have_posts() ) {
15
16
        $query->the_post();
17
18
        // Contents of the queried post results go here.

19
20
    }
21
22
}
23
24
// Restore original post data.

25
wp_reset_postdata();
26
27
?>

The arguments tell WordPress what data to fetch from the database, and it's those that I'll cover here. So all we're focusing on here is the first part of the code:

1
$args = array(
2
    // Arguments for your query.

3
);

As you can see, the arguments are contained in an array. You'll learn how to code them as you work through this tutorial.

Coding Your Arguments

There is a specific way to code the arguments in the array, which is as follows:

1
$args = array(
2
    'parameter1' => 'value',
3
    'parameter2' => 'value',
4
    'parameter3' => 'value'
5
);

You must enclose the parameters and their values in single quotation marks, use => between them, and separate them with a comma. If you get this wrong, WordPress may not add all of your arguments to the query or you may get a white screen.

The Taxonomy Parameters

Setting parameters for taxonomy terms is a little more complicated than for categories and tags since you use tax_query. Within this argument, you write a nested array of arguments to specify the taxonomy and term using these parameters:

  • taxonomy (string): taxonomy
  • field (string): select taxonomy term by ('term_id (default), 'name' or 'slug')
  • terms (int/string/array): taxonomy term(s)
  • include_children (boolean): whether or not to include children for hierarchical taxonomies. Defaults to true.
  • operator (string): operator to test. Possible values are 'IN' (default), 'NOT IN', 'AND', 'EXISTS', and 'NOT EXISTS'.

The fact that you have the operator parameter means you don't need to choose from one of a range of available arguments to define whether you're including or excluding terms (as you do for tags and categories), but can use tax_query for everything taxonomy-related instead.

If you want to query for multiple taxonomies, you can also use the relation parameter before all of your arrays (one for each taxonomy) with AND or OR to specify whether you want to find posts with all of the terms or any of them.

This is most easily explained with some examples.

Querying for One Taxonomy Term

This is the simplest scenario and involves just using one nested array:

1
$args = array(
2
    'tax_query' => array(
3
        array(
4
            'taxonomy' => 'category',
5
            'field' => 'slug',
6
            'terms' => 'tutorial',
7
        )
8
    )
9
);
Post by Category SlugPost by Category SlugPost by Category Slug

The above queries for posts with the tutorial term in the category taxonomy. Note that you also need to use the field parameter to identify which field you're using to identify the term, unless you're using the term ID which is the default. If you wanted to use the term ID, you'd use something like this:

1
$args = array(
2
    'tax_query' => array(
3
        array(
4
            'taxonomy' => 'category',
5
            'terms' => '11'
6
        )
7
    )
8
);
Post by Category IDPost by Category IDPost by Category ID

Using the ID makes it harder for you to identify what your query is looking for at a later date, but it avoids any potential problems if you think your users might edit the term slugs.

Querying for Multiple Terms in One Taxonomy

If you want to identify posts with one or more of an array of terms in the same taxonomy, you still write one nested array, but add an array of terms.

For example, to query posts with any of a list of term IDs from your taxonomy, you use:

1
$args = array(
2
    'tax_query' => array(
3
        array(
4
            'taxonomy' => 'post_tag',
5
            'terms' => [14, 17]
6
        )
7
    )
8
);
Posts by Any Tag IDPosts by Any Tag IDPosts by Any Tag ID

But what if you wanted to query posts with all of these terms? You'll need to use the operator parameter inside your nested array:

1
$args = array(
2
    'tax_query' => array(
3
        array(
4
            'taxonomy' => 'post_tag',
5
            'terms' => [14, 17],
6
            'operator' => 'AND'
7
        )
8
    )
9
);
Posts by All Tag IDsPosts by All Tag IDsPosts by All Tag IDs

Note that the first example actually uses the IN operator to find posts with any of the terms, but as this is the default, you don't have to specify it in your arguments.

Another scenario is if you want to query for posts which don't have any of an array of terms in one taxonomy, which you do like this:

1
$args = array(
2
    'tax_query' => array(
3
        array(
4
            'taxonomy' => 'post_tag',
5
            'terms' => [14, 17],
6
            'operator' => 'NOT IN'
7
        )
8
    )
9
);
Posts by None Tag IDsPosts by None Tag IDsPosts by None Tag IDs

Here, I've replaced the AND operator with NOT IN, which means WordPress will find posts without any of the terms in the array.

Note that if you prefer to use slugs instead of term IDs, you can do so with any of these scenarios. The last example would look like this:

1
$args = array(
2
    'tax_query' => array(
3
        array(
4
            'taxonomy' => 'post_tag',
5
            'field' => 'slug',
6
            'terms' => ['php', 'strings'],
7
            'operator' => 'NOT IN'
8
        )
9
    )
10
);
Posts by None Tag SlugPosts by None Tag SlugPosts by None Tag Slug

Querying Terms From Multiple Taxonomies

If you want to work with more than one taxonomy, you'll need to create more than one array. Let's look at the simplest example, to query posts with one term from the category taxonomy and one term from the tag taxonomy:

1
$args = array(
2
    'tax_query' => array(
3
        'relation' => 'AND',
4
        array(
5
            'taxonomy' => 'category',
6
            'field' => 'slug',
7
            'terms' => ['tutorial']
8
        ),
9
        array(
10
            'taxonomy' => 'post_tag',
11
            'field' => 'slug',
12
            'terms' => ['javascript']
13
        )
14
    )
15
);
Multiple Taxonomies with AND OperatorMultiple Taxonomies with AND OperatorMultiple Taxonomies with AND Operator

Here I've written two nested arrays: one for each taxonomy, using the same arguments as I did for the examples using just one taxonomy. I've preceded these with the relation argument. You need to include the relation argument to tell WordPress whether it's looking for all or some of the posts output by each array. This works as follows:

  • If you use 'relation' => 'AND', WordPress will fetch the posts specified in the first array and the second array. So in the example above, only posts with both the tutorial slug in category and the javascript slug in post_tag will be queried.
  • If you use 'relation' => 'OR', WordPress will fetch posts output by the first array or the second array. So in this case you'll get posts with either the tutorial slug or the javascript slug (or both).

This is the code you'd use if you were looking for posts with either of the two slugs:

1
$args = array(
2
    'tax_query' => array(
3
        'relation' => 'OR',
4
        array(
5
            'taxonomy' => 'category',
6
            'field' => 'slug',
7
            'terms' => ['tutorial']
8
        ),
9
        array(
10
            'taxonomy' => 'post_tag',
11
            'field' => 'slug',
12
            'terms' => ['javascript']
13
        )
14
    )
15
);
Multiple Taxonomies with OR OperatorMultiple Taxonomies with OR OperatorMultiple Taxonomies with OR Operator

You can also look for more than one term in a given taxonomy by adding it to the array:

1
$args = array(
2
    'tax_query' => array(
3
        'relation' => 'OR',
4
        array(
5
            'taxonomy' => 'category',
6
            'field' => 'slug',
7
            'terms' => ['guide']
8
        ),
9
        array(
10
            'taxonomy' => 'post_tag',
11
            'field' => 'slug',
12
            'terms' => ['php', 'strings']
13
        )
14
    )
15
);
Multiple Taxonomies with Multiple TermsMultiple Taxonomies with Multiple TermsMultiple Taxonomies with Multiple Terms

By combining the relation argument with queries and also using the operator argument, you can create sophisticated queries. The arguments below would query posts with a term from one taxonomy but without a term from another taxonomy:

1
$args = array(
2
    'orderby' => 'title',
3
    'tax_query' => array(
4
        'relation' => 'AND',
5
        array(
6
            'taxonomy' => 'category',
7
            'field' => 'slug',
8
            'terms' => ['tutorial'],
9
            'operator' => 'NOT IN'
10
        ),
11
        array(
12
            'taxonomy' => 'post_tag',
13
            'field' => 'slug',
14
            'terms' => ['php', 'math'],
15
            'operator' => 'AND'
16
        )
17
    )
18
);
Multiple Taxonomies with Operator RelationsMultiple Taxonomies with Operator RelationsMultiple Taxonomies with Operator Relations

Note that I've used 'relation' => 'AND' here: if I used OR, it would query posts with slug-two and posts without slug-one, rather than posts which have slug-two but not slug-one, which is what I'm looking for.

You could conceivably take this further to query your taxonomies' terms however you wanted: using the operator argument in both nested queries or adding an additional nested query to query terms in another taxonomy.

Nested Taxonomy Queries

It is possible for you to create nested taxonomy queries to create much more complex filters to get your posts. Support for nested taxonomies was added to WordPress core in version 4.1. It was either a lot more complicated or downright impossible to get similar results earlier.

1
$args = array(
2
    'tax_query' => array(
3
        'relation' => 'OR',
4
        array(
5
            'taxonomy' => 'category',
6
            'field' => 'slug',
7
            'terms' => ['guide'],
8
        ),
9
        array(
10
            'relation' => 'AND',
11
            array(
12
                'taxonomy' => 'category',
13
                'field' => 'slug',
14
                'terms' => ['tutorial'],
15
            ),
16
            array(
17
                'taxonomy' => 'post_tag',
18
                'field' => 'slug',
19
                'terms' => ['php', 'strings'],
20
                'operator' => 'AND'
21
            )
22
        )
23
    )
24
);

The above query will select posts under the category taxonomy with the guide slug or posts that have the tutorial slug under category and have the php, strings slug combination under post_tag.

Nested Taxonomy OperatorsNested Taxonomy OperatorsNested Taxonomy Operators

A Note on the tax Argument

You may be wondering why I haven't included the {tax} argument, where you simply write your argument as follows:

1
$args = array(
2
    'taxonomy1' => 'slug-one'
3
);

You may be familiar with this way of querying taxonomies if you've done it in the past, but it's now deprecated, and you shouldn't use it. So stick to tax_query! Using tax_query gives you a lot more flexibility anyway.

Summary

Querying taxonomies is a bit more complicated than categories and tags, as you need to get to grips with the tax_query argument.

However, as we've seen, this is a very powerful argument that gives you a lot of scope and flexibility to query your database in whatever way you wish.

This post has been updated with contributions from Nitish Kumar. Nitish is a web developer with experience in creating eCommerce websites on various platforms. He spends his free time working on personal projects that make his everyday life easier or taking long evening walks with friends.

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.