Problem/Motivation

AccountForm::form() uses the following code.

$form_state->set('user', $account);

// The user may only change their own password without their current
// password if they logged in via a one-time login link.
if (!$form_state->get('user_pass_reset')) {
  $form['account']['current_pass']['#description'] = $this->t('Required if you want to change the %mail or %pass below. <a href=":request_new_url" title="Send password reset instructions via email.">Reset your password</a>.', [
    '%mail' => $form['account']['mail']['#title'],
    '%pass' => $this->t('Password'),
    ':request_new_url' => Url::fromRoute('user.pass')->toString(),
  ]);
}

Required if you want to change the %mail or %pass below. is problematic to translate in languages that use more than a definite article because, without knowing which word follows the article, it is not possible to decide which article must be used.

For example, in Italian the definite articles are il, lo, gli, i, la, and le depending on the word to which the article is applied. Without knowing what word follows the article, which in this case is replaced by %mail, I cannot know which article to use.
Furthermore, in Italian I could translate email with indirizzo email, indirizzo di posta elettronica, posta elettronica, or simply use email or mail as in English. With the article, those translations would become l'indirizzo email, l'indirizzo di posta elettronica, la posta elettronica, l'email, and la mail. (In l'email, l' is an elision for la, but differently from la, l' is written without spaces before the following word.)

In Norwegian, the definite article is an enclitic which is attached to the word. For example, the translation of the house is husen, while the translation of the car is bilen.
Even supposing I would know which definite article is used, I cannot attach it to the placeholder, which would change to a different placeholder (%mailen instead of %mail).

In both the cases, the sentence can be translated if what follows the definite article is not a placeholder.

The placeholder has been used to avoid to translate again the form element title, but using a placeholder after a definite article causes more translation issues.

Proposed resolution

In 'Required if you want to change the %mail or %pass below. <a href=":request_new_url" title="Send password reset instructions via email.">Reset your password</a>.', do not use the %mail nor the %pass placeholders.
Instead, a string like 'Required if you want to change the <em>Email address</em> or the <em>Password</em> field below. <a href=":request_new_url" title="Send password reset instructions via email.">Reset your password</a>.' should be used, where
Email address and Password are the title of the form elements which requires the current password to be changed.

Original report for Drupal 7

The string

Enter your current password to change the %mail or %pass. !request_new.

on user/n/edit is very hard to translate correctly because of the placeholders %mail and %pass. You really need to control the whole sentence to translate it properly. A couple of examples: In Norwegian, you don't use a separate word like "the" to get the definite form, you add an ending to the word instead. While in German, there are three different versions of "the" depending on the word it's pointing to.

There doesn't seem to be a good reason for these placeholders. The string should be changed to:

Enter your current password to change the <em>e-mail address</em> or <em>password</em>. !request_new.

Issue fork drupal-973772

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

joachim’s picture

Confirming.

The logic in this form is pretty crusty and hard to follow:

    // The user may only change their own password without their current
    // password if they logged in via a one-time login link.
    if (!$pass_reset) {
      $protected_values['mail'] = $form['account']['mail']['#title'];
      $protected_values['pass'] = t('Password');
      $request_new = l(t('Request new password'), 'user/password', array('attributes' => array('title' => t('Request new password via e-mail.'))));
      $current_pass_description = t('Enter your current password to change the %mail or %pass. !request_new.', array('%mail' => $protected_values['mail'], '%pass' => $protected_values['pass'], '!request_new' => $request_new));
    }

$protected_values appears to be some magic needed for the form to work securely, but WTF is with reaching back into it to get strings for a title?

Could do with input from someone who understands how this works before I wade in and make a patch.

joachim’s picture

Also, how are you finding this one:

form_set_error('current_pass', t("Your current password is missing or incorrect; it's required to change the %name.", array('%name' => $name)));

It's probably not clear from what you get as a translator that %name can be either 'password' or 'e-mail address' as above.

joachim’s picture

Status: Active » Needs review
StatusFileSize
new1.24 KB

Here's a patch for the original bit.

I suspect the 'Your current password is missing or incorrect....' bit will need some work too as it has the same problem; might have to split it into two separate strings and forego the clever reuse, as by the sound of it it will fail on languages that need to alter nouns.

I think a follow-on issue is needed to clean up the confusing logic and badly-worded comments, as it took me over half an hour to understand what this form is doing.

EvanDonovan’s picture

Status: Needs review » Needs work

@joachim: Why are the mail and pass variables still in the t() function if they are not being used? Also, neither should be capitalized.

Once that is fixed, it should be good.

joachim’s picture

+++ modules/user/user.module	17 Nov 2010 11:28:14 -0000
@@ -994,7 +994,7 @@ function user_account_form(&$form, &$for
       $protected_values['pass'] = t('Password');

Do you mean this line? This is kinda crack, but it's used by the validation further down. I agree it needs cleaning up, but it's out of the scope of this patch.

Powered by Dreditor.

EvanDonovan’s picture

@joachim: No, I mean

+ $current_pass_description = t('Enter your current password to change the <em>E-mail address</em> or <em>Password</em>. !request_new.', array('%mail' => $protected_values['mail'], '%pass' => $protected_values['pass'], '!request_new' => $request_new));

The first two parameters in the t() function aren't being used anymore, so I don't think they need to be included in it (I know that they need to be set earlier). And the words with which they have been replaced need to be lowercase.

drupal_was_my_past’s picture

Version: 7.x-dev » 8.x-dev
Status: Needs work » Needs review
StatusFileSize
new996 bytes

Re-rolling patch from #3 with EvanDonovan's suggestions. Also pulled $request_new out of t(). Moving this to 8.x because of string freeze.

drupal_was_my_past’s picture

StatusFileSize
new1016 bytes

Re-rolled after #22336: Move all core Drupal files under a /core folder to improve usability and upgrades core directory structure for Drupal 8 was changed.

Status: Needs review » Needs work

The last submitted patch, user-change-password-973772-8.patch, failed testing.

drupal_was_my_past’s picture

Assigned: Unassigned » drupal_was_my_past
Status: Needs work » Needs review
StatusFileSize
new1.16 KB

Re-rolling #8.

tstoeckler’s picture

Version: 8.x-dev » 7.x-dev
Status: Needs review » Needs work

You shouldn't pull $request_new out of t(). Other languages might want to put that bit at a different place than at the end (RTL languages, for instance).

tstoeckler’s picture

Version: 7.x-dev » 8.x-dev

Sorry, didn't want to change version.

drupal_was_my_past’s picture

@tstoeckler But $request_new has already been run through t(). Doesn't running it through twice cause problems?

tstoeckler’s picture

As it currently stands $request_new is added to the string as a !placeholder, which aren't translated in themselves. Another form, which I would personally like even better, is to inline the link in the t() such as:
Required if you want to change the <em>e-mail address</em> or <em>password</em> below. <a href="@url" title="Request new password via e-mail.">Request new password</a>
That would be a change from the current method, though.

drupal_was_my_past’s picture

Status: Needs work » Needs review

But $request_new is uses l() and t() itself, so it seems like it would run the "Request new password." string through t() first in l() and then again in another t().

tstoeckler’s picture

Status: Needs review » Needs work

No it doesn't! t() doesn't translate %arguments, @arguments, or !arguments. That would make no sense. :)

drupal_was_my_past’s picture

OH! I see! I'm sorry I was being so dense. I'll re-roll it with the !placeholder included in the t().

drupal_was_my_past’s picture

On second thought, I'll use your suggestion in #14. Patch forthcoming.

drupal_was_my_past’s picture

StatusFileSize
new1.13 KB

Re-rolled patch with suggestion from #14.

drupal_was_my_past’s picture

Status: Needs work » Needs review

Forgot to change status to needs review.

tstoeckler’s picture

Status: Needs review » Needs work

Thanks for sticking with this. I'm sorry that I have to set this to "needs work" once more.

+++ b/core/modules/user/user.module
@@ -988,8 +988,7 @@ function user_account_form(&$form, &$form_state) {
+      $current_pass_description = t('Required if you want to change the <em>e-mail address</em> or <em>password</em> below. <a href="@request_url" title="Request new password via e-mail.">Request new password.</a>', array('@request_url' => 'user/password'));

You should call url() on 'user/password'. l() does that automatically, that's why it wasn't needed before.

8 days to next Drupal core point release.

drupal_was_my_past’s picture

Status: Needs work » Needs review
StatusFileSize
new1.13 KB

@tstoeckler no problem. Thanks for the fix. I was struggling with that part and gave it my best shot. Patch re-rolled here.

tstoeckler’s picture

Issue tags: -String freeze

I was about to mark this RTBC, but upon looking at it one time I stumbled on the '< em >' part. Before we were using the titles of the form elements, i.e. 'Password' and 'E-mail address' in the < em >. The patch removes that capitalization, but leaves the < em > which now doesn't really reference those form elements anymore. So should we remove the < em > as well, or re-capitalize the two (or neither)? I'm leaning towards the former, but not sure.

Also removing "string freeze" tag, as this will not go into D7 anymore.

kscheirer’s picture

Status: Needs review » Needs work

The last submitted patch, user-change-password-973772-22.patch, failed testing.

mgifford’s picture

Assigned: drupal_was_my_past » Unassigned
Issue summary: View changes

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.8.x-dev

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

quietone’s picture

Version: 8.9.x-dev » 7.x-dev
Issue tags: +Bug Smash Initiative

I tested this on 9.2.x and the string Enter your current password to change the %mail or %pass. does not exist in the code base nor in 8.9.x. It was replaced with Your current password is missing or incorrect; it's required to change the %name.in #2418119: REST user updates bypass tightened user account change validation in March 2015. The new string is easier to translate (looking at the Italian translation right now).

Since the string still exists in D7 moving to the Drupal 7 issue queue.

avpaderno’s picture

Version: 7.x-dev » 11.x-dev

Actually, Your current password is missing or incorrect; it's required to change the %name. is not easier to translate, not even in Italian.

In Italian, the translation of Your current password is missing or incorrect; it's required to change the email. is La tua password corrente è mancante o errata; è necessaria per modificare l'email. The translation of Your current password is missing or incorrect; it's required to change the password. is La tua password corrente è mancante o errata; è necessaria per modificare la password.

In Russian, the translation for Your current password is missing or incorrect; it's required to change the %name. Your current password is missing or incorrect; it's required to change the email. Your current password is missing or incorrect; it's required to change the password. are the following.

  • Ваш текущий пароль отсутствует или неверен; необходимо изменить %name.
  • Ваш текущий пароль отсутствует или неверен; необходимо изменить электронную почту.
  • Ваш текущий пароль отсутствует или неверен; требуется сменить пароль.

Also in this case, the sentence changes basing on what replaces %name.

amanmansuri72 made their first commit to this issue’s fork.

quietone’s picture

Status: Needs work » Needs review

There is some confusion here. I was referring to the string in the issue summary. The string in the issue summary is "Enter your current password to change the %mail or %pass. !request_new." That string was changed in core 2011, #1326172: Improve wording of the "Current password" field description on the user edit form, to "Required if you want to change the %mail or %pass below". That string is still in core.

The string in #36, is different from those two. The string in #36 added in 2010 in [#8629]. So, I think that should be a separate issue.

needs-review-queue-bot’s picture

Status: Needs review » Needs work

The Needs Review Queue Bot tested this issue.

While you are making the above changes, we recommend that you convert this patch to a merge request. Merge requests are preferred over patches. Be sure to hide the old patch files as well. (Converting an issue to a merge request without other contributions to the issue will not receive credit.)

avpaderno’s picture

My comment was a reply to comment #35, which says:

I tested this on 9.2.x and the string Enter your current password to change the %mail or %pass. does not exist in the code base nor in 8.9.x. It was replaced with Your current password is missing or incorrect; it's required to change the %name.in #2418119: REST user updates bypass tightened user account change validation in March 2015. The new string is easier to translate (looking at the Italian translation right now).

Since the string still exists in D7 moving to the Drupal 7 issue queue.

I did not check which string was actually used, but that comment said the string used in Drupal 7 was replaced from Your current password is missing or incorrect; it's required to change the %name., which is said to be easier to translate.

avpaderno’s picture

Even Required if you want to change the %mail or %pass below has the same issue the original string has: Other languages could have more than a definite article, or could use no definite article at all.
In Italian, the definite articles are il, lo, la, gli, i, le, not considering that it is l'email, not la email, but it is la mail. Without knowing which word is used, after the article, I can just guess basing on the placeholder, with the consequence that l'mail or la email could appear, depending on my guess and what value is used for %mail.

avpaderno’s picture

In Norwegian seems to be even more difficult, as the translation of la signora seems to be damen, while the translation of il bambino seems to be barnet. In both the cases, the bold part in the word is the article. (The translation of signora would be dam.)

(Technically, the definite article in Norwegian is an enclitic, contrary to Italian and English where it is a proclitic.)

avpaderno’s picture

quietone’s picture

Issue summary: View changes
Status: Needs work » Active
Issue tags: -Needs issue summary update

So, I came to two different conclusions based on my git research. That doesn't help this at all!

I have updated the issue summary

@avpaderno, do you have a suggestions to fix this?

avpaderno’s picture

Issue summary: View changes
avpaderno’s picture

Title: Hard to translate: "Enter your current password to change the %mail or %pass." » Hard to translate: "Required if you want to change the %mail or %pass below."

The solution is simple: Do not use placeholders after an article.

avpaderno’s picture

Issue summary: View changes

(I forgot the link to the documentation page.)

avpaderno’s picture

The only time the %mail is used in a translatable string is in the core/modules/user/src/AccountForm.php file.
I would leave other cases of placeholder after an article to other issues.

avpaderno’s picture

Status: Active » Needs review
smustgrave’s picture

Status: Needs review » Needs work

Could the issue summary be updated to the standard template please.

avpaderno’s picture

Issue summary: View changes
Status: Needs work » Needs review

I apologize: I was not able to retrieve this issue.

smustgrave’s picture

Status: Needs review » Reviewed & tested by the community

Much appreciated @avpaderno believe the change is good.

  • catch committed 94d42a07 on 10.4.x
    Issue #973772 by drupal_was_my_past, avpaderno, joachim, tstoeckler,...

  • catch committed 353e737c on 11.x
    Issue #973772 by drupal_was_my_past, avpaderno, joachim, tstoeckler,...
catch’s picture

Version: 11.x-dev » 10.4.x-dev
Status: Reviewed & tested by the community » Fixed
Issue tags: +string change in 10.4.0

Committed/pushed to 11.x and cherry-picked to 10.4.x, thanks!

Status: Fixed » Closed (fixed)

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