Skip to content

Localization & Translations

jejacks0n edited this page Nov 19, 2011 · 1 revision

To enable the I18n features, please refer to the configuration. It's outlined in basic terms there, and will give some clarity to this article.

The I18n system in Mercury is fairly simplistic but flexible, and can be broken down into four basic aspects.

  1. Locale Files
  2. Detecting the Locale
  3. Javascript Helpers
  4. HTML String Replacement

Locale Files

The locale files are about as basic as could be expected. The only aspect to be aware of is that regional dialects are nested within the top level language object. Here's a basic example for the foo language, with a regional dialect for BAR (note the underscores in the _BAR_ property):

Mercury.I18n['foo'] = {
  "original string with %d %s.": "translated string with %d whole %s."
  "original string": "translated string"
  _BAR_: {
    "original string with %d %s.": "translated string with %d dang %s."
  }
}

Detecting the Locale

The first time a string is translated Mercury attempts to detect what language the client (browser) has set. If a matching locale file has been included it will be used, but if one isn't found the configured preferredLocale will be used (if set). This is assigned in the configuration and can be anything. In the default configuration swedish_chef-BORK is used as an example -- with swedish_chef being the language, and BORK being the regional dialect (eg. US if using en-US).

Examples:

A user with their language set to es-MX will use the es.locale file, and if a MX regional dialect has been specified in that file, they'll get the MX regional specific translations, with a fallback to the standard es translation if a regional one isn't found. In this way you can create regional overrides without having to provide a translation for everything else.

A user with sk (an unsupported locale) will fall back to the default english strings if there isn't a preferredLocale set. But if the preferredLocal is configured to es-MX, it would behave as though their browser was set to es-MX.

Javascript Helpers

Use the Mercury.I18n helper function to get a translated string. The I18n implementation supports some basic sprintf functionality, so if you need to put variables into your string, do so by using %s, %d, or %f. This is a very basic sprintf implementation, so these are the only interpretations that are handled currently.

Mercury.I18n('original string with %d %s.', 2.5, 'variables') => 'translated string with 2 whole variables.'

Here's a locale line that would match the previous example:

"original string with %d %s.": "translated string with %d whole %s."

If you need to do your own translation logic for some reason, use Mercury.locale() to get the translation object. This object contains a top and sub property. sub should be checked first as it represents the regional dialect that has been selected, then the top -- which represents the primary language.

HTML String Replacement

To keep translation code / variations to a minimum we've taken the approach of finding strings in the html and replacing them if a translation was found. This isn't the most performant way we could've done it, but it's the least intrusive and easiest to manage on a quickly moving project, so keep this in mind -- it should be used sparingly if you care about performance.

The code to do this is a modified version of the jQuery localize plugin. It's been optimized a bit, and adjusted to handle more cases (at minimum the ones we have in the core library). To translate any HTML content use:

jQuery(element).localize(Mercury.locale())

This is the method that's used currently when loading content into a modal, dialog, panel etc. This means that you can use any language you want for your Mercury views, but if you want it to be supported in multiple locales you'll need to add translations to the locale files you wish to have support for.

It's worth noting that content that spans elements is not translated unless done properly. Translation looks for the exact content (eg. trimmed) within any given element. So <span>this is some <em>content</em></span> will not be translated if you're using "this is some content" as your source string. You would need to create two source strings in the locale file, one for "this is some", and one for "content".