Basic password protection without using users and roles

You could try hooking into template_include and showing the user a completely different page containing the login form (without changing the URL) if the post is password protected. Combine that WordPress’ built in post password functionality and you have something really close to what you want (blocking an entire page).

You could also use {{insert whatever method you prefer}} to check if a post needs a password protection thing. Custom fields, block a whole category, etc.

Here’s a simple example using the template_include filter.

<?php
add_filter('template_include', 'wpse77865_hijack_template');
/**
 * Hooked into `template_redirect`.  Checks to see if we're on a singular page
 * and if it's password protected show the user a completely different page.
 *
 * @param   string $tmp The template
 * @uses    locate_template
 * @return  string
 */
function wpse77865_hijack_template($tmp)
{
    if (
        is_singular() &&
        post_password_required(get_queried_object()) &&
        ($pw = locate_template('password.php'))
    ) {
        // if we're here, we are on a singular page
        // need a password and locate_template actually found
        // password.php in our child or parent theme.
        $tmp = $pw;
    }

    return $tmp;
}

The above will replace the single.php template on posts that require a password (eg. the user hasn’t entered one yet) with a template file named password.php in your theme and/or child theme. That template might look something like this (ripped from twenty twelve).

<?php
/**
 * Post password form template.
 *
 * @package WordPress
 */

get_header('password'); ?>

<div id="primary">
    <div id="content" role="main">

        <?php while (have_posts()): the_post(); ?>

            <article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
                <header class="entry-header">
                    <h1 class="entry-title"><?php _e('Password Required', 'wpse'); ?></h1>
                </header><!-- .entry-header -->

                <div class="entry-content">
                    <?php echo get_the_password_form(); ?>
                </div><!-- .entry-content -->

                </footer><!-- .entry-meta -->
            </article><!-- #post -->

        <?php endwhile; // end of the loop. ?>

    </div><!-- #content -->
</div><!-- #primary -->

<?php get_footer('password'); ?>

As you can see, no hint of the content, just the password form. After the user enters the post password, they’ll see the normal page. Not sure if this will mess with the cart or checkout procress, but I’m betting that it won’t.

Here’s the template_include bit as a plugin.