10

So I'm trying to use the Drupal.t() function in some of my custom Javascript code (in my theme).

How do I get the strings I need populated in the Drupal.locale.strings object? I see some strings in there, but of course the entire database can't be loaded. What's the best way to add to it? I would like to use the PHP t() function so that the strings added can be edited in the Translate interface.

8

Drupal handles populating the needing strings into the javascript object. Much like the entire collection of strings isn't loaded on every page, only the needed strings are added to the JavaScript.

I believe this is done by traversing the script files before they are actually added to the page.

So if you add Drupal.t('Some string'); to your JavaScript code, you should be able to translate that in the translate interface.

| improve this answer | |
  • Well then it ain't happening. (the traversal of the script for find the Drupal.t() calls). I'm adding the script via the theme's .info file (scripts[] = scripts/script.js). Maybe I have to add via drupal_add_js() ? – JonMcL Feb 2 '12 at 23:14
  • You are correct. I had to trace through to fully get an understanding, but it does indeed happen automagically. In Drupal 7, the function is locale_js_alter() (in locale.module). It uses the full list of Javascript files and parses each one in _locale_parse_js_file(). Be careful to make sure that file_get_contents() can load your JS file with the path provided (i.e. don't start your path with a / if it's in your theme folder). You can use drupal_add_js or the scripts[] setting in your theme's .info file. Of course, make sure to clear caches and translate the string! :) – JonMcL Feb 3 '12 at 15:14
6

Just ran into this same issue today and researched it a bit more. Chris above has a good comment, but it's ultimately incorrect. You do not need to use Drupal.behaviors for it to work.

As noted by JonMcL himself in his last comment, the function _locale_parse_js_file in locale.inc is responsible for the parsing of Drupal.t("somestring") patterns starting from row 1493 (in Drupal 7.22):

preg_match_all('~
[^\w]Drupal\s*\.\s*t\s*                       # match "Drupal.t" with whitespace
\(\s*                                         # match "(" argument list start
(' . LOCALE_JS_STRING . ')\s*                 # capture string argument
(?:,\s*' . LOCALE_JS_OBJECT . '\s*            # optionally capture str args
  (?:,\s*' . LOCALE_JS_OBJECT_CONTEXT . '\s*) # optionally capture context
?)?                                           # close optional args
[,\)]                                         # match ")" or "," to finish
~sx', $file, $t_matches);

It's just a "dumb" parsing function that doesn't care about semantics and simply finds all instances of Drupal.t("something") in any file it receives.

What could be a common gotcha is that you need to have the whole string in your source code in the Drupal.t("translateme") form, because (obviously) no javascript gets executed when the file is opened through file_get_contents in php. That means you can never do Drupal.t(somevariable) and hope Drupal will catch all string-containing javascript variables that you throw at Drupal.t.

If you want to translate "women" for a chart and give the string a context, the syntax would be:

Drupal.t("women", {}, {context: "charts"}

Also, if you have drush installed, verify your js file is parsed with the command;

drush vget javascript_parsed

Then you can clean your cache with

drush cc all

... and repeat the vget command above to verify the list of already parsed files is empty. This way your file will get reparsed next run (verify that too).

| improve this answer | |
  • 1
    Thanks for drush vget javascript_parsed! A quicker way to force rebuild translations script files is by just removing CSS and JS files using drush @sitealias cc css-js. – lmeurs Jul 11 '14 at 13:46
0

Couple gotchas I've run into while implementing multilingual JS in Drupal 7:

  1. First, make sure your JS file is not being included inline. As of Drupal 7.22, Drupal.locale.strings doesn't seem to automatically update itself if you're inlining JavaScript files in Drupal. The translation interface still picked up the string anyway, adding to my confusion.

  2. Second, make sure you're using Drupal.behaviors to attach your JS to the page. Regular JS closures will not trigger Drupal's "magic" parsing of Drupal.t() invocations. This is technically something you should be doing anyway ;)

From there it really is pretty painless. Just use Drupal.t() around text you want translated, clear your cache each time you update the file, and your translators should see the new string in the interface at /admin/config/regional/translate/translate. It's quite nice once you get it working.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.