Crowley Code! 
 (Take 12)

Bugfix for nsIStringBundle 2007/08/08

XULRunner provides a nice way to localize apps through the use of custom document-type declarations (*.dtd files) and *.properties files used from within your Javascripts (more info on ).  The markup below brings one of these "string bundles" into the app:

<stringbundleset>
	<stringbundle id="locale" src="chrome://app/locale/main.properties" />
</stringbundleset>

Then just one line of Javascript brings it from the XUL world into the Javascript world.  The string bundle element itself contains methods getString and getFormattedString that will bring localized content into your Javascript.

var locale = document.getElementById('locale');
locale.getString('foo');
locale.getFormattedString('bar', [asdf, qwerty]);

But getFormattedString doesn't work right in XULRunner 1.9a7.  It substitutes only the first character of the string (in my experience).  Here is a transparent Javascript-only fix:

var locale = document.getElementById('locale');

// Now hack locale.getFormattedString to work like it should
locale.getFormattedString = function(id, args) {
	var str = locale.getString(id);
	var ii = args.length;
	for (var i = 0; i < ii; ++i) {
		var regex = new RegExp('%' + (i + 1) + '\$[ds]');
		str = str.replace(regex, args[i]);
	}
	return str;
};

This properly takes care of the replacement of each element in args.  In the example above where the variables asdf and qwerty were passed, the contents of asdf would replace %1$s and the contents of qwerty would replace %2$s.  Note the numbering of the placeholders differing from normal array indexing.  Also note that for semantic reasons, a d can be used in the placeholder to denote a number, but no special case is necessary in Javascript.  Happy localizing!

Comments (3)

  1. Searched for a fix with a problem I had with getFormattedString and this post. Thanks for the idea. If I may, I would suggesst adding the 'g' and 'i' flags in your instantiation of the RegExp as well as escaping the '$' sign:

    var locale = document.getElementById('locale');

    // Now hack locale.getFormattedString to work like it should locale.getFormattedString = function(id, args) { var str = locale.getString(id); var ii = args.length; for (var i = 0; i

    Bruno — 2007/10/12 10:06 am

  2. ..  comment body appears to have been cut, here's the line in question : var regex = new RegExp('%' + (i + 1) + '\\$[ds]','gi');

    Bruno — 2007/10/12 10:08 am

  3. This bug fix isn't necessary if you use %S (uppercase S) in the localized string.  This is documented in http://developer.mozilla.org/en/docs/XUL:Method:getFormattedString

    Alex — 2007/11/06 3:29 pm

Richard Crowley?  Kentuckian engineer who cooks and eats in between bicycling and beering.

I blog mostly about programming and databases.  Browse by month or tag.

To blame for...


© 2009 Richard Crowley.  Managed by Bashpress.