Support

Account

Home Forums Backend Issues (wp-admin) Exclude posts from main loop based on ACF field value

Solved

Exclude posts from main loop based on ACF field value

  • I have a custom WP Query that shows a single post based on an ACF True / False field, like so:

    true/false field

    The query works just fine.

    I now want to exclude this post from my main WordPress loop. I’m thinking pre_get_posts is the way to do this, and have this:

    function exclude_featured_post( $query ) {
        if ( $query->is_home() && $query->is_main_query() ) {
    
          $custom_meta = array(
            'key' => 'featured_post',
            'value' => '1',
            'compare' => '!='
          );
        }
    }
    add_action( 'pre_get_posts', 'exclude_featured_post' );

    However, this does not exclude post from the main query.

  • you’d need to call on the $query object to modify it, it should look something like this:

    
    function exclude_featured_post( $query ) {
        if ( $query->is_home() && $query->is_main_query()) {
            // in case for some reason there's already a meta query set from other plugin
            $meta_query = $query->get('meta_query')? : [];
    
            // append yours
            $meta_query[] = [
                'key' => 'featured_post',
                'value' => '1',
                'compare' => '!='
            ];
    
            $query->set('meta_query', $meta_query);
        }
    }
    add_action( 'pre_get_posts', 'exclude_featured_post' );
    

    Cheers

  • Thanks @gummiforweb

    I can’t get the query to return any posts.

    This will get the posts with the ACF True/False set to 1:

            $meta_query[] = [
                'key' => 'featured_post',
                'value' => '1',
                'compare' => '='
            ];

    However this will not do the opposite, and exclude the posts, it shows nothing:

            $meta_query[] = [
                'key' => 'featured_post',
                'value' => '1',
                'compare' => '!='
            ]; 

    Trying things like 'value' => '' with 'compare' => '=' also returns nothing.

  • Using 'compare' => 'NOT EXISTS' instead of 'compare' => '!=' seems to return all posts and exclude the meta_query.

    function exclude_featured_post( $query ) {
        if ( $query->is_home() && $query->is_main_query()) {
            // in case for some reason there's already a meta query set from other plugin
            $meta_query = $query->get('meta_query')? : [];
    
            // append yours
            $meta_query[] = [
                'key' => 'featured_post',
                'value' => '1',
                'compare' => 'NOT EXISTS'
            ];
    
            $query->set('meta_query', $meta_query);
    
          	//echo '<pre>'; print_r( $query ); echo '</pre>';
    
        }
    }
    add_action( 'pre_get_posts', 'exclude_featured_post' );

    From here: https://core.trac.wordpress.org/ticket/18158

  • In that case, you might wanna have an either/or meta query. Because if you just use NOT EXISTS, it’s going to include those that you checked and uncheck (which the featured_post is 0, but still consider “exists”)

    
    $meta_query[] = [
        'relation' => 'OR',
        [
            'key' => 'featured_post',
            'compare' => 'NOT EXISTS'
        ],
        [
            'key' => 'featured_post',
            'value' => '1',
            'compare' => '!='
        ],
    ];
    

    Cheers

  • Thanks @gummiforweb

    You’re correct, when a post has been checked and un-checked as a “featured post” it is excluded from the loop, never to be seen again.

    Your code solves this problem – thanks.

    Thank you

  • I have the same problem:

    The meta query is:

    'meta_query' => [
                        'relation' => 'OR',
                        [
                            'key'     => 'font_hide_page',
                            'value'   => [1],
                            'compare' => 'NOT IN',
                        ],
                        [
                            'key'     => 'font_hide_page',
                            'compare' => 'NOT EXISTS',
                        ]
                    ],

    The problem is that the query is very slow ( takes ~7s per query ). If I remove the meta query, the same query executes around than 0.6ms. Can anybody help with optimised way of doing such queries?

Viewing 7 posts - 1 through 7 (of 7 total)

The topic ‘Exclude posts from main loop based on ACF field value’ is closed to new replies.