So, I should begin with - this definitely isn't the best way, it may not always work - it is more of a hack than anything. However, I could not find anything else that works via Google-fu searching ... and I'm guessing you're in the same boat?

Quick overview, on WordPress if you use the Password Protect Page feature, it adds a form to the page that passes the data to this page: wp-login.php?action=postpass.

Upon correct password input, a cookie is generated and the user is redirected back to the page. The content is outputted if the cookie is set.

What happens if the user enters the wrong password? Correct me if I'm wrong, but it appears it just redirects the user back to the page without the cookie.

There we have the answer ... we have to check for the HTTP Referral and whether the cookie is set or not. Throw the following function and filter into your WordPress themes functions.php file.


function my_password_form() {
     global $post;

     $label = 'pwbox-'.( empty( $post->ID ) ? rand() : $post->ID );

     $passwordProtectedPageURL = 'https://domain.com/password-protected-page/';
     $wrongPassword = ' ';

     if( ( sanitize_text_field( $_SERVER["HTTP_REFERER"] ) === $passwordProtectedPageURL ) && ! isset ( $_COOKIE[ 'wp-postpass_' . COOKIEHASH ] )){
          $wrongPassword = '<span style="color:#ed1b24;font-weight:bold;">The password you have entered is invalid.</span>';
     }


     $form = '<form action="' . esc_url( site_url( 'wp-login.php?action=postpass', 'login_post' ) ) . '" method="post">
' . __( "To view this page, please 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><p>' . $wrongPassword . '</p>';

     return $form;
}
add_filter( 'the_password_form', 'my_password_form' );

Lets review what is happening...

We're creating the my_password_form() function. In it, we call the global $post variable. We also define the the $label, $passwordProtectedPageURL and $wrongPassword variables.

Next, we check if the HTTP Referral URL is equal to your password protected page URL and if the cookie is NOT set. If so, we alter the $wrongPassword variable with the message we want to display when a user enters the wrong password. Otherwise, we leave the $wrongPassword message blank.

The next part is the $form variable building the HTML and outputting it. Finally, we leverage WordPress filters and use the add_filter function to hook into the the_password_form hook.