1. Code
  2. WordPress

WP_Query Arguments: Categories and Tags

This post is part of a series called Mastering WP_Query.
WP_Query Arguments: Posts, Pages and Post Types
WP_Query Arguments: Taxonomies

In the earlier parts of this series, you've learned how WP_Query is structured and what its properties and methods are. The next stage is to understand the various arguments you can use with it and how best to do so.

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 two types of argument, for the following:

  • categories
  • tags

The arguments for these two taxonomies are similar but do have some differences you need to know about if you're going to use them effectively.

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: resetting post data

In practice this will look something like the following:

The arguments are what tells 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:

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:

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.

Category Parameters

Let's start with category parameters. The options you have here are as follows:

  • cat (int): use category id.
  • category_name (string): use category slug (NOT name).
  • category__and (array): use category id.
  • category__in (array): use category id.
  • category__not_in (array): use category id.

Note that for none of these do you use the name of your category. Even the category_name parameter takes the slug as its value, not its name. I tend to use this one rather than the ID as when I come back to my code at a later date, slugs are easier to identify than IDs. However if you think your site users might change the slug for one or more categories, I recommend using the ID to avoid any problems.

Let's take a look at how you use each of these.

The cat Parameter

The cat parameter is straightforward: just use a single category ID or a string of category IDs.

Querying for one category looks like this:

Querying for multiple categories looks like this:

The above will tell WordPress to fetch posts that are in any of the categories listed. If you want to find posts in every one of an array of categories, you use the category_and parameter, of which more shortly.

You can also use the cat parameter to find posts that are in one category but not another, by using a minus sign before the category ID as follows:

The above would query posts in category 12 but not in category 13.

The category_name Parameter

The category_name parameter uses the category slug, not the name (confusing, I know!). Again you can use it with a single category or with a string of categories to find posts that are in any of the categories.

To query posts in a single category you add:

And to find posts in one or more of a number of categories, use this:

As with the cat parameter, this won't find posts that are in all of the categories, but it will find posts in any of the categories.

The category__and Parameter

If you want to find posts that are in all of an array of categories, this is the parameter you use. It takes the category IDs for its value. So to find posts in all of three categories, you would use:

Note that this uses an array not a string, so you code it differently. The parameter has two underscores in its name: use just one and it won't work.

The category__in Parameter

The next parameter looks for posts in one or more of an array of categories. It actually works in the same way as the cat parameter, and also takes the category ID as its value.

So to query posts in one or more of an array of categories, you would use:

The above would fetch posts from one or more of these categories.

The category__not_in Parameter

The category__not_in parameter does as you would expect: it queries posts which are not in a category or an array of categories.

To exclude posts from one category, you would use the following:

And to exclude posts from an array of categories:

This would exclude posts from any of these categories.

Tag Parameters

Tags have slightly different parameters from categories: you can't work out what they might be based on your knowledge of category parameters, I'm afraid!

The tag parameters are:

  • tag (string): use tag slug.
  • tag_id (int): use tag id.
  • tag__and (array): use tag ids.
  • tag__in (array): use tag ids.
  • tag__not_in (array): use tag ids.
  • tag_slug__and (array): use tag slugs.
  • tag_slug__in (array): use tag slugs.

Let's look at each of these.

The tag Parameter

The tag parameter takes the tag slug for its value and can be used to find posts with one tag or with any of a string of tags.

So to find posts with one tag you use:

And to find posts with tags from an array of tags:

Note that the above queries posts with any of the tags in the array, not all of them.

The tag_id Parameter

The tag_id parameter works in a similar way to the cat parameter: it takes the tag ID and can be used with a single tag or multiple tags.

To find posts with a single tag you use this:

To find posts with one or more tags from a string of tag IDs:

You can also use tag_id to exclude tags, either when using it for single tags or multiple tags.

So to query posts except those with a given tag, you'd use:

While to find posts with one of two tags but without another tag, you'd use this:

So the above will query posts with either or both of tags 21 or 23 but not tag 22.

The tag__in Parameter

This parameter lets you find posts with one or more of an array of tags. It works in the same way as tag when used with an array:

This will query posts with any or all of the tags listed. If you want to find posts with all of the tags, you use tag__and, which I'll cover in a moment.

The tag__not_in Parameter

The tag__not_in parameter lets you query posts which don't have a given tag or array of tags.

Use it like this to exclude one tag:

Note that you still need to use an array even though you're only using one tag. For more tags, use:

This will query posts that don't have any of the above tags.

The tag_slug__and and tag_slug__in Parameters

These two parameters behave in exactly the same way as the tag__and and tag__in parameters, except that you use that tag slug in your arrays instead of the tag ID.

So for example to find posts which have both of a pair of tags, you use tag__slug_in:

This finds posts with any of these tags. You could also use the tag parameter with a string of tag slugs to achieve the same result.

To include posts with all of a set of tags, use tag_slug__and:

Instead of querying posts with any of the tags, this only queries posts that have all of the tags.


Querying your posts by category and/or tag is something there's a good chance you'll have occasion to do with WP_Query. By using the arguments above, and combining them where necessary, you can create powerful arguments to extract exactly the data you need from the database.

Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.