This document describes all features offered by RAIN client runtime for interacting with localization.
Client Language Runtime methods work by default with the current selected language. Some methods allow an optional “language” parameter that will be used instead of the current language if defined.
Imagine we do an ajax request and based on some conditions when we receive an http error status code we want to display a friendly localized message.
Imagine we have a list of help messages and depending on the language we want to display some of them or all. We may want to declare a “help” complex key like this: help={key:msg1} {key:msg2} {key:msg3}, where msg1, msg2, msg3 are other keys. This way we can achieve a composition of translations.
In this scenario we must be careful when passing parameters to the complex translation key, so that every “inline” key receives the exact number of parameters that it requires.
Imagine a fragment that is displayed within an aggregator. The aggregator contains a dropdown that allows users to change the language. In this case each fragment from the aggregator should reload the translations. Moreover, when moving to the next aggregator, the selected language should be the one changed in the previous aggregator.
Imagine we create an application which contains multiple views. From a developer perspective, we add some text which might be changed over time. Without inline editing, the developer becomes responsible for changing the text. For additional information about this read Client Language Inline Editing.
After RAIN parser finished parsing the document and the markup is completed rendered the following data structure is used for holding translations (available on client side):
1 2 3 4 5 6 7 8 9 | {translations : {
"id1" : {
"en_US" : 'localized text - en version',
"de_DE" : 'localized text - de version'
},
"id2" : {
"en_US" : 'localized text - en version'
}
}}
|
The client side controller holds a reference to this structure in viewContext object.
Change language operation publishes an event at page level that can be handled by each module individually.
<html>
<head>
<link rel="stylesheet" href="rain specific url for consolidated css" />
<script type="text/javascript" src="js/require-jquery.js"></script>
<script type="text/javascript">
require(["js/test_controller.js"], function(module) {
..... contexts specific code come here
module.init(viewContext);
});
</script>
</head>
<body>
<div id="module5" class="module1">
<div class="fragment1" id="fragment1">
<img id="img1" alt="Default de_DE" src="de_DE_img.jpg" />
<p id="p1"></p>
</div>
</div>
</body>
</html>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | define(function() {
function init(viewContext) {
var languageRuntime = this.clientRuntime.clientLanguageRuntime;
var messaging = this.clientRuntime.messaging;
var parentDiv = $("#" + this.viewContext.getInstanceId());
// obtain paragraph innerText using client runtime.
messaging.subscribe("languageChanged", function(data) {
var pText = languageRuntime.getKeyValue("id1");
parentDiv.find("#p1").html(pText);
});
}
return {init : init};
});
|
It would be nice that RAIN provides a default behavior for handling “languageChanged” event. For this to work we need to have access to all client side controllers from page. Then each view might override this behavior by subscribing to “languageChanged” event.
When displaying information about images, audios or videos (media elements) we have multiple attributes for these tags. The simpler way is to add different translation keys for each attribute. For an image we may need to following attributes: src, alt, width, height; a video has sources and poster attributes. Changing all these attributes (or adding new ones that are not initially known) for a media element might require developer involvement.
We can improve this update translations process by defining a new type of keys: media keys. We will associate a key with a media tag and generate the element attributes on the fly based on the list of attributes contained in the translation object. The translation of the key will be a JSON object with keys being the attributes names.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | {translations : {
"id2" : {
"en_US" : {
"type" : 'image',
"src" : 'url to img source - en version',
"alt" : 'alternative localized text - en version',
"width" : '32',
"height" : '32'
},
"de_DE" : {
"type" : 'image',
"src" : 'url to img source - de version',
"alt" : 'alternative localized text - de version'
}
},
"id3" : {
"en_US" : {
"type" : 'video',
"src" : 'url to video source - en version',
"poster" : 'url to poster image - en version',
"width" : '32',
"height" : '32',
"sources" : [
{
"src" : 'url to video source 1 - en version',
"type" : 'video/mp4'
},
{
"src" : 'url to video source 2 - en version',
"type" : 'video/ogg'
}
]
}
}
}}
|
<html>
<head>
<link rel="stylesheet" href="rain specific url for consolidated css" />
<script type="text/javascript" src="js/require-jquery.js'></script>
<script type="text/javascript">
require(["js/test_controller.js"], function(module) {
..... contexts specific code come here
module.init(viewContext);
});
</script>
</head>
<body>
<div id="module5" class="module1">
<div class="fragment1" id="fragment1">
<img id="img1" alt="Default de_DE" src="img_de_de.jpg" />
</div>
</div>
</body>
</html>
1 2 3 4 5 6 7 8 9 10 11 12 13 | define(function() {
function init(viewContext) {
var languageRuntime = this.clientRuntime.clientLanguageRuntime;
var parentDiv = $("#" + this.viewContext.getInstanceId());
// obtain paragraph innerText using client runtime.
var imgObj = languageRuntime.getMediaKeyValue("id2");
parentDiv.find("#img1").attr("src", imgObj.src);
parentDiv.find("#img1").attr("alt", imgObj.alt);
}
return {init : init};
});
|