Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I'm using [wp_login_form()][1] to display login form in a jQuery dialog window.

If user enters wrong password, the user is taken to the backend. I don't want that. Is there a way to notify user that he entered wrong password and still remain on the same page?

Before wp_login_form() came I was using a plugin. I'm kind of hoping I can avoid using a plugin for this.

My code:

wp_login_form(array(
  'label_remember' => __( 'Remember me' ),
  'label_log_in' => __( 'Login' )
));
share|improve this question
add comment

5 Answers 5

up vote 0 down vote accepted

wp_login_form() creates a form with an action attribute of site_url/wp-login.php and that means that when you click the submit button the the form is posted to site_url/wp-login.php which ignores redirect_to on errors (like wrong password) so in your case either go back to using a plugin or recreate the whole login process and that way you have control on errors, take a look at Check for correct username on custom login form which is very similar question.

share|improve this answer
    
ah yeah, good point. Thanks. –  Steven Apr 26 '11 at 19:45
add comment

I came here from google. But the answer didn't satisfy me. I was looking for a while and found a better solution.

Add this to your functions.php:

add_action( 'wp_login_failed', 'my_front_end_login_fail' );  // hook failed login

function my_front_end_login_fail( $username ) {
   $referrer = $_SERVER['HTTP_REFERER'];  // where did the post submission come from?
   // if there's a valid referrer, and it's not the default log-in screen
   if ( !empty($referrer) && !strstr($referrer,'wp-login') && !strstr($referrer,'wp-admin') ) {
      wp_redirect( $referrer . '?login=failed' );  // let's append some information (login=failed) to the URL for the theme to use
      exit;
   }
}
share|improve this answer
    
Thanks Alexey, I will test this (as I'm still using a plugin) –  Steven Jun 19 '12 at 23:29
5  
Alexey's solution works when wrong credentials are entered, but unfortunately fails when the user forgets to enter username or password. Apparently Wordpress doesn't even try to log the user in in this case, so wp_login_failed action is not performed. –  Szczepan Hołyszewski Sep 12 '12 at 7:39
    
I would use wp_get_referer() here to save some time: codex.wordpress.org/Function_Reference/wp_get_referer –  Jake Jul 3 '13 at 17:00
    
Also, you definitely use add_query_arg here, so the wp_redirect should be: "wp_redirect( add_query_arg('login', 'failed', $referrer) );" –  Jake Jul 3 '13 at 17:14
add comment

One addition to Alexey's answer. You can add a jquery function to check that one of the fields is not blank. That way the form will not submit unless there is something to check, preventing WordPress from redirecting to /wp-login.php.

                        <script>
                                $("#wp-submit").click(function() {
                                  var user = $("input#user_login").val();
                                    if (user == "") {
                                    $("input#user_login").focus();
                                    return false;
                                  }
                                 });
                          </script>   

Still not sure how to fix the forgot password aspect

share|improve this answer
3  
Please be aware that WordPress loads jQuery in "No Conflict" mode. The $ alias does not work. –  s_ha_dum Feb 26 '13 at 5:38
    
You also have to consider that user hits [enter] and not clicking t he login button. Also, you need to check for blank password as well. –  Steven Feb 26 '13 at 11:07
add comment

A solution for Szczepan Hołyszewski's point about empty fields in the accepted solution, the following jQuery will prevent going to the standard wp-login page: (add to login page template or footer.php)

jQuery("#loginform-custom").submit(function(){
     var isFormValid = true;
       jQuery("input").each(function()
       {
       if (jQuery.trim($(this).val()).length == 0){
       jQuery(this).addClass("submit_error");
       isFormValid = false;
       }     
     else {
     jQuery(this).removeClass("submit_error");
     }
     });
     return isFormValid;
});
share|improve this answer
add comment

The current method I am using to deal with all of the issues outlined here works great even with blank username/password and doesn't rely on javascript (though the js could be good along with this).

add_action( 'wp_login_failed', 'custom_login_failed' );
function custom_login_failed( $username )
{
    $referrer = wp_get_referer();

    if ( $referrer && ! strstr($referrer, 'wp-login') && ! strstr($referrer,'wp-admin') )
    {
        wp_redirect( add_query_arg('login', 'failed', $referrer) );
        exit;
    }
}

The key is this filter to change how a blank username/password is treated:

add_filter( 'authenticate', 'custom_authenticate_username_password', 30, 3);
function custom_authenticate_username_password( $user, $username, $password )
{
    if ( is_a($user, 'WP_User') ) { return $user; }

    if ( empty($username) || empty($password) )
    {
        $error = new WP_Error();
        $user  = new WP_Error('authentication_failed', __('<strong>ERROR</strong>: Invalid username or incorrect password.'));

        return $error;
    }
}

You can take this a step further and completely replace wp-login.php by redirecting users to your custom login page and use that page for the login_failed redirect also. Full code:

/**
 * Custom Login Page Actions
 */
// Change the login url sitewide to the custom login page
add_filter( 'login_url', 'custom_login_url', 10, 2 );
// Redirects wp-login to custom login with some custom error query vars when needed
add_action( 'login_head', 'custom_redirect_login', 10, 2 );
// Updates login failed to send user back to the custom form with a query var
add_action( 'wp_login_failed', 'custom_login_failed', 10, 2 );
// Updates authentication to return an error when one field or both are blank
add_filter( 'authenticate', 'custom_authenticate_username_password', 30, 3);
// Automatically adds the login form to "login" page
add_filter( 'the_content', 'custom_login_form_to_login_page' );

/**
 * Custom Login Page Functions
 */
function custom_login_url( $login_url='', $redirect='' )
{
    $page = get_page_by_path('login');
    if ( $page )
    {
        $login_url = get_permalink($page->ID);

        if (! empty($redirect) )
            $login_url = add_query_arg('redirect_to', urlencode($redirect), $login_url);
    }
    return $login_url;
}
function custom_redirect_login( $redirect_to='', $request='' )
{
    if ( 'wp-login.php' == $GLOBALS['pagenow'] )
    {
        $redirect_url = custom_login_url();

        if (! empty($_GET['action']) )
        {
            if ( 'lostpassword' == $_GET['action'] )
            {
                return;
            }
            elseif ( 'register' == $_GET['action'] )
            {
                $register_page = get_page_by_path('register');
                $redirect_url = get_permalink($register_page->ID);
            }
        }
        elseif (! empty($_GET['loggedout'])  )
        {
            $redirect_url = add_query_arg('action', 'loggedout', custom_login_url());
        }

        wp_redirect( $redirect_url );
        exit;
    }
}
function custom_login_failed( $username )
{
    $referrer = wp_get_referer();

    if ( $referrer && ! strstr($referrer, 'wp-login') && ! strstr($referrer, 'wp-admin') )
    {
        if ( empty($_GET['loggedout']) )
        wp_redirect( add_query_arg('action', 'failed', custom_login_url()) );
        else
        wp_redirect( add_query_arg('action', 'loggedout', custom_login_url()) );
        exit;
    }
}
function custom_authenticate_username_password( $user, $username, $password )
{
    if ( is_a($user, 'WP_User') ) { return $user; }

    if ( empty($username) || empty($password) )
    {
        $error = new WP_Error();
        $user  = new WP_Error('authentication_failed', __('<strong>ERROR</strong>: Invalid username or incorrect password.'));

        return $error;
    }
}
function custom_login_form_to_login_page( $content )
{
    if ( is_page('login') && in_the_loop() )
    {
        $output = $message = "";
        if (! empty($_GET['action']) )
        {
            if ( 'failed' == $_GET['action'] )
                $message = "There was a problem with your username or password.";
            elseif ( 'loggedout' == $_GET['action'] )
                $message = "You are now logged out.";
            elseif ( 'recovered' == $_GET['action'] )
                $message = "Check your e-mail for the confirmation link.";
        }

        if ( $message ) $output .= '<div class="message"><p>'. $message .'</p></div>';
        $output .= wp_login_form('echo=0&redirect='. site_url());
        $output .= '<a href="'. wp_lostpassword_url( add_query_arg('action', 'recovered', get_permalink()) ) .'" title="Recover Lost Password">Lost Password?</a>';

        $content .= $output;
    }
    return $content;
}

Customize and add these to add your logo to the wp-login page for password recovery:

// calling it only on the login page
add_action( 'login_enqueue_scripts', 'custom_login_css', 10 );
function custom_login_css() { wp_enqueue_style( 'custom_login_css', get_template_directory_uri() .'/library/css/login.css', false ); }
// changing the logo link from wordpress.org to your site
add_filter( 'login_headerurl', 'custom_login_logo_url' );
function custom_login_logo_url() { return home_url(); }
// changing the alt text on the logo to show your site name
add_filter( 'login_headertitle', 'custom_login_title' );
function custom_login_title() { return get_option('blogname'); }

Login logo css:

.login h1 a {
    background: url(../images/login-logo.png) no-repeat top center;
    width: 274px;
    height: 63px;
    text-indent: -9999px;
    overflow: hidden;
    padding-bottom: 15px;
    display: block;
}

EDIT: I just implemented this on another site form scratch, and found the above "step further" to be more complete, and fixed small syntax errors in the "add_actions". Added some comments and a method to automatically add the login form to login page without a separate template file. The login form method should work in most instances, since it is attached to "the_content", it could cause and issue if you have more than one loop on the login page, just use a page-login.php template in that case.

share|improve this answer
1  
Thanks, I will take a look at this (and see if I can make it work in conjunction with 3rd party login like Twitter and FB) –  Steven Jul 3 '13 at 21:15
1  
Jake - this is a nice complete solution. Thanks for sharing. +1 –  henrywright Sep 29 '13 at 21:39
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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