This is a demo that will localize your application using jQuery's Globalize and CanJS's views.
The end result is a localization that updates the string's itself when the culture
changes. The culture
will change when the user selects a different language from a menu ( example not shown ).
*NOTE: You will need to setup your app for jQuery Globalize and include the files it requires in order for this demo to work correctly.
We create a can.Construct
to serve as a wrapped for our localization calls and hold onto the culture
via a can.Observe
.
can.Construct('app.Locale',{
init:function(){
// extend app.Locale to have SOME of the Gloablize functions
$.each(['findClosestCulture','addCultureInfo','localize','parseFloat','parseDate'],function(i,func){
app.Locale[func] = function(){
return Globalize[func].apply(Globalize, arguments);
};
});
// override 'attr' on the culture to set the global
var old = this.culture.attr;
this.culture.attr = function(attr, val){
if(val){
Globalize.culture(val);
}
return old.apply(this, arguments);
};
},
culture: new can.Observe({
value: undefined
})
}, {});
window.lz = function(key){
return Globalize.localize(key)
};
Add a EJS Helper...
can.EJS.Helpers.prototype.alz = function(key){
if(mj.Locale.culture.attr('value')) {
return window.lz(key);
}
};
Set the locale on the document ready before you have fetched any EJS'es...
app.Locale.culture.attr('value', 'en-US');
and your usage looks like this in the EJS file...
<div class="face"><%== alz('app.face') %></div>
can.EJS will automatically update itself when can.Observes change. In our helper we created above, we tell the view to listen for changes to the culture
attribute change.
At render time, EJS adds hooks to everything wrapped inside this function to re-render upon change that way later on when we update the culture
object by doing something like:
app.Locale.culture.attr('value', 'fr-FR');
the content wrapped inside the block, is refreshed passing the new locale to the lz
function to get the new string.
This only works for strings in EJS files that are placed inside DOM objects. For example:
<button title="<%== alz('%lbl.monkey') %>"></button>
will NOT work. This is because it needs a actual DOM parent to add its hooks. Also, if you try to use this in a controller like so:
init:function(){
this.element.html(alz('app.face'));
}
it will NOT work either since its not going to get the hooks EJS would automatically do.