Overriding the Edit User Form in Drupal 6

This isn't really complex, just something I had to do recently. Sometimes you want to tweak a form in Drupal, like rearrange the form elements for example or add a little text that wasn't there before.

In this case I'm using the Password Policy module to enforce strong passwords. When a user makes a bad password, Password Policy will reject it and dynamically display a message that indicates why the password is unacceptable. It's a pretty cool feature but I'd like users to know what the requirements are before typing in a password. So I want to take the description of the policy and show it to the user in the description by the edit boxes where they can change their password.

Here's the code that's in my template.php:

function ashbridge_user_profile_form($form) {
  if (function_exists('_password_policy_load_active_policy')) {
    $policy = _password_policy_load_active_policy();
    if ($policy && isset($policy['description'])) {
      $form['account']['pass']['#description'] = '<p>'. $form['account']['pass']['#description'] .'</p><p>'. $policy['description'] . '</p>';
    }
  }
  return drupal_render($form);
}

Before I go on I should give one caveat: I think I'm cheating by using the _password_policy_load_active_policy() function. It's probably meant for internal use by the module and if it changes that could do cause trouble with this code when I update the module.

The ashbridge_user_profile_form() function themes the user-profile-form. The name comes from my theme's name - "ashbridge" - and the form's name - user-profile. It receives the $form object which contains all the pieces that drupal_render() will turn into an html form. It uses the PHP built-in function_exists function to check for the _password_policy_load_active_policy() function before calling it. This way the code just won't run if the Password Policy module isn't loaded or if a future version of the Password Policy module changes the name of that function. Normally I'd use module_exists() to detect the module.

Next I set the password field's description to the default description followed by the description of the password policy. Before doing this I make sure that the policy object is valid and that it has the description array member. If the password policy module is installed but no policies have been created then I don't know what _password_policy_load_active_policy() returns and there could be other error conditions that I just want to worry less about.

Finally I have drupal render the modified form object into an actual html form and return that from my theme function.

Of course to make this theme override work I need to tell Drupal about it. The way to do this is in my template.php file there's a function called ashbridge_theme(). This function will be named after your theme followed by _theme. Mine's "ashbridge" - replace that part with your theme's name.

Here's a summarized version of the function that just does the user-profile form.

function ashbridge_theme() {
  return array(
    'user_profile_form' => array(
      // Forms always take the form argument.
      'arguments' => array('form' => NULL),
    ),    
    );
}

After adding all the code, you need to get Drupal to run ashbridge_theme() again. The way I do this is to go to my site's Administer » Site Building » Themes page (at example.com/admin/build/themes) and click "Save Configuration".

So how did I know what array members to use in $form and $policy? Easy, I ran my code in debug and set a breakpoint at a line that had those variables available. I've written about how to set up your own debugger before.

5
Your rating: None Average: 5 (1 vote)
5

Is it possible to re-arrange and actually theme the user edit form by using this method?

Web Presence and Design
www.hankpalan.com

Yup. For example, to move the entire account fieldset down you could do something like

$form['account']['#weight'] = 20;

Or you could add css classes to elements in the theme then use css to change the look of elements.