Skip to content

Instantly share code, notes, and snippets.

@amcdnl
Created September 24, 2012 16:44
Show Gist options
  • Save amcdnl/3776930 to your computer and use it in GitHub Desktop.
Save amcdnl/3776930 to your computer and use it in GitHub Desktop.
Localizing EJSes with CanJS

Localization with EJS and CanJS

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.

The Code

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>

How does this work?

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.

Caveats

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment