Subscribe to RSS Feed

I have already mentioned a few times that we'll take a look at how to properly localize our extension. Even if the process is nothing new for experienced extension programmers, I think it should be part of this tutorial.

First of all, let's extend our directory structure. We'll need a new place where to put localized strings.

helloworld@janodvarko.cz/
    chrome/
        content/
            helloworld/
                helloWorld.xul
                helloWorld.js
        locale/
            en-US/
                helloWorld.dtd
                helloWorld.properties
    defaults/
        preferences/
            prefs.js
    chrome.manifest
    install.rdf

There are two new files: helloWorld.dtd contains entities that are used to localize strings contained in XUL files and helloWorld.properies is used to localize strings in JavaScript code.

To let Firefox know about these files, we need to modify our chrome.manifest file and append following line to it.

locale  helloworld  en-US       chrome/locale/en-US/

Localizing strings in XUL files

All strings in our helloWorld.xul are localized using helloWorld.dtd locale file. This DTD file contains list of entities with corresponding localized strings. In our extension we have to localize just a toolbar button. So, we need two following entities defined in it.

<!ENTITY  helloworld.mybutton.label         "Say Hello">
<!ENTITY  helloworld.mybutton.tooltip       "Push to say hello">

In order to use these entities within the helloWorld.xul file we have to create a reference to the locale file.

<!DOCTYPE helloworldDTD SYSTEM "chrome://helloworld/locale/helloWorld.dtd">

Sometimes you need to reference multiple DTDs from single XUL file. Here is an article that explains how to do it.

Now, we have to replace the strings by the entities that comes from the locale file. Following source code shows how the toolbar button definition looks after the replacement (see label and tooltiptext attributes).

<toolbarbutton id="hwMyButton"
    class="toolbar-text-button"
    label="&amp;helloworld.mybutton.label;"
    tooltiptext="&amp;helloworld.mybutton.tooltip;"
    command="cmd_hwMyButton"/>

Localizing strings in JavaScript code

There is also a few strings in our JavaScript code that must be localized as well. We'll do it by using a standard string bundle that gets the strings from helloWorld.properties file (see more about property files). This file contains following set of strings (name=value pairs).

helloworld.option1=Option1
helloworld.option2=Option2
helloworld.paneltitle=Hello World!
helloworld.message=Hello World!

Now, when we have the property file ready, we need to create a string bundle. There are two ways how this can be done. We can use nsIStringBundleService and read the property file in JavaScript.

var src="chrome://helloworld/locale/helloWorld.properties";
var localeService =
    Components.classes["@mozilla.org/intl/nslocaleservice;1"]
    .getService(Components.interfaces.nsILocaleService);
var appLocale = localeService.GetApplicationLocale();
var stringBundleService =
    Components.classes["@mozilla.org/intl/stringbundle;1"]
    .getService(Components.interfaces.nsIStringBundleService);
var bundle = stringBundleService.CreateBundle(src, appLocale);

See chapter 11. Localization from Creating Application with Mozilla book for more information about string bundles.

The other way is to define the bundle in helloWorld.xul, using stringbundleset and stringbundle elements. This method is simpler and used in our extension.

<stringbundleset id="stringbundleset">
    <stringbundle id="strings_helloWorld"
        src="chrome://helloworld/locale/helloWorld.properties"/>

</stringbundleset>

As soon as the string bundle is ready we have to make sure the JavaScript code loads every string from it instead of using just literal strings. In order to make things a bit easier we'll define two helper functions that load a given string from the string bundle and returns its localized value.

function $HW_STR(name)
{
    return document.getElementById("strings_helloWorld").getString(name);
}

function $HW_STRF(name, args)
{
    return document.getElementById("strings_helloWorld")
        .getFormattedString(name, args);
}

Following source code shows how the $HW_STR method is used to localize Options menu items defined in the previous part.

getOptionsMenuItems: function(context)
{
    return [
        this.optionMenu($HW_STR("helloworld.option1"),
            "helloworld.option1"),
        "-",
        this.optionMenu($HW_STR("helloworld.option2"),
            "helloworld.option2")
    ];
}

If you need to put some dynamic values into the localized string use the $HW_STRF method. This method takes an extra parameter - array of arguments, which are substituted into the string in the bundle. See the following example how to use it.

Here is a localized string with placeholders where dynamic data should be inserted:

helloworld.formattedstring=Here is a value: %S and here is another: %S.

And here is the piece of JavaScript that loads the string:

var localizedString = $HW_STRF("helloworld.formattedstring",
    ["value 1", "value 2"]);

If you are interested in more details how to properly localize Firefox extensions, read this article.

Example extension (helloworld-0.0.4.xpi) can be downloaded here.


Rss Commenti

3 Comments

  1. Is these code right?
    label="&helloworld.mybutton.label;"
    tooltiptext="&helloworld.mybutton.tooltip;"

    I modify and get success.
    label="&helloworld.mybutton.label;"
    tooltiptext="&helloworld.mybutton.tooltip;"

    Anyway, Thank you for your really good articles.

    #1 Steve Yu
  2. Yeah, fixed, thanks!
    I really have to install better WP plugin that doesn't convert "&" to the "&amp ;" entity.

    #2 admin
  3. [...] recorded first by MariAssmann on 2009-04-09→ Extending Firebug, localization (part IV.) [...]

    #3 Recent URLs tagged Localization - Urlrecorder

Sorry, the comment form is closed at this time.