Custom steps and forms in a D7 install profile

1 comment

In the last post I demonstrated creating a very basic install profile in Drupal 7. It was more or less a stripped down version of the standard profile with a few very minor additions.

I've been getting some great comments on my posts and one I wanted to note was from @david regarding the Profiler project. I've not had a chance to use it yet but it looks very promising. The profiler module provides an improved API and tools to vastly simplify what's necessary in writing your install profiles. While I would guess some more complex tasks still require you to use the raw Drupal API, this tool looks like it could give you a huge head start.

So, in the previous post, one of the additions I wanted to make but couldn't, was to create the default client user. The client name and email address will obviously differ on all sites we build. For this we need to add a new step in the install process to allow us to configure the client account prior to it's creation. All of the code from here on out will sit in our .profile file (recall that this is equivalent to a .module file, but for install profiles).

The first thing we need to do is define our profile tasks.

 * Implements hook_install_tasks().
function brochure_install_tasks() {
  $tasks = array(
    'brochure_client_form' => array(
      'display_name' => st('Setup Client'),
      'type' => 'form',
  return $tasks;

hook_install_tasks() allows us to create new steps in the install process. Each task more or less maps to a function in your .profile - in this case brochure_client_form. The display_name is used as the text displayed in the sidebar with the install profile steps as can be seen in the screenshot below.

If you're wondering about the st() function, it's basically equivalent to the t() function but used in a context where the localization system may not yet be available. You should generally use st() in your install profile where t() would normally be used.

Install profile tasks can be far more complex than what I've presented here and I'd strongly recommend reading through official documentation on install profiles or the API docs for hook_install_tasks().

The only other thing left to do here is to define our form API handler. This is done the same as any other Drupal module with _form(), _form_validate(), and _form_submit() functions inside your .profile file. There's nothing specific to install profiles here.

function brochure_client_form() {
  $form = array();
  $form['intro'] = array(
    '#markup' => '<p>' . st('Setup your default client account below.') . '</p>',
  $form['client_name'] = array(
    '#type' => 'textfield',
    '#title' => st('Client Username'),
    '#required' => TRUE,
  $form['client_mail'] = array(
    '#type' => 'textfield',
    '#title' => st('Client E-mail Address'),
    '#required' => TRUE,
  $form['client_pass'] = array(
    '#type' => 'password',
    '#title' => st('Client Password'),
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => st('Continue'),
  return $form;

function brochure_client_form_validate($form, &$form_state) {
  if (!valid_email_address($form_state['values']['client_mail'])) {
    form_set_error('client_mail', st('Please enter a valid email address'));

function brochure_client_form_submit($form, &$form_state) {
  $values = $form_state['values'];

  // Setup the user account array to programatically create a new user.
  $account = array(
    'name' => $values['client_name'],
    'pass' => !empty($values['client_pass']) ? $values['client_pass'] : user_password(),
    'mail' => $values['client_mail'],
    'status' => 1,
    'init' => $values['client_mail'],
  $account = user_save(null, $account);

  // Assign the client to the "administrator" role.
  $role = user_role_load_by_name('administrator');
    ->fields(array('uid' => $account->uid, 'rid' => $role->rid))

By using tasks you have the ability to do some very customized stuff out of the box for your profile. Creating a client user and assigning a role to them (as done in this example) takes maybe 15 seconds to do for each site. If you create say 3 brochure client sites a month that's about 9 minutes of savings per year! That's enough time to take at least 2 showers!

Peanut Gallery


Very helpful.

It's very difficult to find complete examples on this subject, and the most known Drupal distros don't implement this in that way.

You saved my day, thanks :-)