Fiddling with user roles would probably be the most robust solution, however a quick and dirty approach would be to set post meta-data to mark posts that should be hidden, then add a meta-query to post queries by using a pre_get_posts
hook in order to restrict results to non-hidden posts for non-logged-in users.
The following will limit all posts queried for logged-out visitors to those which either do not have associated hide_from_guests
meta-data, or have that metadata set to 'false'
:
function wpse225120_hide_posts_from_guests( $query ) {
// If the user's logged in, exit the function now.
if( is_user_logged_in() )
return;
// Get the current metadata query so we can alter it instead of overwriting it
$meta_query = $query->get( 'meta_query' );
// Create a meta-query filtering out hidden posts
$hidden_meta_query = array(
'relation' => 'OR',
array(
'key' => 'hide_from_guests',
'value' => 'false'
),
array(
'key' => 'hide_from_guests',
'compare' => 'NOT_EXISTS'
)
);
// If there's not already a meta-query, supply the one for hidden posts and exit
if( ! is_array( $meta_query ) || empty( $meta_query ) ) {
$query->set( 'meta_query', $hidden_meta_query );
return;
}
// If there is an existing meta-query, modify it to support our new hidden posts
// meta-query as a top-level 'AND' condition, if need be
if( isset( $meta_query[ 'relation' ] ) && 'OR' === $meta_query[ 'relation' ] )
$meta_query = array(
'relation' => 'AND',
$meta_query
);
}
// Add the hidden posts meta-query and overwrite $query's old meta-query
$meta_query[] = $hidden_meta_query;
$query->set( 'meta_query', $meta_query );
}
add_action( 'pre_get_posts', 'wpse225120_hide_posts_from_guests' );
Note that globally altering every query like this is generally considered to be a bad practice. If at all possible, use
is_main_query()
and other conditional tags to limit query modifications to just the relevant queries in order to prevent unexpected behaviors and performance impact.
The 'hide_from_guests'
post meta-data can be set on individual posts by using the custom fields interface, post metadata functions, or implementing a custom metabox and attaching it to relevant post types, among other ways.