Paulund
2013-02-25 #wordpress

Create Your Own WordPress Login Page

In Wordpress you can create your own users and user roles, you can even do this programmatically which means that you can create a register form so that visitors to your site can register to your site and login to a member's only area.

If you allow visitors to register as users of your site, they will have access to login to your admin area. This isn't too much of a problem if you set their roles to be able to do nothing in your admin area but this isn't very usable to your visitors. It will be better if you can create a new login form, use the inbuilt Wordpress user manager and redirect successful logins to a different area other than the Wordpress admin area. In this tutorial we are going to look at how you will create a new login form for users to be redirected to a different area.

Restrict Access To Admin Area To Only Admin Users

To start with we are going to restrict access to the Wordpress Admin Area to only users who we want to be there, in this situation I'm only going to allow admin users to access the admin area. In your Wordpress theme functions.php file add the following code to block access to the admin area.

function restrict_admin()
{
	if ( ! current_user_can( 'manage_options' ) && '/wp-admin/admin-ajax.php' != $_SERVER['PHP_SELF'] ) {
                wp_redirect( site_url() );
	}
}
add_action( 'admin_init', 'restrict_admin', 1 );

This code will check if the user is an administrator and if they are not Wordpress will redirect them back to the website home page. Now we have restricted access to the admin area to only admin users we can now create a new login form for all the other users in the Wordpress user manager.

Create A New Login Page

First we need to create a new login page template for our theme, this will allow us to create a new Login page in Wordpress and assign it to use this template. Create a new PHP file in your theme and add the following code.


<?php
/*
* Template Name: Login Page
*/
?>

Now if you go into Wordpress to create a new page you will be able to assign the page to use this page template. We want this page to look the same as the other pages in the theme so we need to add the header, footer and the sidebar.


<?php
/*
* Template Name: Login Page
*/
?>

With the page structure in place it will look just like any other page in your theme, we can now add the login form to this page. Luckily there is a Wordpress function to create a login form on the page. This function is wp_login_form(), it will take one parameter which is an array of arguments you use to customise how the form behaviours. These are the arguments you can send to the form function and the default values.


<?php $args = array(
        'echo' => true,
        'redirect' => site_url( $_SERVER['REQUEST_URI'] ), 
        'form_id' => 'loginform',
        'label_username' => __( 'Username' ),
        'label_password' => __( 'Password' ),
        'label_remember' => __( 'Remember Me' ),
        'label_log_in' => __( 'Log In' ),
        'id_username' => 'user_login',
        'id_password' => 'user_pass',
        'id_remember' => 'rememberme',
        'id_submit' => 'wp-submit',
        'remember' => true,
        'value_username' => NULL,
        'value_remember' => false ); ?> 

You can change any of these settings for your own login form, in this example we are just going to change the redirect URL so that on a successfully login we will be taken to the members only area.


<?php
$args = array('redirect' => get_permalink( get_page( $page_id_of_member_area ) ) );

wp_login_form( $args );
?>

On a successful login the Wordpress will then get the URL of the member only page by using the get_permalink() and get_page() functions. That's all you need to do to create a new page for a custom login form which will take you to a members only area instead of the admin area, here is the full code for the page.


<?php
/*
* Template Name: Login Page
*/
?>


<?php
$args = array('redirect' => get_permalink( get_page( $page_id_of_member_area ) ) );

wp_login_form( $args );
?>

Problems With Creating Your Own Login Page

Creating your own Wordpress login page isn't as easy as just using the wp_login_form() function, this will create you a login page and will allow you to successfully login into Wordpress. The problems come when you have a failed login attempt. You need to be able to handle what happens when the user fails the login attempt, what happens if they type in the wrong username, password or what happens if they don't type anything in the login form at all. In each of these scenarios the user should be redirected back to this current login form and you should display an error message that the login has failed. Currently if you just use the wp_login_form() function and you have a failed login you are always redirected to the Wordpress admin area login form wp-login.php. This isn't very usable to the users that need to login to your membership area. Therefore we need to add a couple of additional functions in the function.php file to make sure that this login form behaviours correctly.

Failed Login Attempt

First we are going to handle what will happen if the login attempt fails, this will be when the username and password are incorrect and it won't let you login to Wordpress. There is a Wordpress action wp_login_failed which you will be able to assign a function to run once the login attempt fails. This will only be if the user types in the wrong username and password. If the user doesn't type in a username or password then the login will not get to this stage. Once a login attempt has failed we need to get the URL of the page we came from and make sure that it's not from the default wp-login.php page, we can then add a querystring parameter of failed and redirect to the login form with a querystring of a failed login attempt. Add the following code to your functions.php file to redirect back to the custom login page on a failed login attempt.

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

function pu_login_failed( $user ) {
  	// check what page the login attempt is coming from
  	$referrer = $_SERVER['HTTP_REFERER'];

  	// check that were not on the default login page
	if ( !empty($referrer) && !strstr($referrer,'wp-login') && !strstr($referrer,'wp-admin') && $user!=null ) {
		// make sure we don't already have a failed login attempt
		if ( !strstr($referrer, '?login=failed' )) {
			// Redirect to the login page and append a querystring of login failed
	    	wp_redirect( $referrer . '?login=failed');
	    } else {
	      	wp_redirect( $referrer );
	    }

	    exit;
	}
}

Empty Username And Password

Currently on the custom login page if you didn't type in a username or password then you will be redirected back to the default Wordpress login page, this isn't very good as it will confuse your users, so you need to be able to hook another function to a different action, for this one we are going to use the authenticate action. From here we can check the username and password which has been set and make sure that they are not empty, if they are empty then we want to redirect to the failed querystring. Add the following to your functions.php file to check that the username and password are not empty.

add_action( 'authenticate', 'pu_blank_login');

function pu_blank_login( $user ){
  	// check what page the login attempt is coming from
  	$referrer = $_SERVER['HTTP_REFERER'];

  	$error = false;

  	if($_POST['log'] == '' || $_POST['pwd'] == '')
  	{
  		$error = true;
  	}

  	// check that were not on the default login page
  	if ( !empty($referrer) && !strstr($referrer,'wp-login') && !strstr($referrer,'wp-admin') && $error ) {

  		// make sure we don't already have a failed login attempt
    	if ( !strstr($referrer, '?login=failed') ) {
    		// Redirect to the login page and append a querystring of login failed
        	wp_redirect( $referrer . '?login=failed' );
      	} else {
        	wp_redirect( $referrer );
      	}

    exit;

  	}
}

Now if the user doesn't enter anything in the username or password field then we will get a login failed querystring attempt.

Display A Failed Login Message

When we redirect the user back to the login page it will have a querystring of ?login=failed, this means that we can check for this querystring and display a message to the user. Go back to your login page template and add the following code to the template.


<?php
/**
 * Template Name: Login Page
 */

$args = array( 'redirect' => site_url() );

if(isset($_GET['login']) && $_GET['login'] == 'failed')
{
	?>
		<div id="login-error" style="background-color: #FFEBE8;border:1px solid #C00;padding:5px;">
			<p>Login failed: You have entered an incorrect Username or password, please try again.</p>
		</div>
	<?php
}

wp_login_form( $args );
?>

The above will fix a number a different problems you will face when creating your own custom login pages, you can now create your own membership area and allow users in the Wordpress user manager to login.