Building a Branded WordPress Login Page Template

When using WordPress to build a membership site, you can style and extend functionality to any page … but the login page.

Generally, it uses the default WordPress login page with limited ability to customize, unless you’re using a plugin like Theme My Login.

While plugins are great, you can be restricted by the constraints built into the plugin – so sometimes, custom code is a better option. Let’s walk through how to build a branded login page for your WordPress site.

Create the Login Page Within Your Theme

The first thing to do is create the login page when your theme gets activated.

In the below code, we’ll hook into the init action hook fired on theme initialization and add a callback function named dgtlnk_create_custom_login_page. Inside the callback function, we first check to see if a page with “member-login” as a slug already exists and, if not, then we create that page, set its title to “Login”, and add [dgtlnk-login-form] shortcode as the page content using wp_insert_post() function.

Add this code to your theme’s functions.php file:

add_action('init', 'dgtlnk_create_custom_login_page');
function dgtlnk_create_custom_login_page() {
	$query = new WP_Query( 'pagename=member-login' );
	if ( ! $query->have_posts() ) {
            wp_insert_post(
                array(
                    'post_content'   => '[dgtlnk-login-form]',
                    'post_name'      => 'member-login',
                    'post_title'     => 'Login',
                    'post_status'    => 'publish',
                    'post_type'      => 'page',
                    'ping_status'    => 'closed',
                    'comment_status' => 'closed',
                )
            );
	}
}

Now if you visit the WordPress backend, you’ll see a page called “Login”.

Render the Login Form Using the Shortcode

Next, we need to render the login form using the [dgtlnk-login-form] shortcode.

In order to do this, we’ll use the add_shortcode() function and add the following code to our theme’s functions.php file.

add_shortcode( 'dgtlnk-login-form', function ( $attributes, $content = null ) {
    $attributes = shortcode_atts( $default_attributes, $attributes );
    if ( is_user_logged_in() ) {
        return __( 'You are already signed in.', 'dgtlnk' );
    } 
    $attributes['redirect'] = '';
    if ( isset( $_REQUEST['redirect_to'] ) ) {
$attributes['redirect'] = wp_validate_redirect( $_REQUEST['redirect_to'], $attributes['redirect'] );
    }

    $errors = array();
    if ( isset( $_REQUEST['login'] ) ) {
        $error_codes = explode( ',', $_REQUEST['login'] );
        foreach ( $error_codes as $code ) {
            if ( $code == 'empty_username' || $code == 'empty_password' || $code == 'invalid_username' || $code == 'incorrect_password' ) {
                $errors [] = 'Invalid credentials. Try again.';
            } 
        }
    }
    $attributes['errors'] = $errors;

    $attributes['logged_out'] = isset( $_REQUEST['logged_out'] ) && $_REQUEST['logged_out'] == true;

    ob_start();
    if ( count( $attributes['errors'] ) > 0 ) : ?>
    <div class="login-errors">
        <?php foreach ( $attributes['errors'] as $error ) :
            echo '<p>' . $error . '</p>';
        endforeach; ?>
    </div>
    <?php endif;
    if ( $attributes['logged_out'] ) : ?>
    <p class="login-info">
        <?php echo 'You have successfully logged out.'; ?>
    </p>
    <?php endif;
    
    wp_login_form( array(
        'form_id' => 'login-form',
        'label_username' => 'Email Address',
        'redirect' => $attributes['redirect'],
    ));

    $html = ob_get_contents();
    ob_end_clean();

    return $html;
});

In this code, we first check to see if the user is already logged in. If they are, then instead of displaying the form, we display a message stating they are already logged in.

If they’re not logged in, we check to see if there are any error messages for empty/invalid username or password fields and, if so, display the errors above the form. We then use the wp_login_form() function to display the login form.

When the form is submitted, if there are any errors, we need to redirect them back to the login page and display the errors. To do this, we use the authenticate filter in the following code (added to our theme’s functions.php file).

add_filter( 'authenticate', function ( $user, $username, $password ) {
    if ( $_SERVER['REQUEST_METHOD'] === 'POST' ) {
        if ( is_wp_error( $user ) ) {
            $error_codes = join( ',', $user->get_error_codes() );
            $login_url = home_url( 'member-login' );
            $login_url = add_query_arg( 'login', $error_codes, $login_url );
            wp_redirect( $login_url );
            exit;
        }
    }
    return $user;
}, 101, 3);

This code checks to see if any errors are found during login authentication and, if so, redirects the user back to the login page. We already have logic inside the [dgtlnk-login-form] shortcode that loops through the errors and displays them on the login page.

Redirect Users to the Custom Login Page

Now, we need to redirect any user trying to login using the default WordPress login page to our custom page.

We can do this with the login_form_login action hook and using this code in our theme’s functions.php file.

add_action( 'login_form_login', function () {
    if ( $_SERVER['REQUEST_METHOD'] == 'GET' ) {
        $redirect_to = isset( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : null;    
        if ( is_user_logged_in() ) {
            $user = wp_get_current_user();
            if ( user_can( $user, 'manage_options' ) ) {
                wp_safe_redirect( $redirect_to );
            } else {
                wp_redirect( admin_url() );
            }
            exit;
        }
        $login_url = home_url( 'member-login' );
        if ( ! empty( $redirect_to ) ) {
            $login_url = add_query_arg( 'redirect_to', $redirect_to, $login_url );
        }
        wp_redirect( $login_url );
        exit;
    }
});

In this code, we’re checking to see if the user is already logged in and redirecting them either to the admin (because they’re logged in) or to the custom login page (because they’re not).

The last thing to do is redirect the user back to our custom login page when they log out of WordPress (since by default, logging out will redirect them to the default login page). We use the wp_logout action hook in the following code added to our theme’s functions.php file:

add_action( 'wp_logout', function () {
    $redirect_url = home_url( 'member-login?logged_out=true' );
    wp_safe_redirect( $redirect_url );
    exit;
}

This code redirects the user back to the custom login page, and since we already have code in our [dgtlnk-login-form] shortcode callback function to look for the logged_out attribute, we can display the appropriate message.

By using built-in WordPress functions and hooking into the correct action hooks, we can customize the login experience for users on our site while keeping the branding consistent across all pages. If you also need help customizing the login page on your website or for any other digital marketing needs, reach out to us and we’d be more than happy to assist.