Exclude Taxonomy Terms from WordPress Queries
When displaying posts in WordPress you’ll be using the WP_Query
class to query your posts and sometimes you may want to exclude posts from specific taxonomy terms. This quick tutorial will explain how to use the tax_query
parameter in WP_Query to exclude terms from your loop.
Below is an example of a query where we are pulling posts from the”videos” post type and excluding the “action” genre.
$the_query = new WP_Query( [
'post_type' => 'videos',
'posts_per_page' => 50,
'tax_query' => [
[
'taxonomy' => 'genre',
'field' => 'slug',
'terms' => [ 'action' ],
'operator' => 'NOT IN',
],
],
] );
Dissecting our Example:
In our example we’ve taken a basic WP_Query and added a new tax_query parameter with an array. In the array we’ve added an array for the first value where we tell WordPress that we want to target the taxonomy genre, check for term slugs, specifically the action slug and we want to make sure it’s NOT In such term.
If you wanted to exclude multiple terms simply add them to the array like such:
'terms' => [ 'action', 'comedy', 'romance' ]
The most important thing to notice is that the tax_query parameter takes on an array of arrays for it’s value. In this example we are passing 1 value to the array since we are only looking to exclude a single term from a specific taxonomy.
Taxonomy Parameters Explained
A singular taxonomy query accepts the following parameters:
Parameter | Type | Description | Default |
---|---|---|---|
taxonomy | string | The taxonomy name. | term_id |
field | string | How you are selecting the taxonomy terms. Possible values are term_id, name, slug or term_taxonomy_id. | |
terms | string, int, array | The terms to select. | null |
operator | string | The logical operator. Possible values are IN, NOT IN, AND, EXISTS and NOT EXISTS. | IN |
include_children | boolean | Whether your query should include include children for hierarchical taxonomies. | true |
Making Multiple Taxonomy Queries
Remember I mentioned above that the tax_query parameter accepts an array or arrays? This is because you can pass on chain checks. So lets look at more advanced example:
$the_query = new WP_Query( [
'post_type' => 'videos',
'posts_per_page' => 50,
'tax_query' => [
'relation' => 'AND',
[
'taxonomy' => 'genre',
'field' => 'slug',
'terms' => [ 'action' ],
'operator' => 'IN',
],
[
'taxonomy' => 'actor',
'field' => 'slug',
'terms' => [ 'tom-cruise' ],
'operator' => 'NOT IN',
],
],
] );
So in this example first off we are adding a “relation” parameter to the top of the tax_query to tell it how it should be checking the different taxonomy arguments. In our case we are using “AND” which tells WordPress to combine the arguments.
The result of this query would be to pull 50 posts from the videos post type that are IN the action genre AND exclude any posts that are in the tom-cruise actor taxonomy.
Excluding Standard Categories and Tags
The title of the guide is how to exclude taxonomy terms and perhaps you are not aware of this, but in WordPress categories and tags are also considered taxonomies! So to exclude specific categories or tags from a query you can use the same method, simply use category
or post_tag
for the taxonomy name respectfully.
Check out the example below:
$the_query = new WP_Query( [
'post_type' => 'post',
'posts_per_page' => 50,
'tax_query' => [
'relation' => 'AND',
[
'taxonomy' => 'category',
'field' => 'slug',
'terms' => [ 'news' ],
'operator' => 'IN',
],
[
'taxonomy' => 'post_tag',
'field' => 'slug',
'terms' => [ 'sports' ],
'operator' => 'NOT IN',
],
],
] );
In this example we are querying posts in the “news” category but excluding any posts that are tagged under “sports”.
One thing to mention though is when you are working with categories and tags you don’t necessarily need to use a tax_query. WP_Query includes parameters you can use instead such as category__in
, category__not_in
, tag__in
, tag__not_in
…etc.
Example:
$the_query = new WP_Query( [
'post_type' => 'post',
'posts_per_page' => 50,
'category__in' => 1,
'tag__not_in' => 2,
] );
Personally I prefer using tax_query
for consistency, especially if I’m going to make multiple checks. Plus, using these other parameters means you need to pass on the term ID instead of using a slug which could be confusing later on when looking at your code.
Excluding Terms from Archives & Search Results
Perhaps you are not working with a custom WP_Query but rather you are trying to exclude terms from archives such as your blog, categories, homepage or search results. This is also possible and to do this you will want to hook into the pre_get_posts filter.
Below is a snippet showing a few different examples for excluding content across different parts of your site:
add_filter( 'pre_get_posts', function( $query ): void {
if ( is_admin() || ! $query->is_main_query() ) {
return;
}
// Exclude "uncategorized" category from search results.
if ( $query->is_search() ) {
$query->set( 'tax_query', [
[
'taxonomy' => 'category',
'field' => 'slug',
'terms' => [ 'uncategorized' ],
'operator' => 'NOT IN',
]
] );
}
// Exclude "uncategorized" category from homepage.
if ( $query->is_home() ) {
$query->set( 'tax_query', [
[
'taxonomy' => 'category',
'field' => 'slug',
'terms' => [ 'uncategorized' ],
'operator' => 'NOT IN',
]
] );
}
// Exclude tutorials tag from category archives.
if ( $query->is_category() ) {
$query->set( 'tax_query', [
[
'taxonomy' => 'category',
'field' => 'slug',
'terms' => [ 'tutorials' ],
'operator' => 'NOT IN',
]
] );
}
} );
Important: I’ve noticed that even if you exclude a specific term from your homepage using the pre_get_posts
filter if you have posts that are “sticky” they will display regardless. Just wanted to mention this to prevent any confusion, since it was driving me crazy!
Conclusion
Hopefully you now know how to properly exclude terms from your custom queries, archives and search results by using the tax_query parameter. As always, if you have any issues, questions or feedback be sure to let me know in the comments!
Thank you, I was searching about a good 2 hours trying to figure this out.
Hey there..
I have been trying this method for hours and its just not working. Curious if you could take a look at my code below and let me know what I might be doing wrong?
My Taxonomy is – member_type
and the term I would like to exclude has the slug of “private”..
any help is appreciated..
thanks..
If you can paste the full query somewhere else, maybe Pastebin, where it won’t get messed up by WP I’ll have a quick look for you. Maybe the issue isn’t how you are excluding the term, but maybe its the query itself?
thanks!! :)))
Thank you, I was searching about half day for issue.
Thank you for this article, it allowed me to quickly implement the correct changes to my project.