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.

    • gummi

    • October 28, 2017 at 2:40 pm

    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

    • gummi

    • October 31, 2017 at 4:18 am

    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.

We use cookies to offer you a better browsing experience, analyze site traffic and personalize content. Read about how we use cookies and how you can control them in our Cookie Policy. If you continue to use this site, you consent to our use of cookies.