Exclude post from wp_query based on custom field boolean

I am trying to give users an option to select Exclude from homepage bloglist on a post, and then pick this up on my homepage query so certain posts won't surface on the homepage.

I'm using the Wordpress custom field true/false.

On a post where the box has been ticked, I would assume this post would then not surface on the homepage based on the below query args:

$query_args = array(
    'meta_query' = array(
        'key' = 'exclude_from_homepage_bloglist',
        'value' = false
    )
);

However it seems that even when the true/false box is ticked, the query still outputs the post in question.

Where am I going wrong the the meta query?

Topic wp-query query Wordpress

Category Web


Your code is close, but confusingly meta_query is an array of stuff including the array of values to check, so you need an extra level of arrays:

$query_args = array(
    'meta_query' => array(
        array(
            'key' => 'exclude_from_homepage_bloglist',
            'value' => false
        )
    )
);

You may also need to double check that the value from a checkbox is definitely stored as the PHP value false if unchecked as this may also cause this code not to work.

More reference on the WP_Query args here: https://developer.wordpress.org/reference/classes/wp_query/#custom-field-post-meta-parameters


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

About

Geeks Mental is a community that publishes articles and tutorials about Web, Android, Data Science, new techniques and Linux security.