Using Javascript and “i18n” for Multi-language / Multi-country Drupal Websites
Internationalization, or “i18n” for short (because there are 18 characters between the “i” and the “n” in that lengthy word), is the process of designing a web application so that it can be adapted to various languages and world regions. CivicActions has had an opportunity to work on some localization projects using Drupal and i18n in recent years. We've learned a lot and want to share some of our tips about using Javascript for string translation.
1. Loading up our JavaScript in a way that strings will be translatable:
The most flexible way to do this is with drupal_add_js()1. You don’t want to manually add script tags to the page template, or you could find that your JavaScript strings will not be translatable with Drupal.t() -- see section below.Use your template.php to load the JavaScript files if you want any kind of conditionality. For example you might want to load just some files onto just some pages. This way you can limit what you load to what you need.
In Drupal 6:
function saladtheme_preprocess_page(&$vars, $hook) { $current_url = drupal_get_path_alias($_GET["q"]); $theme_path = drupal_get_path('theme', 'saladtheme'); if (strpos($current_url, ‘articles/tomatosalad’)) { drupal_add_js($theme_path .”/js/lettuce.js”, "theme"); } }
And in Drupal 7:
function saladtheme_preprocess_html(&$variables, $hook) { $current_url = drupal_get_path_alias($_GET["q"]); $theme_path = drupal_get_path('theme', 'saladtheme'); if (strpos($current_url, ‘articles/tomatosalad’)) { drupal_add_js($theme_path .”/js/lettuce.js”); }}
Consider the order in which you load the JS files, as the files loaded first will appear first in the HTML head section2.
2. Drupal.t()
Now that we have our JS files loaded up correctly, we might might want to translate some of the strings that they contain. If you add Drupal’s t() function to a php page, you can have the text translated into multiple languages, with each new text entry stored in the database, via a call to locale(); if the string has already been translated, then the translated version is returned.In the case of Drupal.t(), from misc/drupal.js: Drupal.t() does not add the strings to the DB. What it does do is replace, on the page, any previously translated strings, which can be found in the JavaScript object (Drupal.locale.strings), in a Drupal generated file (in the files directory, under directory languages, with the name of the current language).But how does the JavaScript located string get inserted in the DB in the first place? Well, it begins with drupal_add_js(). Each time a JS file is added with drupal_add_js(), its filepath is added to a static array called $javascript. When drupal_get_js() builds up the JavaScript HTML output, it also calls locale_update_js_files(), which loads the complete $javascript array by an empty call to drupal_add_js(NULL, NULL, NULL). _locale_parse_js_file() parses each of the files in the filepaths stored in $javascript and adds the new translatable strings to the DB, much like locale() does when t() calls it.As with t(), we can use replacement values in Drupal.t(). This page shows a clear example.On the other hand, one noticeable difference between t() and Drupal.t() is that Drupal.t() does not insert the run time value of variables into the database, which is something you can do with t(). We might add t($dynamic_variable); we can use variables when necessary, but it’s something to avoid in the case of user specified content (as Gábor Hojtsy points out here). My hunch is that php variables don’t work with Drupal.t(), and locale_parse_js_file(), because the file is parsed as plain text. There are work-arounds, however, such as using nodes to store the translations, and thus avoiding the use of Drupal.t().We hope this helps you to get a better handle on using translatable strings in JavaScript. We’re always learning more and would be curious to hear from others using Javascript for string translation.
Footnotes:1. If the JS file is loaded on every page, you can just use: scripts[] = js/script.js, in your mytheme.info2. Drupal 7 allows you to set the weight in drupal_add_js(), which could come in useful if JS files, are getting loaded from other locations, such as modules.
Topics