0

I'm interested in creating a filter for pages with password protection and that have a certain category. I've placed this code in my theme's child folder in functions.php since I didn't want to edit the wp-includes files.

/**
 * Retrieve v1-i1 protected post password form content.
 *
 * @since 1.0.0
 *
 * @param int|WP_Post $post Optional. Post ID or WP_Post object. Default is global $post.
 * @return string HTML content for password form for password protected post.
 */
function get_the_v1i1_password_form( $post = 0 ) {
    $post = get_post( $post );
    $label = 'pwbox-' . ( empty($post->ID) ? rand() : $post->ID );
    $output = '<form action="' . esc_url( site_url( 'wp-login.php?action=postpass', 'login_post' ) ) . '" class="post-password-form" method="post">
    <p>' . __( 'This is exclusive content from v1:i1. Please enter password below:' ) . '</p>
    <p><label for="' . $label . '">' . __( 'Password:' ) . ' <input name="post_password" id="' . $label . '" type="password" size="20" /></label> <input type="submit" name="Submit" value="' . esc_attr_x( 'Enter', 'post password form' ) . '" /></p></form>
    ';

    /**
     * Filters the HTML output for the protected post password form.
     *
     * If modifying the password field, please note that the core database schema
     * limits the password field to 20 characters regardless of the value of the
     * size attribute in the form input.
     *
     * @since 2.7.0
     *
     * @param string $output The password form HTML output.
     */
    return apply_filters( 'the_password_form', $output );
}


// If post password required and it doesn't match the cookie.
    if (post_password_required( $post ) && in_category( 'v1-i1' )) {
    return get_the_v1i1_password_form( $post );
} else {
    return get_the_password_form( $post );
}
    `

I can't seem to get this to work. Am I missing something?

  • What is not working? get_the_special_password_form() is not being called? Or is it not returning any output? Are those code in a Page template (e.g. page.php)? – Sally CJ Jan 19 at 6:19
  • I get a blank/error page stating that the page cannot be loaded. get_the_special_password_form() is being called, however, I think I might need to add an else statement so that it reverts to the standard password form if no category is found. – Forrest Walker Whitmore Jan 20 at 19:05
  • You shouldn't call post_password_required() or run that if block directly from the functions.php file like that. Try moving it to (an appropriate place in) a single Post template, e.g. the single.php file. Or you could hook to the_content and run the if from there. – Sally CJ Jan 21 at 1:36
  • I added it all to the single.php file and placed it in the child folder of the theme. I'm still not having any luck. I'm not sure I fully understand "an appropriate place" The page can be viewed here: link The text should read: This is exclusive content from v1:i1. Please enter password below: The page has been given the category "v1-i1" – Forrest Walker Whitmore Jan 22 at 3:42
  • Sorry, I didn't really get what you wanted to do.. so remove that - "I added it all to the single.php file" and check my answer. – Sally CJ Jan 22 at 13:24
0

If you look at the source code of the get_the_content() function which retrieves the post content, you'd see the following conditional:

if ( post_password_required( $post ) )
    return get_the_password_form( $post );

And in the get_the_password_form() function, there's a filter you can use to customize the HTML of the default password form:

return apply_filters( 'the_password_form', $output );

So based on your code, this is how it should be, and be placed in the theme's functions.php file:

function get_the_v1i1_password_form( $output ) {
    // If not in the v1-i1 category, return the $output as-is.
    if ( ! in_category( 'v1-i1' ) ) {
        return $output;
    }

    // Here you can customize the form HTML.
    $post = get_post();
    $label = 'pwbox-' . ( empty($post->ID) ? rand() : $post->ID );
    $output = '<form action="' . esc_url( site_url( 'wp-login.php?action=postpass', 'login_post' ) ) . '" class="post-password-form" method="post">
    <p>' . __( 'This is exclusive content from v1:i1. Please enter password below:' ) . '</p>
    <p><label for="' . $label . '">' . __( 'Password:' ) . ' <input name="post_password" id="' . $label . '" type="password" size="20" /></label> <input type="submit" name="Submit" value="' . esc_attr_x( 'Enter', 'post password form' ) . '" /></p></form>
    ';

    return $output;
}
add_filter( 'the_password_form', 'get_the_v1i1_password_form' );

Note: The get_the_v1i1_password_form() is now a filter callback, so you shouldn't use the return apply_filters( 'the_password_form', $output ); which would cause the page to stop working.

And you also don't need this:

if (post_password_required( $post ) && in_category( 'v1-i1' )) {
    return get_the_v1i1_password_form( $post );
} else {
    return get_the_password_form( $post );
}

Additional Note

The above code gives you full control over the form HTML, but if all you want to do is replace the text "This content is password protected. To view it please enter your password below:", then you can simply use str_replace() like so:

function get_the_v1i1_password_form( $output ) {
    // If is in the v1-i1 category, replace the text.
    if ( in_category( 'v1-i1' ) ) {
        return str_replace(
            'This content is password protected. To view it please enter your password below:',
            'This is exclusive content from v1:i1. Please enter password below:',
            $output
        );
    }

    return $output;
}
add_filter( 'the_password_form', 'get_the_v1i1_password_form' );

But of course, that would only work with the default output of the get_the_password_form() function.

  • 1
    Thanks for the revised answer Sally - that did the trick. I will be customizing the HTML, but it is good to know that there is a simply way of replacing the text string. I appreciate your help. – Forrest Walker Whitmore Jan 24 at 16:35
0

You are not returning anything from the function get_the_special_password_form Please return output from the above function and also contact the $label to $output before return the value if you also want the label.

  • I am calling the function get_the_special_password_form in functions.php – Forrest Walker Whitmore Jan 20 at 19:09
  • Please call the function of 'get_the_special_password_form' from the single.php because I am seeing you are getting the form when a post requires password. – Mohsin Ghouri Jan 21 at 6:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.