Recently I needed to show posts that weren’t in any of the categories (for my custom archive page). It is a very common problem that you encounter when adding new custom post types to WordPress.
I came up with this little WordPress tip:
$postsWithoutCategories = new WP_Query(array( 'post_type' => 'post', 'category__not_in' => get_terms('category', array( 'fields' => 'ids' )), ... ));
Let me explain what is going on. We are creating new WP_Query object and passing into its constructor several params (as array). First one is post_type which is being used to define what kind of post types are we looking for and the second one (category__not_in) will exclude all posts that are in defined categories. Here we are fetching for all of the categories (but only their IDs as array should be provided here).
In plain terms, we are looking for all posts, which are of post_type type, and excluding all that are assigned to any of the categories.
As you can see, WP_Query can become a pretty powerful tool.
This even works for custom post types and custom taxonomies with small alterations:
$publicationsWithoutTerms = new WP_Query(array( 'post_type' => 'publication', 'tax_query' => array(array( 'taxonomy' => 'publication-category', 'field' => 'term_id', 'operator' => 'NOT IN', 'terms' => get_terms('publication-category', array( 'fields' => 'ids' )) )) ... ));
As you can see, custom taxonomy is complicating our WP_Query params but the logic is still the same. We need to use tax_query param and in it we need to specify which taxonomy are we looking at and most importantly which comparison operator we’ll be using (NOT IN in this case).
Of course, you use this query object in normal WordPress loops scenarios. I hope that this little WordPress tip will make your life easier and help you.