I recently got a question asking, to greatly simplify, if it is possible to dynamically load and update localized strings. The answer is yes, and you can find my original response here. However, instead of leaving the response buried away as a comment within another post, I figured I’d make part of the answer its own post.

For most people who work with SproutCore, you will likely add localized strings to your application by doing the following:

SC.stringsFor(“en”, {
  “_hello”: “hello”

It's pretty easy to do, but just exactly how does this work? What is SproutCore doing when you call SC.stringsFor and then later retrieve a localized string by calling the loc method on a string? To answer this, you need to look at SproutCore’s foundation sub-framework. In the foundation framework there are two files to be aware of: the string.js mixin file and the locale.js file. Let’s first look at the locale.js file.

In the locale.js file you will find the SC.Locale class. SC.Locale is what actually stores all of those localized strings. Each language gets its own SC.Locale object. The strings themselves are added to the SC.Locale’s strings hash property. When the SC.stringsFor is called, the method will fetch the locale object for the given language and add the strings to that locale by calling the addStrings method. You can find this code at the bottom of the locale.js file and below (as of version 1.4.3):

SC.stringsFor = function(languageCode, strings) {
  // get the locale, creating one if needed.
  var locale = SC.Locale.localeClassFor(languageCode);
  locale.addStrings(strings) ;
  return this ;
} ;

Now let’s go check out the string.js mixin file.

In the string.js file, a SC.String mixin is defined that gets mixed into the actual JavaScript string object. The mixin contains a lot of convenience methods, but the method that does the localization is, of course, loc. If you look at how loc is implemented, you’ll notice that it makes use of SC.Locale and calls the locale’s createCurrentLocale method to return the appropriate locale object:

loc: function() {
  if(!SC.Locale.currentLocale) SC.Locale.createCurrentLocale();
  var str = SC.Locale.currentLocale.locWithDefault(this);
  if (SC.typeOf(str) !== SC.T_STRING) str = this;
  return str.fmt.apply(str,arguments) ;

Taking a closer look at the code, SC.Locale's createCurrentLocale method makes use of two properties that you can assign on the class: useAutodetectedLanguage and preferredLanguage. So if you want to just let SproutCore handle language detection, simply set the useAutodetectedLanguage to true. If you have a language that you want to be used, then set the preferredLanguage property.

With this knowledge, you now have more control over how SproutCore handles string localization. Just be aware that if you do dynamically update the localized strings, you'll have to also update the views that make use of them.