Normally, posts with a Published status are viewable by anyone and everyone. So what do you do if you want to create a blog post just for close friends, family members, or for editors on your WordPress site? Keeping content hidden from the general public is achievable without resorting to plugins, whether you’re looking to hide post contents, comments, custom fields, and whatever other elements you want to keep from prying eyes. In this tutorial, we’ll learn some techniques for hiding various post components.
Hiding the Content, Excerpt, and Comments
On the Post Edit page, there are three visibility options within the Publish meta-box. Clicking the “Edit” link next to “Visibility: Public” reveals the Password protected and Private options:
- Checking the Password protected radio button reveals a text field for entering a password that will be required to view that post. Note that the password is limited to 20 characters.
- Checking the Private radio button makes your post visible only to your site’s Users with the role of Administrator or Editor.
Click the “OK” button to update your post’s visibility setting.
Click the “Publish” button (or “Update” if the post is already published), then save the post to commit the changes.
Now WordPress will display the post with the following changes:
- The post Title is prefixed by the text “Protected: “.
- If the post has an Excerpt, the text “There is no excerpt because this is a protected post.” is displayed instead.
- The post Content is replaced by a password form with the text: “This post is password protected. To view it please enter your password below:”
Protecting Custom Fields
Notice that in the example above, restaurant details are displayed even before the user submits their password. That’s because, in this particular case, the information is stored as post meta data.
To stop custom fields from printing, you can wrap your get_post_meta() calls within a conditional statement that evaluates the results of post_password_required(). It checks both whether or not your post requires a password as well as whether or not the correct password has already been provided:
<?php if ( ! post_password_required() ) { $restaurant address = get_post_meta( $post->ID, 'address', true ); echo $restaurant address; } ?>
The post_password_required() function can also be employed to prevent password-protected posts from displaying in a list such as search results.
Protecting Excerpt Text
Hiding excerpts is similar to custom fields except that, for those, WordPress offers “the_excerpt” filter.
<?php function hide_excerpt( $excerpt ) { if ( post_password_required() ) { $excerpt = '<em>[This post is password-protected.]</em>'; } return $excerpt; } add_filter( 'the_excerpt', 'hide_excerpt' ); ?>
If you like, you can just as easily show the password form by calling get_the_password_form().
<?php function show_password_form_for_excerpt( $excerpt ) { if ( post_password_required() ) { $excerpt = get_the_password_form(); } return $excerpt; } add_filter( 'the_excerpt', 'show_password_form_for_excerpt' ); ?>
Customizing the Password Form
Another filter named “the_password_form” lets you customize the password form to your own specifications. Just be sure to return the form from the function rather than use echo and to include the maxlength="20"
attribute on the password field so as to match the WordPress password length limitation:
<?php function show_custom_password_form() { global $post; $label = 'pwbox-'.( empty( $post->ID ) ? rand() : $post->ID ); $form = '<form action="' . esc_url( site_url( 'wp-login.php?action=postpass', 'login_post' ) ) . '" method="post"> ' . __( "To view this protected post, enter the password below:" ) . ' <label for="' . $label . '">' . __( "Password:" ) . ' </label><input name="post_password" id="' . $label . '" type="password" size="20" maxlength="20" /><input type="submit" name="Submit" value="' . esc_attr__( "Submit" ) . '" /> </form>'; return $form; } add_filter( 'the_password_form', 'show_custom_password_form' ); ?>
Hiding Password Protected Posts Completely
You may not want password protected posts to be included in search results or archive pages, etc… This can be achieved using a combination of the pre_get_posts action and posts_where filter. First, we make sure that the page contains multiple posts, and that we are not on an admin page. We then remove password protected posts directly from any SQL query that WordPress is running, using the posts_where filter.
<?php // Filter to hide protected posts function exclude_protected($where) { global $wpdb; return $where .= " AND {$wpdb->posts}.post_password = '' "; } // Decide where to display them function exclude_protected_posts($query) { if( !is_single() && !is_page() && !is_admin() ) { add_filter( 'posts_where', 'exclude_protected' ); } } // Action to queue the filter at the right time add_action('pre_get_posts', 'exclude_protected_posts'); ?>
Conclusion
WordPress is more than capable of protecting post contents without any need for third party plugins, thanks to its many filter and action hooks. As long as you aren’t afraid of working with code, I think that you’ll find it to be a fairly painless process.