Here is the code in a simple custom module that I've written:


function new_password_form_alter(&$form, $form_state, $form_id) {
	// Check for the right form
	if ('user_profile_form' == $form_id) {
			unset($form['account']['pass']['pass1']['#title']);
			unset($form['account']['pass']['pass2']['#title']);
			$form['account']['pass']['pass1']['#title'] = t('New password');
			$form['account']['pass']['pass2']['#title'] = t('Confirm new password');
	}
}

My problem is, it doesn't work. I think the expand_password_confirm($element) function in form.inc is executed after the custom module executes. Thus, my changes don't take affect.

Basically, this simple module is supposed to change the 'Password:' title to 'New password:' and the 'Confirm password:' title to 'Confirm new password:'.

I can change any other title on this page except these two. Am I doing something wrong? Is there an alternate way of doing this?

I know that the 'String overrides' module can accomplish this, but it also changes the same labels on the 'Add User' form. So, that doesn't work well for me.

Any help you can offer would be appreciated.

Comments

Timothy Robb’s picture

$20 donation to Drupal in honor of whoever provides the solution to this dillemma. Thank you.

brei9000’s picture

Did you find a solution to your problem?

I'm trying to do the same.

chrisyates’s picture

To override the properties of the pass1 and pass2, you need to add an additional #process handler that runs after FAPI's expand_password_confirm, like so:

function yourmodule_form_alter(&$form, &$form_state, $form_id) {
  switch ($form_id) {
    case 'user_profile_form':
      // Here we need to provide an extra #process handler to allow us to modify
      // the password element that FAPI expands.
      $form['account']['pass']['#process'] = array('expand_password_confirm', 'yourmodule_password_confirm');
      break;
  }
}

/**
 * Implementation of expand_password_confirm.
 */
function yourmodule_password_confirm($element) {
  $element['pass1']['#title'] = t("New Password");
  $element['pass2']['#title'] = t("Confirm New Password");
  return $element;
}

Credit to boaz's blog post for pointing me in the right direction on this.

agileadam’s picture

Awesome! This was just what I needed... helps me understand the element processing/expansion too :)
Thanks chrisyates and boaz.

JThan’s picture

Version: 6.13 » 7.x-dev
Category: support » feature

Hi.

I had this problem also.

I suggest a text change on the password field, because as soon as use form_process_password_confirm you get two password fields and I only see this in places where you want to set a new Password. So why not changing the titles so they say that?

The other advantage would be that you could use the translation feature for the title. In the moment you cannot because you would also overwrite the string in the Login Form also.

Referring to http://api.drupal.org/api/function/form_process_password_confirm/7 we have this in D7:
(D6 is similar, just the function name changed: http://api.drupal.org/api/function/expand_password_confirm/6)

includes/form.inc, line 2146

function form_process_password_confirm($element) {
  $element['pass1'] =  array(
    '#type' => 'password',
    '#title' => t('Password'),
    '#value' => empty($element['#value']) ? NULL : $element['#value']['pass1'],
    '#required' => $element['#required'],
    '#attributes' => array('class' => array('password-field')),
  );
  $element['pass2'] =  array(
    '#type' => 'password',
    '#title' => t('Confirm password'),
    '#value' => empty($element['#value']) ? NULL : $element['#value']['pass2'],
    '#required' => $element['#required'],
    '#attributes' => array('class' => array('password-confirm')),
  );
  $element['#element_validate'] = array('password_confirm_validate');
  $element['#tree'] = TRUE;

  if (isset($element['#size'])) {
    $element['pass1']['#size'] = $element['pass2']['#size'] = $element['#size'];
  }

  return $element;
}

which could be changed to this:

function form_process_password_confirm($element) {
  $element['pass1'] =  array(
    '#type' => 'password',
    '#title' => t('New Password'),
    '#value' => empty($element['#value']) ? NULL : $element['#value']['pass1'],
    '#required' => $element['#required'],
    '#attributes' => array('class' => array('password-field')),
  );
  $element['pass2'] =  array(
    '#type' => 'password',
    '#title' => t('Confirm new password'),
    '#value' => empty($element['#value']) ? NULL : $element['#value']['pass2'],
    '#required' => $element['#required'],
    '#attributes' => array('class' => array('password-confirm')),
  );
  $element['#element_validate'] = array('password_confirm_validate');
  $element['#tree'] = TRUE;

  if (isset($element['#size'])) {
    $element['pass1']['#size'] = $element['pass2']['#size'] = $element['#size'];
  }

  return $element;
}

The changes are just the title fields. I did not make a patch out of this now because I may be overseeing some use cases where this makes no sense. Can someone point there or has any other arguments why the text cannot change?

Thx
JThan

kyberman’s picture

Hi,

I had the same problem and my solution is similar:

function YOURMODULE_form_user_profile_form_alter(&$form, &$form_state, $form_id) {
  $form['account']['pass']['#process'] = array(
    'form_process_password_confirm',
    'YOURMODULE_form_process_password_confirm',
    'user_form_process_password_confirm'
  );
}

function YOURMODULE_form_process_password_confirm($element) {
  $element['pass1']['#title'] = t('New password');
  $element['pass2']['#title'] = t('Confirm new password');
  return $element;
}
aburrows’s picture

This worked for me:

/**
 * @file
 * Allows modification of password fields in FAPI
 */
 function register_alter_form_alter(&$form, &$form_state, $form_id) {
   switch ($form_id) {
     case 'user_register_form':
       // Here we need to provide an extra #process handler to allow us to modify
       // the password element that FAPI expands.
       $form['account']['pass']['#process'] = array('form_process_password_confirm', 'register_alter_password_confirm');
       break;
   }
 }

 /**
 * Implementation of expand_password_confirm.
 */
 function register_alter_password_confirm($element) {
   $element['pass1']['#title'] = t("Password");
   $element['pass2']['#title'] = t("Repeat password");
   return $element;
 }
Ivanhoe123’s picture

Yes, this works for D7

D6 uses: expand_password_confirm();
D7 uses: form_process_password_confirm();

They basically do the same thing, the function has just been renamed in D7.

chanderbhushan’s picture

Category: support » feature
Status: Closed (fixed) » Active
function mymodulename_form_alter(&$form, &$form_state, $form_id) {
    if ($form_id =='form_id'){
	 $form['user']['profile_text_feild_name']['#title']=t('your custom title');
       } 
}
aburrows’s picture

chanderbhushan you were missing a ' in the conditional statement

function mymodulename_form_alter(&$form, &$form_state, $form_id) {
  if ($form_id =='form_id') {
    $form['user']['profile_text_feild_name']['#title'] = t('your custom title');
  } 
}
dddave’s picture

Category: feature » support
Status: Active » Fixed
fonant’s picture

If you want the default password strength meter in D7, you need to include 'user_form_process_password_confirm' too.

Since these default functions are defined as the default '#process' arguments in system_element_info() for a password_confirm element, you can't just append the additional function to the end of the array, as '#process' we see is usually empty.

To be safe (in case Drupal adds new default process functions, and to allow other modules to add process functions before we get here) we need something like:


function YOURMODULE_HOOK_FORM_ALTER(&$form, &$form_state, $form_id) {
  // Get default process function array:
  $element_info = element_info('password_confirm');
  $process = $element_info['#process'];
  // Add our process function to the array:
  $process[] = 'YOURMODULE_process_password_confirm';
  $form['FIELDNAME']['#process'] = $process;
}

function YOURMODULE_process_password_confirm($element) {
  $element['pass1']['#title'] = t('New password');
  $element['pass2']['#title'] = t('Confirm new password');
  return $element;
}

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

Status: Active » Closed (fixed)
prsnjtbarman’s picture

Issue summary: View changes

This worked for me.

ZalemCitizen’s picture

kyberman (#6): congrats, man.
I just added my custom process function at the end of process functions array (build in core file system.module) and it failed. It didn't occur to me that user_form_process_password_confirm needed to be in last position.

Thanks.

vishal.shirguppi’s picture

Worked for me with a small change. My form array structure -

$form['account']['password']['pass']['#process'] = array('form_process_password_confirm', 'my_module_form_process_password_confirm','user_form_process_password_confirm');

Thanks!

Keenegan’s picture

For Drupal 8, I did this :

//in form_alter
$form['#after_build'][] = 'my_module_after_build';

function my_module_after_build($form, &$form_state) {
    $form['account']['pass']['pass1']['#title'] = t('New password');
    return $form;
}

DashDesai’s picture

Extending @Keenegan's suggestion, if anyone is looking for a full code for Drupal 8. Include the following in your custom module:


function my_module_form_alter(&$form, &$form_state, $form_id) {
  switch ($form_id) {
    case 'user_form':
      $form['#after_build'][] = 'my_module_after_build';
      break;
  }
}

function my_module_after_build($form, &$form_state) {
    $form['account']['pass']['pass1']['#title'] = t('New password');
    return $form;
}

AlexeiK’s picture

@Keenegan and @DashDesai
Thanks a lot! Worked like a charm!

jzavrl’s picture

Was looking through this as well and found (I think) a better solution. For Drupal 8, not sure about D7.

/**
 * Implements hook_element_info_alter().
 */
function module_element_info_alter(array &$types) {
  if (isset($types['password_confirm'])) {
    $types['password_confirm']['#process'][] = 'module_form_process_password_confirm';
  }
}

/**
 * Process the password_confirm element.
 */
function module_form_process_password_confirm($element) {
  $element['pass1']['#title'] = t('Password');
  $element['pass2']['#title'] = t('Confirm password');

  return $element;
}

This essentially alters the whole password_confirm element which is used on forms. If you use the form alter approach you would need to think of every form where this might occur. With this approach, if the form is using the password_confirm element, you are already taken care of.

Ralf Eisler’s picture

@jzavrl

Your solution worked for me in Drupal 8. Thank you!

prsnjtbarman’s picture

@Kng #18 - This worked fine for drupal 8 registration form alter password field

prsnjtbarman’s picture

Tunprog’s picture

@jzavrl

Works for me as well in Drupal 8. Thanks!