en
de

Localizing Single Page Applications

2 July 2013
| |
Reading time: 5 minutes

The mobile revolution and HTML5 brought a new paradigm into web application engineering. The classic presentation layer of eg. JEE web applications gets more and more replaced by a data centric service layer providing REST services for so called Single Page Applications (SPAs). This way native mobile apps and HTML5 applications can use the very same server infrastructure.

This shift now asks for alternative approaches in nearly every angle of client side web applications. This holds for localization as well. Localization or short l10n usually has been done in the presentation layer by a server-side web framework. When the user switches to another language, the browser requests the page again and the server delivers the nicely localized HTML document to be rendered by the browser.

With Single Page Applications this is no longer feasible. The users state is held in the browser’s memory and is lost when the document location changes. Moreover SPAs often render HTML markup with a client side template engine. Obviously a client side localization solution must be found. A homebrew solution often meets basic needs but when apps get bigger and more advanced a sophisticated localization is needed.

webl10n – a localization library

Since a while I’m observing the Mozilla community more closely. A by-product of Mozillas FirefoxOS endeavour is a bunch of Mozilla-driven libraries and tools to create FirefoxOS applications. Because FirefoxOS applications are usual HTML/CSS/JavaScript applications, most of these libraries can be used for all kind of web applications. The webL10n library is a such an example. It has been developed by Fabien Cazenave, a member of the FirefoxOS dev team mostly working on the GAIA UI.

webL10n provides a advanced solution of the localization problem on the client side. According to the the author it’s designed to be simple and is “heavily optimized performance wise”. And further: “The webL10n format is compatible with the ‘*.properties’ standard that is used by a lot of Mozilla/Google/Java projects, and it relies on existing Unicode tools such as CLDR to handle pluralization rules.”

Sounds to be quite a nice choice for solving localization in my little FirefoxOS app PwdMan, which I created for and at the FirefoxOS App Day Switzerland. It’s a very simple password manager made on top of mortar app templates which is another contribution of the FirefoxOS community.

Using web10ln

Including the webL10n.js file into your document is enough to make your app locale aware:

<script type="text/javascript" src="l10n.js"></script>

As usual you should place the script tag at the very end of the body element to not block the browser’s rendering. Once loaded webL10n does its work. It scanns the DOM for declared data attributes data-l10n-id:

<div class="field password">
  <label data-l10n-id="form-label-password"></label>
  <input data-l10n-id="form-input-password" type="password"
         placeholder="" />
  <button data-l10n-id="button-save"></button>
</div>

webl10n checks the browser language at page load and picks the appropriate strings from the language files. The language file can simply linked into the document by adding a link tag in the document head:

<link href="lang.ini" rel="resource" type="application/l10n" />

The language file has an ini-file syntax. Here’s the file for the sample markup above in english, german, the swiss-german region and rumantsch grischun:

[en]
button-save=Save
form-label-password=Password
form-input-password.placeholder=your password

[de]
button-save=Speichern
form-label-password=Passwort
form-input-password.placeholder=dein Passwort

[de-CH]
button-save=Späicherä
form-label-password=Passwort
form-input-password.placeholder=dis Passwort

[rm]
button-save=Memorisar
form-label-password=Pled-clav
form-input-password.placeholder=Pled-clav

That’s all. Dot-notation can be used to target attributes of elements. Once in place you can just add further l10n-attributes to your markup and add the key/value entry in the language files.

Cool – but I generate markup after page load

A Single Page Application often generates markup on the client side. So there must be a way to translate markup after the page has initially loaded. The JavaScript API of webL10n allows accessing localization functionality programmaticaly. A property webL10n is added to the global document variable to provide the programming interface:

// provides the string in the current language.
var welcome = document.webL10n.get("welcome");
// sugar
var l10n = document.webL10n.get;
// now shorter
prompt(l10n("go-to-line"), 42);

Changing the current language makes webL10n re-translate the entire document:

document.webL10n.setLanguage("de-CH");

According to the project README setLanguage sets the language code in ISO-639-1 format. I tried it with regions also (de-CH) and it worked.

Partial DOM translation

Client side template engines become more and more popular. After the creation of a DOM fragment by using the DOM API directly or a template engine, translation can be applied selectively on parts of the DOM:

// create DOM element (usually by template engine)
var header = document.createElement("h2");
header.setAttribute("data-l10n-id", "caption-address");
header.id = "caption-address";
// append to document
document.body.appendChild(header);
// translate
document.webL10n.translate(header);

The result in the DOM inspector as expected:

<h2 id="caption-address"
    data-l10n-id="caption-address">
  Your addresses
</h2>

Being notified!

After the initial translation or a language switch a localized event is thrown. An event listener can be registered to link further post-processing to the translation process:

window.addEventListener('localized', function() {
   var htmlEl = document.documentElement,
       l10n = document.webL10n;

   htmlEl.lang = l10n.getLanguage();
   htmlEl.dir = l10n.getDirection();
   htmlEl.classList.add(l10n.getLanguage());
}, false);

The sample above simply sets the language and text-direction attribute of the html element and adds the language as a style class. An simple way to enable CSS selectors to target specific languages. Some languages for example vary significantly in the length of words and expressions. English is a ‘short’ language while french is a ‘long’ one. Having the language accessible in CSS selectors to adjust the styling might help here.

My choice

For my simple example Password Manager app, using webL10n worked very well. No hassle so far. There are further features I haven’t used by now. Such as support for pluralization which is a handy feature for many applications. As a swiss developer it’s sure that I require a localization library for a future project. webL10n will quite likely be my choice. As announced by the author it was very easy to use and fullfilled my needs in a SPA very well.

Comments (5)

×

Sign up for our Updates

Sign up now for our updates.

This field is required
This field is required
This field is required

I'm interested in:

Select at least one category
You were signed up successfully.

Receive regular updates from our blog

Subscribe

Or would you like to discuss a potential project with us? Contact us »