This is an example of creating a template file to custom theme the Edit Account page in Drupal (user/#/edit).
This example is specific to Drupal 6. For suggestions related to Drupal 7, please check the comments below this article.
For the sake of an example of what “could” be done, the template is split into a two column layout, with parts of the form in each column. Also various adjustments and changes are made to some of the form elements, such as rewording a description, changing some of the fieldset titles, adjusting the size of some of the form fields, and renaming the submit and delete buttons.
This code example assumes several settings are enabled on your Drupal site, including: User pictures, signatures, and the permission to select alternate themes (although the UID 1 admin will still be able to select themes here in any case).
Depending on the modules you have installed, additional variables for the fields produced by those modules will need to be prepared in the preprocess function, and added to the user-profile-form.tpl.php in order to show up. As needed, you can uncomment the dsm($vars['form']);
line if you have Devel module installed, which will make it much easier to visually browse through the contents of the form and find the names of elements you want to include.
The <?php print drupal_render($form); ?>
line at the bottom of user-profile-form.tpl.php is very important. There are a variety of hidden form element which must be included in order for the form to function correctly. Adding this line at the bottom will include the remaining part of the form that you haven’t already manually separated out for custom theming (both hidden fields, as well as any regular form content which you haven’t separated out manually). So long as no required fields are shown at the bottom here, it’s possible to wrap the area with a div set to display: hidden if you wish to hide them. Setting this part of the form to be hidden if required fields exist in it will result in the form being impossible to submit.
Much of this information comes from the excellent Drupal Dojo videos which introduce the method for preparing theme template files, as well as theming forms — you should absolutely watch them:
- Drupal Dojo Lesson 41: Theme Template Files for Drupal 6 (includes source files)
- Drupal Dojo Lesson 42: Fine-tuning the UI by Theming Forms In Drupal 6.0
Code for template.php
Add this code to template.php, changing both instances of YOURTHEME to the actual name of your theme:
/**
* Implementation of hook_theme().
*/
function YOURTHEME_theme() {
return array(
'user_profile_form' => array(
'arguments' => array('form' => NULL),
'template' => 'user-profile-form',
),
);
}
/**
* Preprocess user profile form.
*/
function YOURTHEME_preprocess_user_profile_form(&$vars) {
// Uncomment the following line if Devel module is enabled, to view the contents of the form.
// dsm($vars['form']);
// Change the help text for specific form elements.
$vars['form']['account']['name']['#description'] = t('Custom description regarding the Username.');
// Adjust the titles of several fieldsets.
$vars['form']['picture']['#title'] = t('Your user picture / avatar');
$vars['form']['timezone']['#title'] = t('Time zone');
unset($vars['form']['timezone']['timezone']['#title']);
// Set several elements that by default have collapsed fieldsets to expanded and non-collapsible.
$vars['form']['theme_select']['themes']['#collapsible'] = FALSE;
$vars['form']['picture']['#collapsible'] = FALSE;
$vars['form']['contact']['#collapsible'] = FALSE;
$vars['form']['timezone']['#collapsible'] = FALSE;
// Adjust the size of several fields to fit better in 2 columns.
$vars['form']['account']['name']['#size'] = 25;
$vars['form']['account']['mail']['#size'] = 25;
$vars['form']['picture']['picture_upload']['#size'] = 40;
$vars['form']['signature_settings']['signature']['#cols'] = 50;
// Rename the Save and Delete buttons to be more clear.
$vars['form']['submit']['#value'] = t('Save profile');
$vars['form']['delete']['#value'] = t('Delete account');
// Prepare all of the desired form elements as variables, to be used in user-profile-form.tpl.php.
// Everything before this part is optional.
$vars['account'] = drupal_render($vars['form']['account']);
$vars['theme_select'] = drupal_render($vars['form']['theme_select']);
$vars['picture'] = drupal_render($vars['form']['picture']);
$vars['signature_settings'] = drupal_render($vars['form']['signature_settings']);
$vars['contact'] = drupal_render($vars['form']['contact']);
$vars['timezone'] = drupal_render($vars['form']['timezone']);
$vars['submit'] = drupal_render($vars['form']['submit']);
$vars['delete'] = drupal_render($vars['form']['delete']);
}
Code for style.css
Add the following to style.css:
/**
* Custom form layout.
*/
#user-profile-form legend {
font-size: 1.2em;
}
#user-profile-form .form-column-1,
#user-profile-form .form-column-2 {
float: left;
width: 45%;
}
#user-profile-form .form-column-1 {
margin: 0 22px 0 0;
}
Code for user-profile-form.tpl.php
Create a new file in your theme’s directory called user-profile-form.tpl.php and paste in the following code:
<div id="user-profile-form">
<div class="form-column-1">
<?php print $account; ?>
<?php print $contact; ?>
<?php print $timezone; ?>
</div>
<div class="form-column-2">
<?php print $theme_select; ?>
<?php print $picture; ?>
<?php print $signature_settings; ?>
</div>
<?php print $submit; ?>
<?php print $delete; ?>
<?php print drupal_render($form); ?>
</div>
After you add all the code and files, you will need to rebuild the theme registry in order for Drupal to load the new template file. The easiest way to do this is using Admin Menu module (top left icon) or the Devel block offered by Devel module. If you don’t have either of these (though you should) then you can rebuild the theme registry by either 1) Visiting the main Themes page and saving it without any changes, 2) Visiting the Modules page, or 3) Going to Administer > Site configuration > Performance and clicking the “Clear cached data” button.
On Drupal 7 at least, some actions seem to need other components.
I used this, in my theme fonction
$vars[‘actions’] = drupal_render($vars[”][‘actions’])
. drupal_render($vars[”][‘form_token’])
. drupal_render($vars[”][‘form_id’])
;
then this, in the tpl
print $actions;
This solution does not work at all, please remove it from the internet because it wasted several hours of my time. The variables will not be accessible to the template in drupal 7.
I have added a note to the top of the article clarifying that this is specific to Drupal 6, and to check the comments for suggestions related to Drupal 7.
Is it possible to create sub pages this way?
For example.
I add custom fields to my user account in drupal 7.
Then I can create multiple sub tabs (kind of like the profile2 module does) by making templates that pull the fields.
A notifications tab would be templated at user-profile-form-notifications.tpl.php
Does this make sense? I can explain more.