In drupal core’s drupal.js file. In the Drupal.formatString() function which is used by the Drupal.t() function. The issue is that if I’m adding the same placeholder in the t() function twice, than only the first occurrence will be replaced. This is because the Drupal.formatStrint() uses regular expressions to replace the placeholders, but the global flag is not set on the RegEx.

E.g.
Drupal.t(‘Click this link: <a href="@link">@link</a>', {'@link': 'https://www.drupal.org/'})
will have the output html output like this:
Click this link: <a href="https://www.drupal.org/“>@link</a>

All this is happening only in JS. If I would create this translation in PHP with the t() function, than I’ll get the expected output:
Click this link: <a href="https://www.drupal.org/“>https://www.drupal.org/</a>

So the two translate function doesn’t work the same in JS as in PHP.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

arpadCsanyi’s picture

This patch modifies the regular expression used for replacing the placeholders by adding the /g flag to it.

I'm creating a RegExp object as adding flags in the String.prototype.replace() function should be avoided (see on this page at the parameter's description: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global...).
I think it is more straightforward to use the RegExp object then concatenating the parts to a regular expression.

David_Rothstein’s picture

Status: Active » Closed (duplicate)

I think this should be fixed by #2182265: Drupal.t() placeholder substitution doesn't always work correctly (backport part of the Javascript file translation fixes from Drupal 8) - I will edit that issue and give it a better title now.

Testing/reviews of the patch there are definitely needed. It wound up being a bit more complicated than yours, I believe because it's also trying to address the issue where you have two variables that start with the same text (e.g. @link and @link_two). But if it's possible to simplify, that would be good to know.