2

Using WP_Query, I need to gather a selection of posts that are both Category1 and Category2. I want this selection to include Category1 and all of its subcategories (Category3 and Category4), as long as they are also labeled Category2, even if they aren't labeled Category1.

Categories:

Name          ID     Parent
Category1     1
Category2     2
Category3     3      1
Category4     4      1

Posts:

ID     Categories
1      1,2
2      2,3
3      2,4


Now, if I were to use WP_Query to find posts in just Category1 it seems to find all three posts including Post2 and Post3 since Category3 and Category4 are subcategories of Category1 even though the posts aren't Category1.

new WP_Query(
        array(
            'cat' => 1
        )

However, if I use 'category__and' to find posts that are both Category1 and Category2

new WP_Query(
        array(
            'category__and' => array(1, 2)
        )

it only finds Post1 that has both Category1 and Category2, but it won't find Post2 that is Category2 and Category3 or Post3, even though Category3 and Category4 are subcategories of Category1.

Is there a way I can take the result of this:

new WP_Query(
        array(
            'cat' => 1
        )

Which finds posts that are Category1 AND subcategories of Category1, even if they aren't also Category1...

And then filters it to only include those posts that also are Category2?

Thanks for any suggestions.

3
  • I mistyped 'cat' as 'cat_id' in the above question, but 'cat' is what I'm actually using in my working code. Question code has been corrected.
    – user79283
    Sep 14, 2014 at 14:08
  • added some additional clarification
    – user79283
    Sep 14, 2014 at 14:15
  • Welcome to WPSE. If you haven't done so, please see How to Ask and also visit our tour page. It is important to make sure to provide correct details/code for someone to help you. This also avoids that your question gets closed due to syntax errors. :-) Sep 14, 2014 at 16:14

2 Answers 2

1

The category parameters of WP_Query does not have this type of logic. category__and and category__in does not return posts in child categories of the set categories.

I would suggest that you make use of the tax_query parameters in WP_Query, which have the logic you are looking for. The relation parameter has two possible values, AND and OR

relation (string) - The logical relationship between each inner taxonomy array when there is more than one. Possible values are 'AND', 'OR'. Do not use with a single inner taxonomy array.

Also, by default, child terms are included in a tax_query, and that is what you need.

include_children (boolean) - Whether or not to include children for hierarchical taxonomies. Defaults to true.

You can do something like this:

$args = array(
    'post_type' => 'post',
    'tax_query' => array(
    'relation' => 'AND',
        array(
            'taxonomy' => 'category',
            'field'    => 'term_id',
            'terms'    => 1,
        ),
        array(
            'taxonomy' => 'category',
            'field'    => 'term_id',
            'terms'    => 2,
            'include_children' => false,
        ),
    ),
);
$query = new WP_Query( $args );

What this code does, it looks for posts that are in category 1 and in its child categories, also, it checks whether these posts from category 1 and its child categories are also in category 2. The list of posts returned will be posts that are in category 1 or any of its child categories and which is also in category 2.

I have excluded the child categories from category 2, but you can remove this if needed.

2
  • Awesome - that worked. I'd upvote your answer, but I don't have high enough reputation yet. Thanks for the help!
    – user79283
    Sep 14, 2014 at 16:30
  • No problem. Glad this worked out for you. Enjoy :-) Sep 14, 2014 at 16:32
3

What describe is the way it should work:

  • cat_id it is not a valid argument, so you get posts from all categories. Use cat to set one category ID or an array of categories ID. For example:

Get posts from category 1:

new WP_Query(
    array(
        'cat' => 1
    )

Get posts from category 1 and from category 2 (not in both necessarily)

new WP_Query(
    array(
        'cat' => array( 1, 2 )
    )
  • category__and finds posts that belongs to all specified categories. For example:

Get posts that are in both categories, 1 and 2:

new WP_Query(
    array(
        'category__and' => array( 1, 2 )
    )

More details in WP Query, category parameters.

1
  • Sorry, I mistyped 'cat' as 'cat_id' in the above question, but 'cat' is what I'm actually using in my working code. So this doesn't answer my question yet. I want to get to find all posts that are in Category2 AND (Category1 OR SubCategories of Category1). Your 'category__and' code does not find the subcategories
    – user79283
    Sep 14, 2014 at 14:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.