Exclude post from wp_query based on custom field boolean

Excluding things in queries is extremely expensive, but also avoidable. What’s more, filtering posts by their post meta values is also super expensive. That query would get exponentially slower as the post count rises.

Instead you can avoid this completely by telling it what you do want, not what you don’t want. So instead of excluding things from the homepage, include them instead.

And to avoid the post meta query and make it super fast, use a private taxonomy. Set 'public' => false when registering it.

Finally, lets say our private taxonomy is called filters, we can hook into save_post and set show_on_homepage with a hook like this:


add_action( 'init', function() {
    register_taxonomy( 'filters', 'post', [
        'public' => false
    ] );
} );

add_filter( 'save_post', function( int $post_id ) : int {
    $hide = get_post_meta( $post_id, 'exclude_from_homepage_bloglist', true );

    if ( $hide ) {
        wp_remove_object_terms( $post_id, [ 'homepage-show' ], 'filters' );
    } else {
        wp_add_object_terms( $post_id, [ 'homepage-show' ], 'filters' );
    }
    
    return $post_id;
}

Now you have a super fast way to filter things on the homepage, e.g.

add_action( 'pre_get_posts', function ( $query ) {
    if ( ! $query->is_home() ) {
        return; // we only want the homepage
    }
    $query->set( 'filters', 'homepage-show' );
}

And you have a super useful way to highlight things! What if you also added a featured area? Then you could add a featured term and query for it like this:

$query = new WP_Query( [
    'filters' => 'featured'
] );
// followed by a standard post loop...

Ofcourse you still have your post meta, which you can eliminate if you want and use has_term to test, but you’re probably using a plugin like ACF to give you a UI. ACF and others can be told to use the taxonomy to save but you can play around with that and keep the post meta just to make things easy if you want. You’ll also want to add that homepage show term to all your existing posts so they show on the homepage too