How to filter posts that belong to a specific category only if that is the only category

I need to filter posts that belong to a category only if that is the only category. For example if my post A belongs to cat1 and I don’t want to display posts that belong to cat1, post A won’t be displayed. But if post A belongs to cat1 and cat2 it will be displayed as I don’t want to filter cat2.

I tried to do something like this:

Read More
<?php while (have_posts()) : the_post(); ?>

$category_to_exclude = 11;
while ( have_posts() ) : the_post();
$categories = get_the_category();
if( in_array($category_to_exclude, $categories) && count($categories) > 1 ) {
    the_title();
    the_content();
}
endwhile;

but of course it doesn’t work properly as “cut off” posts only. It should filtered directly from the query used to get the posts but I don’t know how to write this query. Any idea?

Related posts

Leave a Reply

1 comment

  1. You will need more than one query because before querying posts you have to know what posts to exclude.

    I personally don’t see anything bad in ‘cutoff’. This code should work properly:

    Update: It breaks pagination (see comments).

    <?php
    $category_to_filter = 11;
    while ( have_posts() ) : the_post();
        $categories = get_the_category();
        if( in_array($category_to_filter, $categories) && count($categories) > 1 ) {
            the_title();
            the_content();
        }
    endwhile;
    

    Update: Following code will not break pagination:

    <?php
    $category_to_filter = 11;
    $posts_in = array();
    while ( have_posts() ) : the_post();
        $categories = get_the_category();
        if( in_array($category_to_filter, $categories) && count($categories) > 1 ) {
            $posts_in[] = $post->ID;
        }
    endwhile;
    
    $my_query = new WP_Query( array(
        'post_type' => 'post',
        'post_status' => 'publish',
        'post__in' => $posts_in
        )
    );
    
    while ( $my_query->have_posts() ) : $my_query->the_post();
        // your template stuff here
    endwhile;
    wp_reset_query();