Theming the User Registration Form in Drupal 6

Jan
14

When you are building an online community, one of your important jobs is to remove obstacles for users to sign up to create accounts. Drupal's user registration form, out of the box, is one of the simplest forms out there, and maybe that is why it is also one of the easiest things to overlook when building a site. By the time profile fields are added in, captchas are placed on the page, and other components have had their way with the fields that become part of it, the form can get rather messy and detract from the user experience.

Fortunately, changing the way the user registration form looks is pretty easy. Modifying forms is something that Drupal 6 has made a lot simpler with advances in the forms api and the theming system. Instead of needing to create a custom module and modify the form at a structural level, developers can implement changes directly within their themes that allow them to author the display of forms using standard CSS and HTML markup. This moves the work of changing the look and feel of a site from aesthetically challenged developers squarely to the realm of designers, where it belongs.

Step One: Tell Drupal What Template to Use

There are 2 steps you need to take to implement a better looking user registration page within your Drupal site - create a template file, used to display the contents of the form, and make some small changes to template.php within your theme file to tell Drupal which template to use. We will look changes to template.php first, you will be modifying a function called 'themename_theme' (substitute the name of your theme for 'themename' in that statement). If this function is not already there, create it using the example below. Here, we are passing on the name of the template file for the user registration form, and calling it 'user-register'. You can feel free to use any name you wish for the template file.

<?php
function themename_theme($existing, $type, $theme, $path) {
  return array(
    ...
   
// tell Drupal what template to use for the user register form
   
'user_register' => array(
     
'arguments' => array('form' => NULL),
     
'template' => 'user-register', // this is the name of the template
   
),
    ...
  );
}
?>

After that is done, reset the registry by clearing cached data at the bottom of the Administer > Performance page.

Step Two: Build Your Template

The next step is you will want to create the template for the user registration form itself. In your theme directory, create a filed called user-register.tpl.php. Notice how the name exactly corresponds to the name we used in the code for template.php. If your form is not displaying properly, there is a good chance it is because there is a mispelling in one of these places. The following example shows you how to create some basic template code that will display the username and password fields, along with the submit button. Within user-register.tpl.php, paste the following code:

<div id="registration_form">
  <div class="field">
    <?php
     
print drupal_render($form['account']['name']); // prints the username field
   
?>

  </div>
  <div class="field">
    <?php
     
print drupal_render($form['account']['pass']); // print the password field
   
?>

  </div>
  <div class="field">
    <?php
       
print drupal_render($form['submit']); // print the submit button
     
?>

    </div>
  </div>
</div>

At this point, Drupal should know to use your template for generating the user registration page. Season to taste with some CSS and you are on your way to a great looking registration page!

As your site grows more complex, you may need to add additional fields to the form. The drupal_render function tells Drupal to 'build' any field that has been defined for this form. If you ever need to get a list of all the form fields that are part of the user registration form, put the following code anywhere within your template to generate a list of fields that are 'defined' for it.

<?php
 
print '<pre>';
  print
var_export($form);
  print
'</pre>';
?>

51 Comments

I am guessing the same

I am guessing the same principal applies for all forms on the site.

Yes you are correct this

Yes you are correct this process works for all forms on a site.

I created a the files as

I created a the files as shown above and now i am not able to display it in the front end.can u help me.

Hi, thanks for that great

Hi,
thanks for that great function, but do you know how to override the rest of the registration page? I still have the tabs and die design which is arround the form on the page. I only want to display the fields nothing else...

best regards

Use the page.tpl.php, check

Use the page.tpl.php, check for the user/register path and hide the $tabs variable there.

For example:

if (drupal_get_path_alias($_GET['q']) != "user/register") {

<?php
print $tabs;
?>

}

Hi Great Tutorial. Really

Hi Great Tutorial. Really well written and easy to understand. I used it and it came on screen as expected, validated the password as it should but when I submitted the form nothing happened and the form just went back to the default form values. I went to check the user page to see if the settings had changed there and none of the options had been changed there. I know the template was being recognized because I could change the layout of the form.

Any ideas how to get the form to submit to the database?

Yeah... the tutorial is

Yeah... the tutorial is concise and easy to understand, I applied all the concepts in Drupal 6.9 version but still couldnt submit the values to the database. When I press submit it reloads the creat an account page with no success. I also have the logintobbogan module. Any ideas?

me too getting the same

me too getting the same

at the last of the form,u

at the last of the form,u should also print the following in tpl file,other wise form will be submitted

:--------

print drupal_render($form['form_build_id']);
print drupal_render($form['form_id']);
print drupal_render($form['form_token']);
drupal_render($form);

becoz drupal checks for all elements

Hi, I'm new to Drupal so I

Hi, I'm new to Drupal so I need a simple help with that.
I bought a theme for Drupal 6. I installed it and it's working great.
I have no template.php file in /themes/mytheme dirctory so I create one with the above code. Then I create a user-register.tpl.php file with the above code too.
I added some code in the user-register.tpl.php file and clear the caching but I'm still get the default user registration form, any idea why?

Thanks.
Miki

Don't forget the

Don't forget the form_build_id and the form_id in the user-register.tpl.php

Without, it won't work ;-)

print drupal_render($form['form_build_id']);
print drupal_render($form['form_id']);

@Miki, don't forget the changes in template.php

Yep! Very important to

Yep!
Very important to rebuild the form with submitted data (eg. when the form is invalid and you need to render it again)

I added this code to my

I added this code to my template.php file, created the user_register.tpl.php file, added the print drupal_render($form['form_build_id']);
print drupal_render($form['form_id']); code then cleared the cache and nothing changed.

What could the problem be?

Don't forget to render hidden

Don't forget to render hidden fields or it won't work ;)

echo drupal_render($form['timezone']);
echo drupal_render($form['form_build_id']);
echo drupal_render($form['form_id']);

you also have to print the

you also have to print the "token" in order to make the form work

print drupal_render($form['form_token']);

From my own experience using

From my own experience using a form tpl.php, you need to print the whole $form at the very end of the template to ensure that the form will validate upon submission.

<?php print drupal_render($form); ?>

Just adding the hidden form_build_id and the form_id fields will not mean the form will work.

Printing the entire form at the end, however, will mean that all the stuff you wanted to hide in making the template will show. For those fields, include "unset" statements for each one:

<?php unset($form['field_to_hide']); ?>

Please correct me if I'm wrong or if there is a better way to do this.

I stand corrected - the

I stand corrected - the method below of printing the token (along with the form_id and the form_build_id) appears to work -- with no validation error. Thanks for the anonymous tip!

This is very important. This

This is very important.
This seems to be the solution to save an authenticated user to the users table in the database

This is very useful. If the

This is very useful.

If the desired fields are not displayed, try printing $form to see the actual keys that you should use. This snippet can be handy:

error_log('$var:'.var_export($var, TRUE)); // TODO: remove $var

hi i have used this model and

hi i have used this model and customized the user registration the issue was i could not able to redirect when submitting , any tips to rectify

Please let me know if you get

Please let me know if you get that resolved. I've been banging my head against a keyboard trying to get the user registration page to redirect to a new page after someone creates a new account.

Have you tried to add

Have you tried to add something like to your submission handler
(or in a -form_alter)

$form_state['redirect'] = sprintf('user/%d', $account->uid);

I found this tips in "Learning drupal 6 module development" (published in 2008) , on page 162

how to re-arrange the fields?

how to re-arrange the fields? cause this is the biggest issue I am facing right now the module "terms of use" and "create an account" button appearing between the form fields.

Thank you for this fine walk

Thank you for this fine walk through. While I think I've done everything as needed for a D6 template override of the user-profile-edit function, I find that the resulting form post does not store changed data and does not return an error. A little background:

In template.php:

function mytheme_theme(&$existing, $type, $theme, $path) {
return array(
'$hooks' => zen_theme($existing, $type, $theme, $path),
'user_register' => array(
'template' => 'user-register',
'arguments' => array('form' => NULL),
),
'user_profile_form' => array(
'template' => 'user-profile-edit',
'arguments' => array('form' => NULL),
),
);
}

The user-profile-edit.tpl.php is pretty straightforward, so nothing really to consider there.

Any thoughts on the failure to restore changed data without any sort of error?

Very helpful. Thanks for

Very helpful. Thanks for sharing. It's this basic Drupal stuff that gets us started on the right path. Thanks again.

This is exactly what I've

This is exactly what I've been trying to accomplish the last couple of days. Thanks for this tutorial. It has answered a million questions I've come up with over the last couple of days of hair-pulling.

The token wont print! print

The token wont print!
print drupal_render($form['form_token']);
Does not work,

drupal_render($form['timezone']);
echo drupal_render($form['form_build_id']);
echo drupal_render($form['form_id']);
works

So i need to use

<?php
print drupal_render($form);
?>

why wont the token be made?
the dirty option sucks.... i really want to token to work

I would just suggest that the

I would just suggest that the users feedback be considered by the writer of article to make necessary changes. Better than soooo many comments like "Don't forget to do so and so" and " Don't forget to print that whatever"

just ammend that in the main article... or if somebody can write a new article based on that

The article is very valuable and many thanks to the author :)

Hello Marc, Thanks for a very

Hello Marc, Thanks for a very nice tutorial. I understood some theming aspects now. But being a complete newb in php, I am a bit confused about some very primary thing. Hope you wont laugh at me and be kind enough to clear my confusion. I tried to work around my user registration form with the help of your tutorial. But on the same part when you say: print '';print var_export($form); print ''; in tpl.php file. I did that and then I checked user registration form after logging out as admin. I didnt find any array there. I also tried:
print drupal_render($form['form_build_id']);
print drupal_render($form['form_id']);
print drupal_render($form['form_token']);
drupal_render($form);
and also this : print drupal_render($form); . In the second method form id and form build id is needed, I dont know where to find those IDs and where to find all those printed arrays. Please help me clear my confusion, with some clear guidelines, taking account of my lack of php expertise. I will be very thankful to you.

Oh I am here again. I at last

Oh I am here again. I at last got all those fields after clearing cache. But omg, it comprises of arrays on 141 pages (after I copy pasted on words) -- of my simple user forms having around 10 fields about address, resume upload and educational backgrounds. How am I to look at all those 141 pages and then make a template out of this. Please help!

Thanx dude this was a much

Thanx dude this was a much more easy process than the usual way..

Hi, I just installed content

Hi,

I just installed content profile module for Drupal 6.16. I am having trouble setting up the user registration page to display the way I want it to. The custom fields I set up for my "Customer Profile" show up, but it ignores everything else (tried creating a contemplates dir and creating a "user-register.tpl.php" in my theme directory. Is there a good tutorial or someone who could lead me through.

Thanks,

:) David

PS - I need content profile (I think) becuase I have users that need to be login in to edit content, etc, and other customers who login but only get to save their billing and shipping info.

David, I am not 100% sure

David,

I am not 100% sure what you're looking to achieve, but using

<div class="field">
<?php
     
print drupal_render($form['Customer Profile']['profile_shipping-address']);
   
?>

  </div>

Or something like it should display fields.

For formatting, you can use CSS, or look into the Drupal Form API (http://api.drupal.org/api/drupal/developer--topics--forms_api_reference....)

Can someone tell me why in

Can someone tell me why in this script the three (...) dots are used?
When they're there I get error.

<?php
function themename_theme($existing, $type, $theme, $path) {
  return array(
    ...
   
// tell Drupal what template to use for the user register form
   
'user_register' => array(
     
'arguments' => array('form' => NULL),
     
'template' => 'user-register', // this is the name of the template
   
),
    ...
  );
}
?>

The three dots just mean that

The three dots just mean that the user_register key can exist in hook_theme with lots of other keys.

when i did all these things i

when i did all these things i am able to over ride the user registration tempalte with mine but unfortunately i wasnt able to bring the profile fields which i created through profile module. is there any solution to bring these fields into the override template(user-register.tpl.php)

**************template.php*************

function picop_theme($existing, $type, $theme, $path) {
return array(
'user_register' => array(
'arguments' => array('form' => NULL),
'template' => 'user-register', // this is the name of the template
)
);
}

**************user-register.tpl.php*************

<?php
//print drupal_render($form['account']);

     
print drupal_render($form['account']['name']); // prints the username field
   
?>

<?php
     
print drupal_render($form['account']['mail']); // print the password field
   
?>

<?php
    
print drupal_render($form['account']['profile_country']); //
   
?>

<?php
       
print drupal_render($form['submit']); // print the submit button
     
?>

****************
i created field profile_country in profile but not displayed in the tpl...why????

in template.php file, i write

in template.php file, i write like this
//friendspark is my theme name

<?php
function friendspark_theme($existing, $type, $theme, $path) {
    
'user_register' => array(
     
'arguments' => array('form' => NULL),
     
'template' => 'user-register', // this is the name of the template
   
),
}
?>

but this function is not called by drupal,

i checked this by

<?php
function friendspark_theme($existing, $type, $theme, $path) {
     exit;
    
'user_register' => array(
     
'arguments' => array('form' => NULL),
     
'template' => 'user-register', // this is the name of the template
   
),
}
?>

but it wont exit, please help me!

Oh my, Isn't there a module

Oh my, Isn't there a module for that?
So then when is the time for some Irony...
To see that a full blown heavenly documented custom registration module is absolutely necessary to stay within the lego block idea?
Yep, something's wrong if everybody needs to use hook_alter's and begin creating own modules (custom made to their needs) or tweaking existing modules, css files, snippets, theming, altering etc... So we're heading back to plain PHP coding right?
No critisism to the hard work an beautiful enthusiasm... but what was the point of drupal again?
I'm sorry to be hard on the workers here and off topic concerning the registration form itself.
Let an advanced drupal developper convince me in a NON-CODE language. :-)

Thanks a lot for this post,

Thanks a lot for this post, it's exactly what I was looking for.

I'm using Zen. Could you help

I'm using Zen. Could you help with the syntax for adding the code to my template.php.

<?php
function zen_theme(&$existing, $type, $theme, $path) {
  include_once
'./' . _zen_path() . '/template.theme-registry.inc';
  return
_zen_theme($existing, $type, $theme, $path);
}
?>

Thanks

-=Daniel

I wanna use different

I wanna use different node-{type}-form.tpl.php files.
Can someone tell me how my MYTHEME_theme() should look like?

I made this but it only works for the tweet content_type.
I tried to add a switch but nothing works.

<?php
function acquia_prosper_theme($existing, $type, $theme, $path) {
       
$items = array();
                  
$items['tweet_node_form'] = array(
                   
'arguments' => array('form' => array()),
                   
'path' => drupal_get_path('theme', 'acquia_prosper'),
                   
'template' => 'node-tweet-form',
                   
'preprocess functions' => array(
                                
'acquia_prosper_preprocess_tweet_form'
                        
)
                    );
                    return
$items;
}
?>

You just need to replicate

You just need to replicate the following for your other node types such that they are all added to the $items array.

<?php
$items
['{node_type}_node_form'] = array(
 
'arguments' => array('form' => array()),
 
'path' => drupal_get_path('theme', 'acquia_prosper'),
 
'template' => 'node-{node_type}-form',
 
'preprocess functions' => array(
   
'acquia_prosper_preprocess_{node_type}_form'
 
)
);
?>

You could do this by looping through an array of content types.

Thanks for the quick

Thanks for the quick respond.
And it was helpfull.

This worked wonderfully in

This worked wonderfully in drupal 6, But how can I acheive this on drupal 7, Any or all help is greatly appreciated.

Hello All, I need to

Hello All,

I need to different user registration templates for user Signup page.
When i put following code in template file

<?php
$saw
= arg();
if(
$saw['2'] == 'supplier'){
return array(   
     
'user_register' => array(
     
'arguments' => array('form' => NULL),
     
'template' => 'user_supplier', // this is the name of the supplier template
   
)     
  );
}
else if(
$saw['2']=='neighbor') {
return array(   
     
'user_register' => array(
     
'arguments' => array('form' => NULL),
     
'template' => 'user_neighbor', // this is the name of the neighbor template
   
)     
  );
}
?>

This code always loads user_neighbor template can any one suggest what i am doing wrong.
Thanks in advance

http://api.drupal.org/api/dru

http://api.drupal.org/api/drupal/developer--hooks--core.php/function/hoo...

You will notice some key words there: "Register a module (or theme's) theme implementations."

This means that hook_theme is used to register templates once (during a theme registry rebuild) and used on many page loads. This rules out the possibility of using dynamic code to switch templates in hook_theme.

http://drupal.org/node/223440#custom-suggestions would be a good place to start looking for how to override the template being used.

Hi Folks, I am new to this

Hi Folks,

I am new to this drupal development.
After studying the materials on drupal. I got some idea to work. Once i just started working on some module like, user-register module.

I created a user-register.tpl.php page in root/modules/user/ folder.
I can access that registration. Once i successfully fill that form and click on submit. Its not submitting the values to DB.

Can any one guide me how the flow of registration will work normally.
I am trying to find out a solution for that. But its very hard to find.

Looking for someone to solve my solution.

Thanks,
Sunil Kumar

HI Guys, I'm new Drupal and

HI Guys,

I'm new Drupal and to this post. Currently I've developed one of my site in drupal but using different template, When I Created new user account the page get redirected to home without display pending approval message which I've setup in Admin->Configuration->Account Setting "Visitors, but administrator approval is required" as selected. Any help would be appreciated.

You might not be printing the

You might not be printing the messages variable in your custom template. I suggest starting there - compare to a default theme template.

to me <?phpprint

to me

<?php
print drupal_render($form);
?>

is working properly....

but when i used

<?php
     
print drupal_render($form['account']['mail']); // print the password field
  
?>

method to display each and individual fields, its not working properly..
see the problem is all fields are visible, but when i click submit button nothing happens then,neither the validation nor the form posting..
can anyone help me??

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.
  • You may post code using <code>...</code> (generic) or <?php ... ?> (highlighted PHP) tags.

More information about formatting options