I'm trying to override the default query on my client's single.php page and can't seem to affect the query at all, despite seemingly doing it correctly (guess not!).

I simply want to eliminate one category of posts from the query. Its slug is "homepage-item" and its category is 10 (when I hover over its name in the Dashboard listing of categories, I see (in part): "...taxonomy=category&tag_ID=10..."

I've simply inserted this near the top of my single.php:

<?php
    $customArgs = array( 
        'category__not_in' => '10' 
    );
    $custom_query = new WP_Query( $customArgs );
?>

...and I added my custom query's variable name here:

<?php
    if ( $custom_query->have_posts() ) {
        $count = 0;
        while ( $custom_query->have_posts() ) {
            $custom_query->the_post();
            $count++;
?>

But whatever I do, my query seems unaffected - the same content appears. I even tried changing $customArgs to remove virtually all content but see no change.

I'm sure I'm missing something obvious, but... what might it be?

Hope someone can help! Adam

up vote 1 down vote accepted

There's an action you could hook into. It's called pre_get_posts and it lets you alter the query before the query is run.

This code should be placed into your functions.php file.

function my_exclude_category( $query ) 
{
    if ( $query->is_singular('post') && $query->is_main_query() ) {
        $query->set( 'cat', '-10' );
    }
}
add_action( 'pre_get_posts', 'my_exclude_category' );

Please note. Your approach is not working because you are trying to create a new query within a theme template file that is supposed to be used to display a singular post. Also, you aren't affecting the main query by creating a new WP_Query. That's what the pre_get_posts action hook is for. The template file that is used for displaying a list of posts is e.g. archive.php please see the template hierarchy documentation for more information.

  • Thanks @marcwiest. I had avoided pre_get_posts due to reading this in the Codex: "pre_get_posts will not work if used in template files (e.g., archive.php), since they are called after the query has been completed." The trouble is, I built this site a long time ago and would do it differently now, but all kinds of custom content display is hard-coded into index.php and it's now simplest if a certain category doesn't appear there. I don't want it to be excluded everywhere though, which the function would do - right? – Adam Abrams Jun 13 at 2:42
  • Ah, I see it would be limited to single posts, i.e. not the front page. Will try it! – Adam Abrams Jun 13 at 2:45
  • It seems not to be working, but I should clarify: I'm still seeing a news item (wanted to remove these) as the Next post in the "Previous/Next" area, when I'm on the last-added of the posts I do want to see (ski resort reviews, the only kind of post I want to see here). I'd assumed that if WP_query didn't include News (cat. 10) posts, I'd see no "Next" link with a News item. Why might it still be there? (And yes, I've cleared my cache, etc.) – Adam Abrams Jun 13 at 20:28
  • I'm sure that pre_get_posts will do the trick. Take some time to study WP_Query as well as it's conditional tags. By using the example code from my answer and the documentation you will be able to modify the query any way you need. – Marc Wiest Jun 13 at 22:23
  • Thanks Marc, I will dig deep into WP_Query before I ask for further help (and hopefully won't need it!). – Adam Abrams Jun 14 at 3:56

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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