Your problem is your query, but before I cover that, there are some concerns that are getting in the way of seeing the problem.
Firstly, every single line has . It’s like hanging up and dialling the number again at the end of every sentence in a telephone conversation, and it’s so much more effort to type and read. So lets fix that:
<?php
$query = new WP_Query( 'cat=-32,-99' );
if ( $query->have_posts() ) :
while ( $query->have_posts() ) :
$query->the_post();
if (! in_category ('-32')) ;
x_get_view( 'ethos', 'content', get_post_format() );
endif;
endwhile;
wp_reset_postdata();
else :
?> <p><?php _e( 'Sorry, no posts matched your criteria.' ); ?></p><?php
endif;
This is much easier to read, and reveals a new bug you were unaware of. You’ve been using the shorthand syntax here:
if (! in_category ('-32')) ;
x_get_view( 'ethos', 'content', get_post_format() );
endif;
But notice the if statement has a ;
not a :
? This evaluates to:
if ( ! in_category( '-32' ) ) {
// do nothing
}
x_get_view( 'ethos', 'content', get_post_format() );// this always happens
You can also pass -32
rather than '-32'
into in_category
. I strongly recommend using if () {}
syntax as it’s more widespread, better supported in tools and editors, and easier to type. Don’t make extra work for yourself.
You’re also checking if the post is inside the category -32
, do you mean to check against 32
?
Moving on to your original problem:
$query = new WP_Query( 'cat=-32,-99' );
Here cat
is being used, however this isn’t the best way to define it, and technically cat
should take a single parameter. Instead define it this way:
$query = new WP_Query( array(
'category__not_in' => array( 32, 99 )
) );
My final concern is that you’ve hardcoded the IDs of the category terms. This code will fail spectacularly if you ever tried an import/export. This is a bad case of magic numbers
Instead, perhaps use the category slugs instead:
$example_term = get_term_by( 'name', 'example1', 'category' );
$example_term_2 = get_term_by( 'name', 'example2', 'category' );
$query = new WP_Query( array(
'category__not_in' => array( $example_term->term_id, $example_term_2->term_id )
) );
While category slugs/names are still bad, they’re much more portable and robust than category term IDs. Ideally you would pull these from an option value or a post meta value instead.
The Final and Most Important Issue
All of this, is exactly the same as doing this:
query_posts( array(
'category__not_in' => array( 32, 99 )
) );
You’ve discarded all the work WordPress did then did it a second time yourself.Instead, you should be using the pre_get_posts
filter to tell WordPress what you actually wanted, putting it all together giving us:
add_filter( 'pre_get_posts', function ( $query ) {
if ( $query->is_home() && $query->is_main_query() ) {
$example_term = get_term_by( 'name', 'example1', 'category' );
$example_term_2 = get_term_by( 'name', 'example2', 'category' );
$query->set( 'category__not_in', $example_term->term_id, $example_term_2->term_id );
}
});
This allows you to use the main loop rather than a custom WP_Query loop, simplifying your original code even further