A custom login/register page for Drupal 6 - developed.be

This tutorial explains how to created a single page with a login form an a register form in Drupal6.

developed_loginregister

To accomplish this, we have to go through some concepts first:

User Module

The user module in Drupal handles all the login/register functions. The paths (=url’s) in this module are:

  • /user:
    • returns the login page if a user is not logged in
    • returns the user account page if the user is logged in
    • handles the POST request to login.
  • /user/register
    • returns the register page if the user is not logged in
    • handles the POST request to register
  • /user/login:
    • an alias for /user, but only works when the user is not logged in, otherwise the user gets the unclear error “you have no rights to access this page”.
  • /user/password:
    • returns the “forgot password” page
    • handles the POST request to ask for a new password.

Display the login form

/user/login returns the page where the login form is plotted on.

Let’s take a look at the original code in the user module to see how the /user page is handled

/**
 * Access callback for path /user.
 *
 * Displays user profile if user is logged in, or login form for anonymous
 * users.
 */
function user_page() {
  global $user;
  if ($user->uid) {
    menu_set_active_item('user/'. $user->uid);
    return menu_execute_active_handler();
  }
  else {
    return drupal_get_form('user_login');
  }
}

This code says: if the user has a user id, go to the profile page, otherwise display the login form.

We can literally read the code to display the login form, namely:

<?php print drupal_get_form('user_login'); ?>

In the same way we can print the register form:

<?php print drupal_get_form('user_register'); ?>

If you’d put the above code in any template, it will return the login or register form as we know it.

My Module

Now we have to overwrite the user_page() function to display our own page. You can do this by creating a custom module.

Custom authentication template

Create a template file MYMODULE_authenticate.tpl.php inside the custom module directory, which contains some old fashion html to display the login form next to the register form:

<table id="login-table">
  <tr>
    <td>
      <h2><?php print(t('Log in')); ?></h2>
      <div>
        <?php print drupal_get_form('user_login'); ?>
      </div>
      <div>
        <a href="/user/password" ><?php print(t('Forgot password'));?>?</a>
      </div>
    </td>
    <td>
      <div>
        <h2><?php print(t('Not yet registred?')); ?></h2>
        <div>
          <?php print drupal_get_form('user_register'); ?>
        </div>
      </div>
    </td>
  </tr>
</table>

Override the /user path

Now we have to replace the normal login template with our custom template. We do this by overriding the /user path in the menu hook.

function mymodule_menu(){
  $items['user'] = array(
    'title' => t("Authenticate"),
    'page callback' => 'mymodule_authenticate',
    'access arguments' => array('access content'),
    'type' => MENU_NORMAL_ITEM,
  );
  return $items;
}

Replace both instances of “mymodule” by your module name. You also have to do this  for the next code snippets.

Then create a theme hook to register our newly created template in Drupal:

function mymodule_theme(){
  return array(
    'mymodule_authenticate' => array(
      'template' => 'mymodule_authenticate',
      'arguments' => array(),
    )
  );
}

Next, create a new function inside your module with the following code. This code will be called when accessing /user:

function mymodule_authenticate(){
  global $user;
  if ($user->uid) {
    menu_set_active_item('user/'. $user->uid);
    return menu_execute_active_handler();
  }else{
    return theme("mymodule_authenticate"); //shows the new authentication form
  }
}

You can see it’s a copy of the user_page() function, only the theme-function argument has changed to our theme.

It’s important not to call the theme function from within the menu hook, because then the POST action wouldn’t work.

If you active mymodule and clear all caches, log out of your site and visit /user or /user/login you should see both forms and they should also work both.

Change the html of the login form

So far we made a page with the default login form and the default register form next to eachother. But what if we want to change to look and feel of the login form itself?

To separate concerns, it’s best to make these form altering theme dependent, so we’ll put the code in the template.php page of the theme, and not in the .module file.

The code snippet “overrides” the default login form:

function mytheme_theme(){
  return array(
    'user_login' => array(
      'template' => 'user-login',
      'arguments' => array('form' => NULL),
    )
  );
}

Next we create the function that return the custom login form:

function mytheme_preprocess_user_login(&$variables) {
  $variables['rendered'] = drupal_render($variables['form']);
}

So far, the mytheme_preprocess_user_login returns the default form, because we haven’t changed anything yet.

You could throw a dump_var($variables) to understand what’s inside $variables.

Keep in mind: with every change you do in the preprocess function, you might clear you cache to see the changes.

This snippet will remove the description in the form:

function mytheme_preprocess_user_login(&$variables) {
  $variables['form']['name']['#description'] =  '';
  $variables['form']['pass']['#description'] =  '';
  $variables['rendered'] = drupal_render($variables['form']);
}

As in the above example, you can change every aspect of the form elements with $variables[‘form’]. Here’s another example to put a class on the name tag:

$variables['form']['name']['#attributes']['class'] = 'some-class';

These example should get you on the rails for the entire login form.

As a final step, we also have to create a user-login.tpl.php file inside the theme-directory. This template only needs to contain this code:

<?php print $rendered; ?>

The template prints the $variables[‘rendered’] value from the preprocess function.

Change the html of the register form

The register form is no different.

1) Alter the theme hook in templates.php

function mytheme_theme(){
  return array(
    'user_login' => array(
      'template' => 'user-login',
      'arguments' => array('form' => NULL),
    ),
    'user_register' => array(
      'template' => 'user-register',
      'arguments' => array('form' => NULL),
    )
  );
}

2) create the function mytheme_preprocess_user_register(&$variables)

function dewemo_shop_preprocess_user_register(&$variables) {
  $variables['form']['name']['#description'] =  '';
  $variables['rendered'] = drupal_render($variables['form']);
}

3) create the template user-register.tpl.php inside the theme directory with at least this content:

<?php&nbsp;print&nbsp;$rendered;&nbsp;?>

4) clear caches.

Remove the user tabs

At last you might perfer to remove the tabs that appear on the user pages. In the template.php file from your theme, you can add this code:

function phptemplate_menu_local_task($mid, $active, $primary) {
  //Check which tab is being rendered
  $item = menu_get_item($mid);
  //Remove core user tabs
  if ($item['path'] == 'user') {
    return '';
  }
}

Drupal 7

Keep in mind: this only works for Drupal6!

This manual on drupal.org also informs about Drupal7.


Rss Comments

One comment

  1. Hello,
    I create the function in template.php

    But its wouldn’t be work.

    function my2_preprocess_user_register(&$variables) {

    $variables[‘form’][’email’][‘#description’] = ”;

    $variables[‘rendered’] = drupal_render($variables[‘form’]);

    }

    #1 Pushkar

Leave a comment