For years my companies website has used WordPress’s password protection function to hide posts that we wanted people to review before going live. I needed a solution that affected the main loop, otherwise I could just use WP_Query arguments. So to hide those posts from the main query we’ve used this code snippet.
/** * * Remove Password Protected Posts from the main query * */ function collin_password_post_filter( $where = '' ) { if (!is_single() && !is_admin()) { $where .= " AND post_password = ''"; } return $where; } add_filter( 'posts_where', __NAMESPACE__.'\sji_password_post_filter' );
The snippet above first checks to make sure you are not logged in, and not on a single (a post or custom post type) page. However it does not check if you are on a page.
This causes password protected pages, to 404. To fix this, simply adjust the conditional statement to also check for pages:
/** * * Remove Password Protected Posts from the main query * */ function sji_password_post_filter( $where = '' ) { if ( !is_page() && !is_single() && !is_admin()) { $where .= " AND post_password = ''"; } return $where; } add_filter( 'posts_where', __NAMESPACE__.'\sji_password_post_filter' );