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 working on a customized login form for WordPress. I noticed that it's pretty difficult to achieve what I wanted.

Here's the HTML of the form:

<form method="post" action="<?php bloginfo('url') ?>/wp-login.php">
    <div class="loginbox_fields">
        <div class="loginbox_field"><input type="text" name="log" id="user_login"  value="" placeholder="<?php _e('Username'); ?>"/></div>
        <div class="loginbox_field"><input type="password" name="pwd" id="user_pass" value="" placeholder="<?php _e('Password'); ?>"/></div>
        <div class="loginbox_text">
            <input name="rememberme" type="checkbox" id="rememberme" value="forever"  <?php checked( $rememberme ); ?> />
            <label for="remember"><?php esc_attr_e('Remember Me'); ?></label>
        </div>
        <a href="/nojs.html" class="loginbox_button form_submit" title="<?php esc_attr_e('Log In'); ?>"><?php esc_attr_e('Log In'); ?></a>
        <table>
            <tr>
                <td class="first_column">Not registered?</td>
                <td></td>
                <td>Forgot password?</td>
            </tr>
            <tr>
                <td class="first_column"><a href="<?php echo get_permalink(); ?>?action=register" class="loginbox_stdbutton" title="Register">Register</a></td>
                <td></td>
                <td><a href="<?php echo get_permalink(); ?>?action=lostpassword" class="loginbox_stdbutton" title="Reset Password">Reset Password</a></td>
            </tr>
        </table>
    </div>
</form>

Due to style requirement, I put div wraps around input boxes and the submit button is an anchor tag. According to the document, wp_login_form and its hooks will not be able to implement this design.

So I followed the suggestions on this question (I asked) Custom user profile, registration, login page with theme , and got something close to http://digwp.com/2010/12/login-register-password-code/ . Basically, it allows you to put the login form anywhere you want, but still points back to wp-login.php when submitted.

But it has one major flaw. When login is incorrect, it points you back to wp-login.php. Like this demo, if you click "Login" without entering anything, it leads you back to the default wp-login.php form.

I'm currently putting the above form in one of the custom pages. I had a filter hooked to template_include and used this HTML code as the login form. I only wanted to change the style, I'm not planning on adding functions.

What does it take to implement this login form design? Shall I start from wp-login.php and change it? If so, how do I start (in terms of putting in the theme and form)?

share|improve this question
add comment

1 Answer 1

up vote 1 down vote accepted

To redirect back to your custom login form after login fails try this code:

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

function my_front_end_login_fail($username){
    // Get the reffering page, where did the post submission come from?
    $referrer = add_query_arg('login', false, $_SERVER['HTTP_REFERER']);

    // 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')){
        // let's append some information (login=failed) to the URL for the theme to use
        wp_redirect($referrer . '?login=failed'); 
    exit;
    }
}

You'll have to check also for an empty password or login - when login form from frontend (your custom login form) is submitted empty, you'll end up on standard wp-login.php again. To prevent this, append this code:

add_action( 'login_head', 'my_frontend_login_no_pass_no_username' );

function my_frontend_login_no_pass_no_username(){
    $referrer = add_query_arg('login', false, $_SERVER['HTTP_REFERER']);
    if ( (!isset($_REQUEST['user_login']) || ( isset( $_REQUEST['user_login'] ) && trim( $_REQUEST['user_login'] ) == '' ) ) || (!isset($_REQUEST['user_pass']) || ( isset( $_REQUEST['user_pass'] ) && trim( $_REQUEST['user_pass'] ) == '' ) ) ){
        wp_redirect( add_query_arg('login', 'failed', $referrer) ); 
        exit; 
    }   
}

If you're interested in a proper login after registration fails too, check my blogpost on this topic.

share|improve this answer
    
Thank you for the answer. You pointed the right direction. I'll read your post further. Although after digging a bit, it turns out that wp_login_failed will only be triggered when both username and password is filled. I found a post here: wordpress.org/support/topic/… which mentioned wp_authenticate. I ended up hooking both, and changed wp_authenticate to match my particular requirement. –  He Shiming Feb 10 '13 at 13:17
    
Again, thank you for the elegant solution on login_head. –  He Shiming Feb 10 '13 at 13:37
    
You're welcome. I've spent few hours on this problem just few days ago, and I'm glad I can share my knowledge and save other's time ;) –  david.binda Feb 10 '13 at 13:50
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.