User Tools

Site Tools


developer_center:articles:add-on_locale_support

Add-on Locale Support

Why your extension needs locale support

In case you haven't noticed, Nightingale is not just available in English - it's available for an ever-increasing number of languages and localizations. Imagine international users' reactions to seeing a fully localized application only to have random English strings from your add-on mingling with their native language interface!

If you are new to extension creation, you're probably wondering how you can possibly support every language with your add-on. Thankfully, the Gecko engine provides some magic: Nightingale will automatically detect what language your add-on should display based on the user's application settings. If the target language is not provided by your add-on, then it will fall back to English (en-US) as the default.

You can structure your add-on such that it will be considerably easier for other translation and localization experts to localize for you. All you simply have to do is build in the locale support.

A simple solution for a simple user interface

It's often the case that the number of strings to be used in your extension is just a list of simple common words, such as:

Home
Edit
Cancel
Title
Artist
Tags
Download
Please wait...

Or they may be longer strings that already appear in elsewhere in Nightingale interfaces such as:

Copy music files with the following extensions to the device: Check for Updates… Select destination folder:

In that case, the simplest solution is to extract the localizable entities from the Nightingale application itself.

See in this file for a list of all the strings you can extract and notice the mapping they have to entity names in this file.

  • The first step to localization is to insert the following doctype line at the top of your XUL file:
<!DOCTYPE window SYSTEM "chrome://songbird/locale/songbird.dtd" >

As you can see, this is the address of a locale file inside the Nightingale chrome, and it will automatically switch to the needed locale language of the Nightingale user.

  • Now use these entity names in your XUL instead of the English strings, and you are all done! The translation in every available language will be displayed in the user's locale.

Important note : the entity name in the XUL must be in the following format:

&entity.name;
  • Here is a simple example:

If you have:

<toolbarbutton  id="overlayToolbar"
                 class="toolbarbutton-1 chromeclass-toolbar-additional"
                 label="Play/Pause"
                 oncommand="onPlayPauseOverlayToolbar();"/>
</toolbarpalette>

You can see that the Play/Pause string is already in the application interface as:

<!ENTITY menu.control.play "Play/Pause" >

So you can go ahead and use this entity in your XUL:

<toolbarbutton  id="overlayToolbar"
                 class="toolbarbutton-1 chromeclass-toolbar-additional"
                 label="&menu.control.play;"
                 oncommand="onPlayPauseOverlayToolbar();"/>
</toolbarpalette>

Create a locale structure

Of course, generally, your add-on will have more strings than the Nightingale application can provide by default, so the above solution will be insufficient for these strings. For this case, you need to create a full dedicated locale structure:

All you have to do is to add a locale folder in the chrome at the same level as content and skin. Inside the locale folder, create one subfolder per supported language.

Image:Locale-structure.png FIXME

Consolidate user interface strings into one location

To make it easier to localise, we want to take those embedded strings out of the XUL and put them into a central file in the locale subfolder we just created. So we need to substitute in an entity for these embedded strings.

Spot strings in the XUL files

Here is a sample of code of what a XUL file looks like with embedded user interface strings (green highlighted) Image:Strings_in_xul.png FIXME

Create entities

- Remember from above, the syntax for an entity in a XUL file is:

&entity.name; 

Each unique string must have a unique entity name. So in general, non-repeating strings should be uniquely named. If you are using the same literal string in multiple places, then reusing the entity name is fine.

Here is the same XUL code, but with the embedded English strings represented by entities.

Image:Entities_in_xul.png FIXME

Move the strings to the locale/*.dtd file

Now we need to move the embedded strings we just took out and place them into a locale-specific .dtd file. The syntax for an entity line in a .dtd file is:

<!ENTITY entity.name "String for user interface">

So for our example, our strings will move into a .dtd file that looks like:

Image:Strings_in_dtd.png FIXME

Very important note: The encoding for .dtd files MUST be UTF-8

Add a doctype line

In order to get the add-on to look for locale strings in our locale subfolder, we have to ensure we set the correct doctype at the top of every XUL file.

Example:

<!DOCTYPE overlay SYSTEM "chrome://timer/locale/timer.dtd" >

As you can see, we point it to the path to the locale file related to this specific XUL file (good practice is to choose same filename for both, e.g about.xul –> about.dtd )

The doctype “definition” depends of the kind of XUL file you have. It can be: overlay - dialog - window

Properties for .js files

Of course, add-ons are more than just XUL. You may have some strings embedded in your .js files, and if they will be displayed to your user at any point, then they should be localised too. There are two methods to localize these kinds of strings, both based on the principle that there is a list of strings (otherwise known as a stringbundle) in the locale folder, which the Javascript file will fetch its variables from.

Create a stringbundle in the xul

Here is the kind of strings we want to localize in our Javascript :

function showTags(){alert("You may use the following tags in your titles...\n");

Let's suppose you have a XUL file with the path to a script in a .js file including strings.

You can insert these three lines in the XUL file:

<stringbundleset id="stringbundleset">
<stringbundle id="extname-strings"
  src="chrome://extname/locale/extname.properties"/>
</stringbundleset>

This creates a stringbundle with an id and points it to the path to the locale's .properties file.

What this means is that in the Javascript .js file, you can now use:

function showTags(){alert(document.getElementById('extname-strings').getString("YouMayUse"));

and place the following in your locale/*.properties file: YouMayUse=You may use the following tags in your titles…\n

Create a stringbundle at the top of the .js

Another solution is to not modify your .XUL file and instead place the stringbundle at the top of the .js file.

  • Insert this line:
var gBundle = components.classes["@mozilla.org/intl/stringbundle;1"].getService(Components.interfaces.nsIStringBundleService);
  • Then choose a variable name to define the stringbundle and its path:
var strings = gBundle.createBundle("chrome://extname/locale/extname.properties");
  • Now you can define variables for your string like so:
var youmayuse = strings.GetStringFromName("YouMayUse");
function showTags(){alert(youmayuse);

Register the locales in the chrome manifest

One more mandatory step is to register your locales in your add-on's chrome manifest (chrome.manifest file), otherwise the add-on will not even know the locales exist! In your chrome.manifest file, you already have lines to provide paths for content, skin, and overlay:

content songbird-mashtape chrome/content/
skin songbird-mashtape classic/1.0 chrome/skin/
overlay windowtype:Songbird:Library chrome://songbird-mashtape/content/overlayLibrary.xul

All you have to do is add the path for all the included locale the same way (don't forget the trailing slash!)

locale songbird-mashtape en-US chrome/locale/en-US/
locale songbird-mashtape fr-FR chrome/locale/fr-FR/

A handy alternative: The Externalize extension

If you feel all the above steps are too long and annoying, or you're just lazy - learn how to use the magical “Externalize” extension (originally written for Firefox by Davide Ficano).

It will make the whole process semi-automatic, thus saving you precious time.

This extension is now available for Nightingale here FIXME

You can have a look at this 10-step HOWTO guide on the BabelWiki page

Tutorials/References

Other BabelZilla tutorials that might be helpful to you:

Want more languages and localizations for your add-on?

- You are welcome to hop on BabelZilla and submit your extension. BabelZilla is a community of volunteer translators from all over the world, dedicated to the translation of extensions for Moz family apps.

developer_center/articles/add-on_locale_support.txt · Last modified: 2013/06/17 07:22 by geekshadow