You are currently viewing a snapshot of www.mozilla.org taken on April 21, 2008. Most of this content is highly out of date (some pages haven't been updated since the project began in 1998) and exists for historical purposes only. If there are any pages on this archive site that you think should be added back to www.mozilla.org, please file a bug.



Writing Global Customization Friendly Code

Tao Cheng


Goals

Why it is important to write localization (l10n), customization, and internationalization (i18n) friendly code:
  • Enablement. No need to modify XUL, CSS, or even C++ code. Localization/customization could be done in the language packs, "langenus.xpi", or content packs, "regus.xpi". 
  • Cost effectiveness. Translators deal with (key, value) pairs in the *.dtd or *.properties. No markup language or programming language discipline is required.
  • Content or language switching, installation, and upgrade. Language and content packs are plugable and all we need to produce a localized/customized build.
  • Less QA concern. Since modified resources are de-coupled from the program's logic and binary, errors are restrained to the GUI and more discoverable.
  • Less error-prone. Fixed format files (key, value) are less prone to human errors.

Non-goals

Introduction of XUL technology: the assumption is the audience has a basic grasp of C++, Javascript, and markup language coding experience.

Localization and Customization

What is localization and customization and how do we enable them in Mozilla?
  • Localization: translation or customization of the UI resources to fit local or regional culture.

    • Mozilla UI is built on top of XUL technology which is an application of XML. To facilitate localization, we externalize all localizable resources to the external subset of Document Type Definition (DTD). Translators and localizers localize the Browser by translating the entity values in DTD, e.g., "navigator.dtd", without understanding XUL syntax.
    • In C++/JavaScript code, strings or resources are stored as (key, value) pairs in Java property files, e.g, "navigator.properties". XPCOM objects, nsIStringBundleService and nsIStringBundle, are used to retrieve them.
    • Layout of menus, forms, or dialog are localizable. For example, the Search menus and the NewCard dialog of Addressbook . For such UI, we often employ XUL Overlay for implementation.
    • During localization, only DTD, property, and RDF files are sent to translators who work on the (key, value) pairs.

  • Customization: similar to localization but emphasize on UI modification. Sample customizations:

    • add a menuitem to "Help" menu.
    • add Sidebar tab.
    • modify throbber icon and url.
    • remove Net2phone from Personal toolbar, Tasks menu, and Preferences dialog.

Writing Localizable/Customizable code

  1. What are localizable/customizable resources?

    • Text, strings that are visible to end users. Such resources should live in one of the jar files in langenus.xpi.
      • good: in en-US.jar, or en-{mac, unix, win}.jar
      • bad: hard coded string in XUL, JavaScript, C++ code, etc., so that localization has to be performed outside of language packs.

    • Web links (URLs), e.g., " http://www.foo.com "  point to remote Web sites. For examples, the URL associated with "Home" button, "N" logo button, ads banner, etc.
      • good: in US.jar.
      • bad: hardwired in XUL or in langenus.xpi.

    • Geometry (width, height, resizability, etc) settings of UI (pull down menu, dialog, etc). Translation (Asian, German, etc.) might cause the width (and/or height) of the strings to grow. To prevent text from being truncated after translation, please make them localizable.
      • good: externalize to *.dtd (or *.properties)
      • bad: hardcoded in .xul , .css, or C++/ JavaScript code.

    • Language, culture specific image.  Images and icons that contain (English) texts are hard to localize. Bad example:
      • Image "My" in MyNetscape.
      • Bold , Italic button icons in the Composer (or Editor's) Formatting toolbar.
      • SpellChecker button icon, " abc ", in the Composer (or Editor's) toolbar.

    • Temperature units (Fahrenheit v.s. Centigrade)
      • bad: assume the measurement unit is Fahrenheit.
      • good: clearly mark the measurement unit and make them localizable.

    • Mailing address format. Mailing address format differs from country to country. There is no unified addressing format across the world. The user interface design needs to take the locality into consideration and leave room for localization adjustment. For example,
      • In the United States, most of mailing addresses contain fields in the following order: :"Street address", "City", "State", "Zip Code", and "Country".
      • However, in the Asia, the mailing address starts with "Country", and then "Province", "County", "City", etc.

    • Measurement Unit: Metric v.s. English system.

  2. How to make them Localizable/Customizable. Recommended methods are provided for the following types of source files. (See details here: " XUL Coding Style Guidelines ".)

    1. XUL: use XML DTD (*.dtd)

      • always use chrome URLs,  : chrome://navigator/content/foo.xul , to reference chrome files needed in Mozilla.
      • externalize localizable resources into *.dtd: chrome://navigator/ locale/foo.dtd

        Example: in EdColorPicker.xul you declare the location of the external DTD subset that text entities are defined: and then reference the entity by

        <!DOCTYPE window SYSTEM "chrome://editor/locale/EdColorPicker.dtd"

         69     <button id="LastPickedButton" crop="right" oncommand="SelectLastPickedColor();">
        70 <spacer id="LastPickedColor"
        71 LastTextColor="" LastBackgroundColor=""
        72 persist="LastTextColor LastBackgroundColor"/>
        73 <label value="&lastPickedColor.label;" flex="1" style="text-align: center;"/>
        74 </button>
        In DTD, EdColorPicker.dtd , the entity is defined as

        <!ENTITY lastPickedColor.label "Last-picked color">

      • key v.s. value: (hierarchical naming convention)
        • <!ENTITY openFileCmd.label "Open File...">
          <!ENTITY openFileCmd.accesskey "o">
          <!ENTITY openFileCmd.commandkey "o">

    2. C++/JavaScript: use String Resource Manager, (nsIStringBundleService and nsIStringBundle), to externalize runtime resources such as

      • error messages:
        • alert.txt =Connection to server, "home.foo.com", failed.
        • alert.url = http://support.foo.com/
      • progress strings: downloading %1 out of %2
      • preference strings/value: browser.startup.homepage= http://home.netscape.com  
      • For XUL and JavaScript example:

        In navigator.xul you declare string resource bundles needed:
         85   <!-- hook for stringbundle overlays -->
        86 <stringbundleset id="stringbundleset">
        87 <stringbundle id="bundle_navigator" src="chrome://navigator/locale/navigator.properties"/>
        88 <stringbundle id="bundle_brand" src="chrome://global/locale/brand.properties"/>
        89 <stringbundle id="bundle_navigator_region" src="chrome://navigator-region/locale/region.properties"/>
        90 <stringbundle id="bundle_brand_region" src="chrome://global-region/locale/region.properties"/>
        91 <stringbundle id="findBundle" src="chrome://global/locale/finddialog.properties"/>
        92 </stringbundleset>

        Then, in navigator.js, you retrieve them to access the bundled (key, value) pairs via getString{Name,ID}()

        257 function Startup()
        258 {
        259 // init globals
        260 gNavigatorBundle = document.getElementById("bundle_navigator");
        261 gBrandBundle = document.getElementById("bundle_brand");
        ... }

        783 function BrowserOpenFileWindow()
        784 {
        785 // Get filepicker component.
        786 try {
        787 const nsIFilePicker = Components.interfaces.nsIFilePicker;
        788 var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
        789 fp.init(window, gNavigatorBundle.getString("openFile"), nsIFilePicker.modeOpen);
        790 ...
        ...
        ...
        796 }
        797 }

  3. Separation of regional content (US.jar) from UI language (en-US.jar): to speed up the deployment of localized builds varied by regions such as English (US), English (Canada), and English (GB), the regional content files are stored in a different jar from en-US.jar. Vendors can distribute localized contents without localized the UI language portion which often requires much more time and resources allocation. The following two sub-sections list what type of localizable resources belong to UI language v.s. regional contents and where they should be stored.

    1. UI language: all non-regional specific localizable resources should live in "langenus.xpi". This includes

      • Non-platform specific resources (strings, text, etc.) visible to end users should live in " en-US.jar". A sample crome url is "chrome://navigator/locale/foo.dtd"
      • All Platform-specific files or dynamic overlay should live in "en-{mac, unix, win}.jar". A sample url is  "chrome://foo-platform/locale/foo.dtd" . The installer script (packaged in langenus.xpi) contains the logic of choosing which jar to install for a particular platform. The goal of separating platform-specific resources fromen-US.jar is to make langenus.xpi portable across platforms. Examples of platform-specifc resources are
        • Default charset settings. For Japanese browser, the default charset for UNIX browser is "EUC-JP", while it should be "Shift-JIS" for Windows browser.
        • key bindings: "Ctrl + N", v.s. "Cmd + N"
        • mouse wheel: Windows and Linux only
        • Print Dialog: Unix only

    2. Regional contents: region/country specific resources should live in regus.xpi. There are two types of regional resources

      • Locale provider of chrome: regional contents (URLs). Any region-sensitive resources referenced by chrome urls, e.g., "chrome://navigator-region/locale/region.dtd" , should live in "US.jar". Such resources are switchable within the same profile.
        • urls associated with menu items
          • region.dtd
          • region.properties:
          • builtinURLs.rdf - for runtime urls of N logo, helpMenu, etc.
        • customizable/localizable UI
          • "Search" menu (starting from 4rd menuitem): searchMenu.rdf
          • "Print Plus" menu: communicatorOverlay.rdf
          • personal toolbar buttons: "Home", "My Netscape", "Search", "Shop", and "Net2Phone".
        • others?

      • Profile defaults (bin/{defaults,searchplugins}). These are copied into newly created profiles and then modified during user session. Note that profile data are not switchable once they are copied to the profile. For example, in the client install folder, sub-folder, "defaults" contains the following directories and sub-directories:

        • "isp/ US/{aol.rdf,nswebmail.rdf}" - these are referenced in "New Mail/News Account Setup Wizard"
        • "messenger/ US/Template" - this is the default message template.
        • "profile/ US"
          • bookmarks.html
          • default-invite.rdf - used in AIM
          • default-messages.rdf - used inAIM
          • localstore.rdf - used to control chrome related UI settings
          • mimeTypes.rdf - referenced by Helper Applications
          • panels.rdf - default sidebar panels
          • search.rdf - control which search engine to use.

  4. CSS - no UI strings in CSS, please. Use DTD or property files instead.

    1. Font setting: font settings affecting the global UI strings should go to "chrome://global/locale/intl.css."
    2. no UI strings in CSS, please. Use DTD or property files instead. For example,
      • HTML form button labels: submit, ok, etc.
      • CSS decorated dialog button labels.

Localization Freeze Guidelines

Michele Carlson 9/12/01

Purpose:
The localization UI freeze date has been put into place so that it is possible for us to ship localized product simultaneously with the US product. This means that on the date that the public sees a new Netscape browser on the market, they will see it in several languages. If the localization UI freeze date is not respected, the localized products are at risk of not shipping simultaneously with the US product. This would create a loss in many users around the world. UI changes made after the freeze will cause re-translation and re-building of the localized products. The localization team must send new strings out for translation and wait for the files to come back. What impact does this have on localized products?

  • It increases the cost of translation and jeopardizes the ability to control the translation budget
  • It increases the workload of the localization engineers. Re-translation results in another round of integration and builds.
  • It increases the QA workload. Each re-translation introduces another round of QA cycle testing.
  • It lengthens the time to market often making it impossible to ship simultaneously.
Goal:
It is important that we make our product available in as many markets as possible outside the US simultaneously with the US product. This effort makes us a globally recognized brand. We are working hard to be a truly international company. This is just one of the many things that we do to make ourselves an internationally recognized company with users around the world.

Definition:
Respecting the localization UI freeze date means the following to engineers:

  • No user visible strings changes should be made, including adding, deleting, or modifying the strings in the files.
  • No graphic images files should be changed if the images contain text.
  • No moving strings from one place to another, one file to another, or from one jar/xpi file to another.
  • No content changes, including URLs, menus, buttons, search engines, or plugins.
  • No changes to strings including changing words, spaces, commas, colons, etc. Or changing anything that appears in the user interface within a string.
What can an engineer change after the localization UI freeze date without affecting localization?
Engineers can continue to make bug fixes to the core code in any other area outside the UI. If your fix does not effect the UI, then engineers can make it without affecting localization.

Timeline:
It is important to put into place localization UI freeze dates for both Beta and RTM releases. Specific localization UI freeze dates should be put into the master schedule. Owners of the schedule will be responsible for coordinating localization UI freeze dates with mcarlson to assure that the dates meet the guidelines described. If owners are unsure of the size of the release, mcarlson's team can provide size estimates based on word counts.

When there is a need for Mozilla developers to observe localization freeze, the staff of Mozilla.org will communicate the timeline with Mozilla developers.

Exceptions:
Exceptions to the localization UI freeze dates will be reviewed on a case by case basis. All requests for exceptions should be sent to the Netscape localization engineering team manager mcarlson@netscape.com for approval.