A nice feature of SproutCore is the ability to easily localize strings in your application. As an example, I can create a strings.js file that contains the following:


SC.stringsFor("en", {
  "_hello": 'Hello',
  "_world": 'World'
});

So now instead of hard-coding English text into my application’s code, I can instead do something like the following:


helloButton: SC.ButtonView.design({
  layout: { bottom: 0, left: 0, height: 25, width: 100 },
  title: '_hello'.loc()
}),
      
worldButton: SC.ButtonView.design({
  layout: { bottom: 0, right: 0, height: 25, width: 100 },
  title: '_world'.loc()
})

All we had to do is make use of the string localize method loc() that the SproutCore framework automatically adds to the JavaScript String object. Now if I want to internationalize my application to, say, work in French, I just have to create another string file that contains the following:


SC.stringsFor("fr", {
  "_hello": 'Bonjour',
  "_world": 'Monde'
});

And with that I don’t have to touch the strings in the rest of my application’s code. (Note that the use of the underscore character prefixed to each of the localized string keys is just a convention.)

Handling individual words works fine, but what about sentences? For instance, if I were to say in English “today is Monday“, in French it would be “Nous sommes lundi aujourd’hui”. Notice the difference in the English and French grammatical representation. Well, it turns out we can also use SproutCore’s localization feature as a sentence factory by making use of SproutCore’s format (fmt) string feature. The approach we use is to templatize the localized strings.

Let’s update our English strings.js file to handle the case “Today is <day>” where <day> is any day of the week (e.g. Monday, Tuesday, etc). Our string file is now the following:


SC.stringsFor("en", {
  "_Monday": "Monday",
  "_Tuesday": "Tuesday",
  "_Wednesday": "Wednesday",
  "_Thursday": "Thursday",
  "_Friday": "Friday",
  "_Saturday": "Saturday",
  "_Sunday": "Sunday",

 "_today is": "Today is %@"
});

Notice the localize string key “_today is” and how its value contains the %@ sequence that SproutCore’s fmt format method recognizes. Now we could do the following in our application:


var weekday = new Array(7);
weekday[0] = "_Sunday".loc();
weekday[1] = "_Monday".loc();
weekday[2] = "_Tuesday".loc();
weekday[3] = "_Wednesday".loc();
weekday[4] = "_Thursday".loc();
weekday[5] = "_Friday".loc();
weekday[6] = "_Saturday".loc();

var todayIsTemplate = "_today is".loc();

var date = new Date();
var todayIsString = todayIsTemplate.fmt(weekday[date.getDay()]);

We also made use of localization not just for our “_today is” template but also for the day of the week. First we translate the day of the week, then we insert the day into the template via the fmt string method. Really simple and it keeps our application’s code clean.

Since we’ve done English, let’s go ahead and create the French string file:


SC.stringsFor("fr", {
  "_Monday": "lundi",
  "_Tuesday": "mardi",
  "_Wednesday": "mercredi",
  "_Thursday": "jeudi",
  "_Friday": "vendredi",
  "_Saturday": "samedi",
  "_Sunday": "dimanche",

 "_today is": "Nous sommes %@ aujourd'hui"
});

Peace of cake. Your localized string templates can be as complex as the sentences you want to make. Just keep in mind the position of where the place holders in the string templates are. If you have a string template that takes more than one input, those inputs could be reordered depending on the language you’re working with.

Remember that SproutCore’s string localization feature is something worth taking advantage of even if you don’t intend to internalize your application. Just for the sake of cleaner code it becomes handy.

-FC

Update (Feb 9, 2010):

(1) If you’d like to know how to start your SproutCore application to use the different languages, refer to my comment in this post. Thanks to Macario for the original question.

(2) I failed to point out that you can pass in arguments to the loc() method so that it will automatically do formatting on the string. So instead of:

todayIsTemplate.fmt(weekday[date.getDay()])

you can make life even easier and do the following:

"_today is".loc(weekday[date.getDay()])
Advertisements