To expand on Jeremy's answer, you're going to want to study Drupal's Form API and user_register()
. In short, you build an associated array; each element in the array corresponds to one form element.
Each form element in the array is its own associated array. They can have a type: textfield, select menu, checkboxes, etc.: see the Form API reference for all the types.
Each form element can also have a weight: this is how you order elements around. Lower numbered weights show up before higher numbered weights in the form.
One of the element types available to you is fieldset
: this is what will allow you to group elements together. When you use a fieldset, it creates a section of the form with its own weight values.
So, let's say you have a form with three fields: Name, Company, and E-mail address. The Name should show up first, Company second, E-mail address third. You could specify the form like so:
$form['name'] = array(
'#type' => 'textfield',
'#title' => t('Name'),
'#weight' => 1,
);
$form['company'] = array(
'#type' => 'textfield',
'#title' => t('Company'),
'#weight' => 2,
);
$form['email'] = array(
'#type' => 'textfield',
'#title' => t('E-mail address'),
'#weight' => 3,
);
Note the #weight
key. If you wanted Company to appear after E-mail address, you'd set $form['company']['#weight']
to something higher than 3.
Now let's say you wanted to group Name and Company into a fieldset called Personal Information. Your form would now look something like this:
$form['personal'] = array(
'#type' => 'fieldset',
'#title' => t('Personal information'),
'#weight' => 1,
);
$form['personal']['name'] = array(
'#type' => 'textfield',
'#title' => t('Name'),
'#weight' => 1,
);
$form['personal']['company'] = array(
'#type' => 'textfield',
'#title' => t('Company'),
'#weight' => 2,
);
$form['email'] = array(
'#type' => 'textfield',
'#title' => t('E-mail address'),
'#weight' => 3,
);
Note that Name and Company are now array elements of $form['personal']
.
If you want to make Name show up after Company in the fieldset, set its #weight
higher than 2. Because the Name is now part of a fieldset that has a lower #weight
than the E-mail address field, even if you set $form['personal']['name']['#weight']
to 4, it wouldn't make the Name show up after E-mail address.
So what you're going to attempt to do is use hook_form_alter()
to alter the user_register
form to change the weights of certain form elements, create your own fieldsets, and move certain form elements into your newly created fieldsets.
There are ways to do this within your theme, but I prefer creating a custom module for this. Create your custom module, and implement hook_form_alter()
:
function test_form_alter(&$form, $form_state, $form_id) {
if ($form_id === 'user_register') { // Only modify the user registration form
// Before you can get down to business, you need to figure out the
// structure of the user registration form. Use var_dump or kpr to dump
// the $form array.
// Note: if you want to use kpr on the user registration form, give
// anonymous permission to see devel information.
// kpr($form);
// Move Name field to after E-Mail field
$form['name']['#weight'] = 2;
$form['mail']['#weight'] = 1;
// Group Name and E-mail together into a fieldset
$form['personal_info'] = array(
'#type' => 'fieldset',
'#title' => t('Personal information'),
);
$form['personal_info']['name'] = $form['name'];
$form['personal_info']['mail'] = $form['mail'];
// The last block only copied the elements: unset the old ones.
unset($form['name']);
unset($form['mail']);
}
}
In more complex forms, moving things from one fieldset to another might yield unexpected results when submitting the form. This is because $form['name']
isn't the same as $form['group']['name']
, which isn't the same as $form['other_group']['name']
. You don't have to worry about that on the user_register
form for the most part, but check out the handbook page on #tree and #parents for more information about this.
This covers modifying existing fields in the user registration form: if you want to add new fields, I highly recommend using Content Profile. If you want to create custom fields on your own, it's going to get a lot more complex as you're going to have to implement your own validate and submit handlers. Content Profile handles this for you: check out its README to see how to activate it for registration forms.