2

I am trying to select posts that have category id 4 but exclude posts that also have category id 2

Here's what i'm trying

$query = new WP_Query(array(
  "cat__in"         => array(4),
  "cat__not_in"     => array(2),
  "post_type"       => "post",
  "post_status"     => "publish",
  "orderby"         => "date",
  "order"           => "DESC",
  "posts_per_page"  => $limit,
  "offset"          => 0
));

However, it's not making the proper selection. What am I doing wrong?

1
  • 1
    cat__in and cat__not_in is not valid parameters. Go and check the valid category parameters in WP_Query. You can just simply pass 'cat'=>4 to your arguments to just get posts from category 4. Or as Brad suggested, use pre_get_posts and pass the same parameters to that Commented Jul 14, 2014 at 10:09

3 Answers 3

1

Use pre_get_posts to exclude the categories you don't want to display in the loop.

function exclude_posts_from_specific_category( $query ) {
    if ( $query->is_home() && $query->is_main_query() ) {
        $query->set( 'cat', '-2' );
    }
}
add_action( 'pre_get_posts', 'exclude_posts_from_specific_category' );

Or create a new WP_Query and use the Category Parameters.

<?php

$args = array( 

'category__not_in' => 2 ,

'category__in' => 4 

);

$the_query = new WP_Query( $args );


if ( $the_query->have_posts() ) {
        echo '<ul>';
        while ( $the_query->have_posts() ) {
        $the_query->the_post();
        echo '<li>' . get_the_title() . '</li>';
    }
        echo '</ul>';
} else {

}

wp_reset_postdata();

If you only want to display posts from one category, you would use the category archive. See Template Hierarchy.

5
  • Ah, that was my problem. I was using cat__in and cat__not_in. I needed to use the full word category in each parameter. I'm going to tinker with your other method, too.
    – user56536
    Commented Jul 14, 2014 at 18:05
  • I've edited my answer to compile a complete(?) list of methods to do this.
    – user56536
    Commented Jul 14, 2014 at 18:34
  • That's great @naomik. Did you also test your code as well? Commented Jul 14, 2014 at 21:22
  • do you mean unit tests? I just ran a quick smoke test to see that each method in my post works.
    – user56536
    Commented Jul 14, 2014 at 23:38
  • Lets leave the commenting here as its dragging out a bit but i simply suggest you test all code snippets in your theme. Commented Jul 15, 2014 at 8:23
1

As it turns out, this can be done in 4 separate ways

Using cat with a negative number

$query = new WP_Query(array(
  "cat" => "4, -2",
  // ...
));

Using category__in and category__not_in

I was mistakenly using cat__in and cat__not_in which are not valid WP_Query parameters

$query = new WP_Query(array(
  "category__in"     => array(4),
  "category__not_in" => array(2),
  // ...
));

Using tax_query

$query = new WP_Query(array(
  "tax_query" => array(
    "relation" => "AND",
    array(
      "taxonomy" => "category",
      "field"    => "term_id",
      "terms"    => array(4)
    ),
   array(
      "taxonomy" => "category",
      "field"    => "term_id",
      "terms"    => array(2),
      "operator" => "NOT IN"
    ),
  ),
  // ...
));

Using the pre_get_posts filter (as provided by Brad Dalton)

function exclude_posts_from_specific_category($query) {
  if ($query->is_home() && $query->is_main_query()) {
    $query->set("cat", "-2");
  }
}
add_action("pre_get_posts", "exclude_posts_from_specific_category");
3
-3

Suppose you have posts with cat id 4.

query_posts('cat=4');
  while (have_posts()) : the_post();
      the_content();
  endwhile;
4
  • Please add an explanation to your answer: why would that solve the problem?
    – fuxia
    Commented Jul 14, 2014 at 9:23
  • You should never use query_posts, never Commented Jul 14, 2014 at 10:04
  • reason for never using query_posts ?
    – jojo
    Commented Jul 14, 2014 at 10:27
  • This post should shed some light on that Commented Jul 14, 2014 at 10:49

Your Answer

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