Complete Category and Taxonomy Querying in WordPress

Complete Category and Taxonomy Querying in WordPress

In an earlier article, we’d looked at how the regular categories and tags within WordPress might be insufficient for your categorization needs. For this reason, we learned how to create different taxonomies for unique scenarios, especially those where you need to add subcategories to existing ones.

But now that you’ve created the kind of logical structure for your blog that you want, we need to learn how to query it properly. If you’re just using categories, WordPress already has some pretty simple techniques to filter posts based on the category they’re in, or the category they are NOT in. But in addition, custom taxonomies have their own specific syntax that can get pretty complicated depending on the needs of your query.

In this article, we’ll take a comprehensive look at querying both categories as well as taxonomies. Since we already know that the default WordPress categories are simply a specific example of the more general taxonomy structure, we can use the latter as a more sophisticated form of the former.

So first let’s take a look at the inbuilt categories as well as the default functions that WordPress provides us for querying them.

Preparing the Query with pre_get_posts

Before we get started, you might be wondering how to get the results of your custom taxonomy category query onto the screen. The answer is by modifying the object WP_Query from within an action hook called “pre_get_posts”. This action allows you to parse the query object by reference. It means that you don’t need to explicitly return a value for the changes to take effect. A skeletal structure for the pre-get_posts action hook will look like this:

function modify_the_query_here($query) {

    // Check to see if in right place

    // Modify the query here

}
add_action( 'pre_get_posts', 'modify_the_query_here' );

Place this in your functions.php file before the closing ?> PHP tag. Whatever changes you make to the query will be reflected in the page currently displayed. If you only require the query to run for specific archives, taxonomies, or categories, insert a conditional statement at the beginning that checks to see whether or not you’re in the right place and return without doing anything if not.

If you don’t know how to add code snippets to WordPress, read my earlier tutorial on how to do so.

Querying Categories

if you only want to show posts from specific categories, here are various ways to go about it. Keep in mind that you might need to know the category ID which you can get by visiting the “Categories” menu under “Posts” in the WordPress dashboard.

Show posts with a category ID AND subcategories:

$query->set( 'cat', 23 );

Show posts with a category ID WITHOUT subcategories:

$query->set( 'category__in', 23 );

Note that the above line consists of a double underscore “__”.

Multiple Categories

You might want to show posts that belong to one of several categories. In which case, you can use something like this:

$query->set( 'category__in', array( 23, 19 ) );

This will set the query to posts that belong either to category number 23 or 19. If you want this to be a AND relationship instead of OR, you can use the “category__and” function like this:

$query->set( 'category__and', array( 23, 19 ) );

This will display posts that have a category of 23 as well as 19.

Finally, you can also exclude categories with the “category__not_in” parameter. Like this:

$query->set( 'category__not_in', array( 23, 19 ) );

In the last function, the second underscore is single “_”.

Taken together, these options provide you with a nice toolkit for displaying specific sets and subsets of categories while allowing you to exclude them as well. Where it fails however is in its inability to have more complex logical relationships.

Say for example you wish to show all posts either from the “technology” category, or those belonging to “Philosophy” AND “Personal”. Using the above functions, you can accomplish either one or the other – but not both. To solve this problem, we’re going to make use of the WordPress functions to display complex taxonomies. Since “category” is just an example of an existing taxonomy, the following functions will serve just as well for categories as well as custom taxonomies.

Simple Taxonomy Queries

The go to variable for taxonomy functions is “tax_query”. For example, if you have a custom taxonomy named “genre” and wants to only display the “fantasy” section, the following code should take care of that:

$tax_query = array(
    'post_type' => 'post',
    'tax_query' => array(
        array(
            'taxonomy' => 'genre',
            'field'    => 'slug',
            'terms'    => 'fantasy',
        ),
    ),
);
$query->set( 'tax_query', $tax_query );

In this, we specify the taxonomy name “genre”, and the “terms” variable contains the specific genre we want to filter. The “field” variable in this example tells us that we’re specifying the slug and not the ID.

Note that this is an “array of arrays”.

Complex Taxonomy Queries

Using this, we can create as many complex queries as we like. The catch is that arrays of arrays makes writing complex queries tricky.

In the previous section, I give an example of a query that can’t be solved using categories. With the “tax_query” toolkit, the code looks like this:

$tax_query = array(
        'post_type' => 'post',
        'tax_query' => array(
            'relation' => 'OR',
        array(
        'taxonomy' => 'category',
        'field'    => 'slug',
        'terms'    => array( 'technology' ),
        ),
        array(
                    'relation' => 'AND',
                    array(
            'taxonomy' => 'category',
            'field'    => 'slug',
            'terms'    => array( 'philosophy' ),
                    ),
                    array(
                        'taxonomy' => 'category',
                        'field'    => 'slug',
                        'terms'    => array( 'personal' ),
                    ),
        ),
    ),
);
$query->set( 'tax_query', $tax_query );

This code will retrieve posts belonging EITHER to the “technology” category, OR to posts belonging to BOTH the “philosophy” AND “personal” categories.

It starts out with an array or variables. The variable “relation” can be “AND” or “OR” followed by further arrays. This secondary array contains the following:

  1. taxonomy – the name of the taxonomy (in this case, category)
  2. field – how we will specify the terms (in this case, I will use the slug. Easier to read)
  3. terms – the actual terms within the taxonomy (in this case technology, philosophy, and personal).

Within this array, we can specify yet another “relation” (AND or OR), followed by another two or more arrays (which in turn can have more relation definitions).

In the above query, I’ve bolded the various terms that are specific to my example. Instead of rewriting the entire taxonomy query on your own, simply copy paste this code while making your own modifications. It’s easier to avoid making mistakes that way.

So for example, if you have your own custom taxonomies instead of “category”, replace the word “category” with the one you want. Similarly if you want to display your own post type, replace the word “post” with your own. And of course, you can modify the logical relationships between the various arrays.

Using “tax_query” should give you all the flexibility you need to construct any kind of complex taxonomy query. Once you wrap your head around nested arrays and logical relationships, it should be easy to take existing code and simply make the modifications you want.

As mentioned earlier, most of your needs should be met by categories and the associated simple functions that WordPress provides. But in case you need to get more complicated, you can do that as well.

Leave a Reply

This Website is Hosted by

Powered by RamNode

Disclosure: We receive a compensation from some of the companies whose products or services are presented on our website.