Please note, this is a STATIC archive of website developer.mozilla.org from 03 Nov 2016, cach3.com does not collect or store any user information, there is no "phishing" involved.

How to enable locale switching in a XULRunner application

This article is for developers who have localised their XUL application using DTD entity files and want to provide their users with a mechanism to switch the locale in the application itself. Normally the application locale is inherited from the OS environment of the host system, however there are situations when you might want to give users the option to override the default setting and choose a different locale.

Here is an outline of the solution:

1. Modify the application preferences

First, you need to tell XULRunner that your application wishes to ignore the default OS locale and that it will do its own choosing instead. Edit the application preferences file and set "intl.locale.matchOS" to false. Your application is now going to ignore the OS locale, so it would be a good idea to define one to fall back on using the preference "general.useragent.locale".

defaults/preferences/prefs.js

/* Don't inherit OS locale */
pref("intl.locale.matchOS", "false");

/* Choose own fallback locale; later it can be overridden by the user */
pref("general.useragent.locale", "en-GB");

 

Note that some distributions of XULRunner or Firefox don't honour the "intl.locale.matchOS" setting, so in those cases you won't be able to override the OS locale [Debian Iceweasel bug #417961].

2. Include a XUL control for the locale selection

The next step is to add a XUL control to your application which lists the available locales in the package and makes it possible for the user to select one of them. I chose a listbox with a button.

 LocaleSwitchDemo.01.jpg 
Screenshot of sample locale switching control

3. Populate the XUL control with the available locales

The available package locales are declared in the chrome manifest.

Sample chrome/chrome.manifest

content   localeswitchdemo		content/
locale    localeswitchdemo	de-DE	locale/de-DE/
locale    localeswitchdemo	en-GB	locale/en-GB/
locale    localeswitchdemo	fr-FR	locale/fr-FR/

How are you going to populate the XUL listbox?

You can hardwire the choices into the XUL code using fixed list items, or could take the elegant approach and construct the list dynamically.

The dynamic list population requires an XPCOM to query the currently selected locale as well as all locales available in the application package. Here is a code snippet showing how this is done:

The definition of the XUL control:

<listbox id="locale-listbox">
  <!-- generated list items go in here -->
</listbox>

<button label="&switchLocale.button;" oncommand="changeLocale()"/>

The Javascript code to populate the control:

try {
	// Query available and selected locales
	
	var chromeRegService = Components.classes["@mozilla.org/chrome/chrome-registry;1"].getService();
	var xulChromeReg = chromeRegService.QueryInterface(Components.interfaces.nsIXULChromeRegistry);
	var toolkitChromeReg = chromeRegService.QueryInterface(Components.interfaces.nsIToolkitChromeRegistry);
		
	var selectedLocale = xulChromeReg.getSelectedLocale("localeswitchdemo");
	var availableLocales = toolkitChromeReg.getLocalesForPackage("localeswitchdemo");
		
		
	// Render locale menulist by iterating through the query result from getLocalesForPackage()
	const XUL_NS = "https://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
		
	var localeListbox = document.getElementById("locale-listbox");
		
	var selectedItem = null;
	
	while(availableLocales.hasMore()) {
			
		var locale = availableLocales.getNext();
			
		var listitem = document.createElementNS(XUL_NS, "listitem");
		listitem.setAttribute("value", locale);
		listitem.setAttribute("label", locale);
			
		if (locale == selectedLocale) {
			// Is this the current locale?
			selectedItem = listitem;
		}
			
		localeListbox.appendChild(listitem);
	}
		
	// Highlight current locale
	localeListbox.selectedItem = selectedItem;
		
} catch (err) {

	alert (err);
		
}

 4. Code to update the locale user preference and restart the application

Mozilla XULRunner doesn't allow runtime switching of the locale, therefore the application must be restarted to activate the new choice.

Here is an example event handler which is fired when the user clicks on the button to change the locale. It saves the new locale to the user application preferences (thereby overriding the default prefs.js above) and then asks XULRunner to restart.

function changeLocale() {

	try {
		// Which locale did the user select?
		var localeListbox = document.getElementById("locale-listbox");
		var newLocale = localeListbox.selectedItem.value;
		
		// Write preferred locale to local user config
		var prefs = Components.classes["@mozilla.org/preferences-service;1"].
                    getService(Components.interfaces.nsIPrefBranch);
		prefs.setCharPref("general.useragent.locale", newLocale);
		
		// Restart application
		var appStartup = Components.classes["@mozilla.org/toolkit/app-startup;1"]
                     .getService(Components.interfaces.nsIAppStartup);

		appStartup.quit(Components.interfaces.nsIAppStartup.eRestart |
         		        Components.interfaces.nsIAppStartup.eAttemptQuit);
		
	} catch(err) {
	
		alert("Couldn't change locale: " + err);
	}
}

 * * *

Here I include a complete XULRunner application example that demonstrates the locale switching. The code snippets above were taken from it.

LocaleSwitchExample.zip (7KB, tested with XULRunner 1.9.0 for Linux)

Document Tags and Contributors

Tags: 
 Contributors to this page: teoli, vladimir.dzhuvinov
 Last updated by: vladimir.dzhuvinov,