Chapter Three LLC

HOWTO: Fully Theme and Customize the Drupal User Registration Form

Matt Cheney

Just a little to the left please. Flip it around. Put that on top of this. Call it by a different name. It is the little changes, that seem trivial and small, that often end up being real headaches to make and support our clients in making. Do we really want to try to build capacity with clients by teaching them to adjust #weight in hook_form_alter?

The Drupal Theming System is pretty powerful and, when done right, can offer a good avenue for our clients and their staff to edit, modify, and change their own website content. Its a lot easier to modify HTML files than Drupal module files.

A good example of where this kind of process is needed is on the user registration page. There are a lot of little bits of language and ordering to change and add, but to do so in Drupal module code can get a little hairy. Observe our technique to abstract the user/register form into a flat template file (while maintaing most of the other good Drupal goodness).

Step One: Create a theme override in your module code for the user/register form that executes a _phptemplate_callback to use a separate template file.

<?php
function theme_user_register($form) {
 
$vars = array();
 
$output _phptemplate_callback('user_registration_form', $vars);
 
$output .= drupal_render($form);
  return
$output;
}
?>

Step Two: Expand the theme override function made in step one to remove the titles and descriptions Drupal provides for the form elements. We do this in the theme function (instead of in a hook_form_alter) to preserve the original field titles so they can be used as part of any error messages coming out of form validation.

<?php
 
foreach($form as $key => $value) { // loop through top level
   
if (is_array($form[$key])) {
     
$form[$key]['#title'] = '';
     
$form[$key]['#description'] = '';
      foreach(
$form[$key] as $key2 => $value2) { // loop through second level
       
if (is_array($form[$key][$key2])) {
         
$form[$key][$key2]['#title'] = '';
         
$form[$key][$key2]['#description'] = '';
        }
      }
    }
  }
?>

Step Three: Create "rendered" versions of each of the form elements and set them as variables that can be passed to the template file.

Note: This can also be done with a generic foreach loop (similar to the one in step two) that renders each form element automatically.

<?php
 
// Set up the Vars Array
 
$vars = array();

 
// Render Specific Fields You Want on Your Registration Form
  // note - the specific location of the element in the form array varies
 
$vars['name_element'] = drupal_render($form['account']['name']);
 
$vars['mail_element'] = drupal_render($form['account']['mail']);
 
// continue for each field you want...

  // Don't Forget the Submit Button 
 
$vars['submit_button'] = drupal_render($form['submit']);

?>

Step Four: Create a template file in your site's theme directory to build the user/register form with the customized variables we defined in step three.

Note: This file needs to be the same name as specified in the _phptemplate_callback (example: user_registration_form.tpl.php).

<div class="user-register-element">
  <label>Enter a screen name:</label>
  <div class="user-register-element-input">
    <?php print $name_element; ?>
  </div>
  <div class="user-register-element-description">
    Screen names can be up to 13 characters in length.
  </div>
</div>

<div class="user-register-element">
  <label>Enter an Email:</label>
  <div class="user-register-element-input">
    <?php print $mail_element; ?>
  </div>
  <div class="user-register-element-description">
    Emails must be valid.
  </div>
</div>

<?php // continue on for each rendered form element ?>

The drupal magic here is that the user registration form is now uniquely customizable by anyone who can edit the theme template. This allows for customized "prompts" for each profile field element, without changing the site-wide field name in admin/user/profile, and it allows for customization of the username and email titles and descriptions.

This technique will need to be modified to support external modules that modify the user/register form like LoginToboggan. It also needs to take into account things like "required" fieldstates.

Nice article.

Nice article. Thanks.

Question:
where is “submit” button in your ‘user_registration_form.tpl.php’ example?

Posted by Drupal Themes Garden (not verified) | Jun. 26th, 2008 @ 4:54am | Link to this Comment

Setting values...

Hi, the article has been a great help.

Is there a way to set the value of the input fields?

Specifically I’m wanting to set the ‘name’ and ‘email’ field values with a couple of $_POST variables, if they exist.

I’ve got a basic custom block form with ‘name’ and ‘email’ fields on another page and would like that to submit to the registration page and auto fill those two fields.

Posted by BK (not verified) | May. 22nd, 2008 @ 4:43pm | Link to this Comment

You may also try this

Posted by Anonymous (not verified) | Apr. 20th, 2008 @ 9:12pm | Link to this Comment

Where do I create the theme override.

As explained in step one, in what module code do I put the theme override?

The module code for the user/register form is in user.module.
But I doubt that you are talking about that.

Posted by Alexander (not verified) | Apr. 16th, 2008 @ 6:14am | Link to this Comment

Minor Correction

Where you have:

<?PHP
$output = _phptemplate_callback(‘user_registration_form’, $vars);
?>

That should actually be:

<?PHP
$output = _phptemplate_callback(‘user_registration_form’);
?>

If you provide a non-array to _phptemplate_callback for the 2nd argument, PHP will issue a warning.

Posted by Brendon (not verified) | Mar. 26th, 2008 @ 1:44pm | Link to this Comment

user registration

Hello,

Thank you for this informative HOWTO. My need is to reproduce the user registration form on the front_page. I do not have to change anything, just grab the form and style it special for the front.

The following is in template.tpl.php:
function zen_join_box() {
$output .= ”;
$output .= drupal_get_form(‘user_register’);
$output = ”.$output.”;
return $output;
}

But when I call zen_join_box from the front_page, I get undefined function.

Thank you for your help.

Posted by lynda (not verified) | Feb. 19th, 2008 @ 4:41pm | Link to this Comment

using t()

Nice article there, but as the title stated. Isn’t it encouraged to use t() in new D6 theming ? Looking at the name label and the descriptions for the fields.

Posted by Folkert (not verified) | Feb. 18th, 2008 @ 6:15pm | Link to this Comment

Nice tip. Don’t forget to

Nice tip. Don’t forget to run drupal_render on all the hidden elements. Omitting the token and other elements may render the form useless.

Posted by dvessel (not verified) | Feb. 15th, 2008 @ 10:45pm | Link to this Comment

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <br> <br/> <br /> <p> <img> <blockquote> <i> <b> <u>
  • Lines and paragraphs break automatically.
  • SmartyPants will translate ASCII punctuation characters into “smart” typographic punctuation HTML entities.
  • You may post code using <code>...</code> (generic) or <?php ... ?> (highlighted PHP) tags.
  • Web page addresses and e-mail addresses turn into links automatically.

More information about formatting options

4 + 5 =
Solve this simple math problem and enter the result. E.g. for 1+3, enter 4.