Diff for /books/www/chapters/ch11.html between versions 1.7 and 1.8

version 1.7, 2002/12/04 06:07:15 version 1.8, 2002/12/11 18:57:10
Line 1 Line 1
<HTML>    <style type="text/css">
<HEAD><TITLE>Chapter 11</TITLE></HEAD><BODY BGCOLOR=WHITE><H2>Chapter 11</H2>      div.c24 {font-weight: bold; text-align: center}
<H1><A NAME="77028"></A> Localization</H1>      div.c23 {text-align: center}
<P>This chapter describes how to use Mozilla's internationalization (I18N) and localization (L10N) technologies to make applications usable by people around the world. Because the Mozilla community (and the Internet community in general), is global, it is vital to be able to cross language barriers by localizing your application and making it available to a wider audience.    </style>
<P>In this chapter, you are given step-by-step instructions on how to change the visible text for your application in the XUL interface and how to handle nonstatic strings that arise from dynamic string handling in other areas of your application code.
<P>While the basic technologies that are used are not new, Mozilla is innovating in areas such as Unicode support and quick access language pack installs. The information in this chapter about the internationalization (<I><A HREF="http://www.mozilla.org/projects/intl/index.html">http://www.mozilla.org/projects/intl/index.html</A></I>) and localization (<I><A HREF="http://www.mozilla.org/projects/l10n/mlp.html">http://www.mozilla.org/projects/l10n/mlp.html</A></I>) projects will give you a solid foundation for what is possible in your own application.    <h2>Chapter 11</h2>
<H2><A NAME="77029"></A> Localization Basics</H2>    <h1><a name="77028"></a> Localization</h1>
<P>Before learning how to  <!--INDEX internationalization:(see also localization)[internationalization:zz(see also localization)] -->  <!--INDEX localization:(see also internationalization)[localization:zz(see also internationalization)] -->  <!--INDEX localization:overview -->  <!--INDEX internationalization:overview --> localize your Mozilla application, it's useful to run through some of the high-level goals and features of the Mozilla internationalization and localization projects. First, here are some definitions:    <p>This chapter describes how to use Mozilla's
<DL><DT>Internationalization (I18N)    internationalization (I18N) and localization (L10N)
<DD>The design  <!--INDEX I18N (see internationalization) --> and development of software to function in a particular locale. The shorthand term, I18N, refers to the 18 letters between the initial "i" and final "n."<P>    technologies to make applications usable by people around the
<DT>Localization (L10N)    world. Because the Mozilla community (and the Internet
<DD>The  <!--INDEX L10N (see localization) --> modification of software to meet the language of a location and the adaptation of resources, such as the user interface (UI) and documentation, for that region. L10N is an acronym for localization and refers to the 10 letters between the initial "l" and final "n."<P>    community in general), is global, it is vital to be able to
<DT>Locale    cross language barriers by localizing your application and
<DD>"A set of conventions  <!--INDEX locales --> affected or determined by human language and customs, as defined within a particular geo-political region. These conventions include (but are not necessarily limited to) the written language, formats for dates, numbers and currency, sorting orders, etc.," according to the official Mozilla document found at <I><A HREF="http://www.mozilla.org/docs/refList/i18n/">http://www.mozilla.org/docs/refList/i18n/</A></I>.<P></DL>    making it available to a wider audience.</p>
<P>Locale in the context of this chapter is related specifically to the display of text in the user interface. The focus will be on UI localization of XUL files and strings contained in JavaScript and C++ files, as well as the methods employed for localization.    <p>In this chapter, you are given step-by-step instructions on
<P>Here are some main features of the Mozilla internationalization capabilities, which are relevant to the user front end application level:    how to change the visible text for your application in the XUL
<UL><P><LI>Mozilla is Unicode-enabled for Latin-based languages, Cyrillic, Greek, Chinese, Japanese, and Korean. Mozilla widgets and HTML rendering can support the input and display of these languages. Unicode-enabling for other languages and character sets is an ongoing process.<P>    interface and how to handle nonstatic strings that arise from
<P><LI>Mozilla can be easily localized into different languages, even if not supported by the underlying operating system.<P>    dynamic string handling in other areas of your application
<P><LI>Most Mozilla localization work involves translating strings as entities in Document Type Definition (DTD) format and properties file format (an idea taken from Java), which are based on open standards.<P>    code.</p>
<P><LI>Localization can be done once and run on Windows, Macintosh, Unix, and other platforms-something we have come to expect from the Mozilla framework. This is a great time saver, and indeed a cost saver if you come at it from that perspective.<P>    <p>While the basic technologies that are used are not new,
<P><LI>Mozilla supports BIDI, the display and input of text in a bidirectional format for such languages as Arabic and Hebrew, yet the capabilities for this in the UI were not mature when we were writing this book.<P>    Mozilla is innovating in areas such as Unicode support and
<P><LI>The UI locale DTD files use UTF-8 as the default encoding for translated items. Mozilla then maps to Unicode or non-Unicode fonts, depending on which platform you're running on or what fonts you installed in your system. You are encouraged to encode your DTD files as UTF-8 when possible.<P></UL>    quick access language pack installs. The information in this
<P>Recalling the architecture of the XPFE toolkit described in <A HREF="ch02.html#77048">Chapter 2</A>, the locale component can be easily plugged     chapter about the internationalization (<i><a href=
in and out of the application that you are working on without impacting any other components. This functionality is ideal, for instance, for people with linguistic skills and less experience with technical issues to become involved in a Mozilla-related project.    "http://www.mozilla.org/projects/intl/index.html">http://www.mozilla.org/projects/intl/index.html</a></i>)
<H3><A NAME="77030"></A> For the Developer</H3>    and localization (<i><a href=
<P>Many available  <!--INDEX localization:resources -->  <!--INDEX resources:localization --> resources show you how to help localize an existing application into a specific language or to find out how to add localization support to your own application. <!--INDEX newsgroups, localization -->  <!--INDEX development:localization resources -->    "http://www.mozilla.org/projects/l10n/mlp.html">http://www.mozilla.org/projects/l10n/mlp.html</a></i>)
<P>The Mozilla Localization Project hosts various localization teams and provides help whenever possible. The Mozilla community includes a discussion group that uses many languages to discuss Mozilla development issues. The <I>netscape.public.mozilla.l10n</I> and <I>netscape.public.mozilla.i18n</I> newsgroups are a great place to discuss these issues with other developers.    projects will give you a solid foundation for what is possible
<P>When developing an application, some words and phrases that developers like to hear (according to the Mozilla organization, at <I><A HREF="http://www.mozilla.org/projects/l10n/xul-l10n.html">http://www.mozilla.org/projects/l10n/xul-l10n.html</A></I>) are: standards compliant, simple, leveragable, portable, extensible, separable, consistent, dynamic, valid, parser friendly, invisible (part of the XUL authoring process), and efficient. The following sections will help you understand how these terms and goals impact the chosen technologies and how to use those technologies. The ultimate aim is to help you localize your application easily.    in your own application.</p>
<H3><A NAME="77031"></A> Files and File Formats</H3>    <h2><a name="77029"></a> Localization Basics</h2>
<P>Here are the  <!--INDEX localization:file types -->  <!--INDEX files:localization file types --> main file types you'll see when learning about locale and that you will use when localizing your Mozilla application. A good home for all of these resources is in the <I>locale</I> area of the application <I>chrome</I>.    <p>Before learning how to 
<DL><DT>DTD (<I>.dtd</I>)    <!--INDEX internationalization:(see also localization)[internationalization:zz(see also localization)] -->
<DD>Files containing entities that host the strings from XUL content files.<P>    <!--INDEX localization:(see also internationalization)[localization:zz(see also internationalization)] -->
<DT>Property (<I>.properties</I>) or string bundles    <!--INDEX localization:overview --> 
<DD>Files containing strings that are accessed by JavaScript, C++, and possibly other scripting or component files.<P>    <!--INDEX internationalization:overview --> localize your
<DT>RDF    Mozilla application, it's useful to run through some of the
<DD>RDF files are described in XML syntax, so use entities.<P>    high-level goals and features of the Mozilla
<DT>HTML and text    internationalization and localization projects. First, here are
<DD>Suitable for long text, HTML and XML documents and other content that needs to be localized.<P></DL>    some definitions:</p>
<P>The next two sections will help you start localizing your application. The sections focus on DTD files and string bundles, which are the core formats for XUL-localizable content. Before getting started, here is a review of some general principles that might help you design and implement the locale component.    <dl>
<H3><A NAME="77032"></A> UI Aesthetics and Principles</H3>      <dt>Internationalization (I18N)</dt>
<P>To put locale in context, this section looks at some issues you may encounter when localizing your Mozilla application. Some are universal principles and others are unique to the environment. This reference is by no means exhaustive, but it contains some scenarios and tips the authors came across in their experience with locale in Mozilla.      <dd>The design <!--INDEX I18N (see internationalization) -->
<H4><A NAME="77033"></A> Space management</H4>      and development of software to function in a particular
<P>One of the  <!--INDEX localization:UI aesthetics, space management -->  <!--INDEX user interface:localization:space management -->  <!--INDEX design issues, user interfaces:localization and space management --> guiding principles in UI design is for your interface to not get too crowded. Although estimates are not specific, it is wise to leave about 30 percent expansion space in your window and dialogs. To achieve this flexibility, you have to ensure that the XUL window has ample space in the first place for all the widgets to fit.      locale. The shorthand term, I18N, refers to the 18 letters
<P>More specifically, the application needs to have space for widgets to expand or contract without detracting from the overall look and feel.       between the initial "i" and final "n."</dd>
Intuitive use of the XUL box model (refer to <A HREF="ch03.html#77084">Chapter 3</A> for more information) and correct choice of widgets goes a long way in achieving this goal.      <dt>Localization (L10N)</dt>
<P>The factors that can cause this space to be filled include using languages/character sets that are more verbose than the one that was there originally, and the users changing their font size settings. Some safeguards that have been built into Mozilla already handle this problem. Much of it is done in CSS, but other methods are available. The section "Language Quirks," later in this chapter, outlines one of these methods.      <dd>The <!--INDEX L10N (see localization) --> modification of
<H4><A NAME="77034"></A> Help system</H4>      software to meet the language of a location and the
<P>If you  <!--INDEX help system, localization and -->  <!--INDEX localization:help system -->  <!--INDEX user interface:localization:help system --> choose to integrate a Help system into your application, a localizable resource will be most content. Opinions differ within technical writing circles, but having screenshots in your documents is generally not considered advantageous. For example, they can get out of date easily in the constantly evolving world of software, or they need to be retaken frequently when new features are added to the UI.      adaptation of resources, such as the user interface (UI) and
<H4><A NAME="77035"></A> Tooltips</H4>      documentation, for that region. L10N is an acronym for
<P>Tooltips  <!--INDEX tooltips:localization and -->  <!--INDEX localization:tooltips -->  <!--INDEX user interface:localization:tooltips --> are a sometimes overlooked yet valuable way of relaying information to the user. They can be used as an alternative to a help system if you are looking for something simpler. They can also expand an explanation of something that was annotated in the UI text. Sometimes text can have multiple meanings in context, and expanding it with a tooltip can clear up any confusion. In an editor or multifile browser, for example, you might have a find button. A tooltip can clear up the confusion about whether the results of the action searches in the current file or in all files.      localization and refers to the 10 letters between the initial
<P>Most XUL widgets support tooltips. Implementation is as straightforward as adding a <TT>tooltip</TT> attribute to the widget with an associated value. For it to be localizable, it must be in the form of a DTD entity.      "l" and final "n."</dd>
<PRE>&lt;tab id="config" label="&amp;config.label;" tooltip="&amp;config.tooltip;" /&gt;</PRE>      <dt>Locale</dt>
<P>The <A HREF="#77040">"Inserting Entities</A>" section, later in this chapter, provides more information on the rationale for using entities and how to insert them into XUL content.      <dd>"A set of conventions <!--INDEX locales --> affected or
<H4><A NAME="77036"></A> Grammar</H4>      determined by human language and customs, as defined within a
<P>In any user <!--INDEX grammar, localization and -->  <!--INDEX localization:user interface:grammar considerations -->  <!--INDEX user interface:localization:grammar considerations -->  interface, there is limited screen space. When possible, however, provide complete or near-complete sentences. These sentences are better than using text based on phrases or acronyms. They provide meaning to the translator and clearer instructions to the user.      particular geo-political region. These conventions include
<H4><A NAME="77037"></A> Commenting</H4>      (but are not necessarily limited to) the written language,
<P>Commenting  <!--INDEX comments:localization and -->  <!--INDEX localization:user interface:commenting -->  <!--INDEX user interface:localization:commenting --> was mentioned before, but is worth stressing again. The translators may have not even seen the software that you are working on, but you hope that is not the case! Commenting is very useful for giving context and flagging strings that should not be commented. You can comment your HTML, XML, or DTD files by wrapping it in a <TT>&lt;!-- comment --&gt;</TT> block.      formats for dates, numbers and currency, sorting orders,
<PRE>&lt;!--NOTE to Translators: Do NOT change the next string --&gt;      etc.," according to the official Mozilla document found at
&lt;!ENTITY appName.label "My Application"&gt;</PRE>      <i><a href=
<P>Note that a bundle file uses the <TT>#</TT> notation at the beginning of each line to signify a comment.      "http://www.mozilla.org/docs/refList/i18n/">http://www.mozilla.org/docs/refList/i18n/</a></i>.</dd>
<PRE># This text is used in the view menu for launching the page choices dialog    </dl>
pageChoices=Go To...</PRE>    <p>Locale in the context of this chapter is related
<H4><A NAME="77038"></A> Web resources</H4>    specifically to the display of text in the user interface. The
<P>Localizable <!--INDEX web resources, localization and -->  <!--INDEX localization:user interface:web resources -->  <!--INDEX user interface:localization:web resources -->  resources are not only strings of text that need to be translated into different languages; they are any variable information that is liable to change over the lifetime of your application. The handling of URLs is a case in point. You may have references interspersed throughout your UI that point to web resources. These references can be explicit listings or widgets that, once activated, launch a client to bring you to a certain location.    focus will be on UI localization of XUL files and strings
<P>Images are another resource commonly used in documentation. A tutorial on your application may have screenshots of the UI in action. If you do use images, keep an eye out for localizable content in them.    contained in JavaScript and C++ files, as well as the methods
<H2><A NAME="77039"></A> DTD Entities</H2>    employed for localization.</p>
<P>Entities in XUL <!--INDEX DTD entities -->  work the same way as they do in any other XML application. They are used to reference data that was abstracted from the content. This process encourages reuse of data, but in the context of Mozilla's XPFE, it is used to extract visible text in interface widgets. This extraction ensures that the content can remain untouched during the localization process.    <p>Here are some main features of the Mozilla
<H3><A NAME="77040"></A> Inserting Entities</H3>    internationalization capabilities, which are relevant to the
<P><A HREF="#77008">Example 11-1</A> shows <!--INDEX DTD entities:inserting into XUL code -->  <!--INDEX XUL (XML-based User-interface Language):DTD entities, inserting into code -->  how to put DTD entities into your XUL code by using attribute values for the text of a menu item (<TT>label</TT>) and the keyboard access shortcuts (<TT>accesskey</TT>). The syntax requires that an entity be placed in quotes as the value of the attribute. This is a useful example because it highlights the localization of a widget label, which is common to many widgets, and a supplementary attribute, which, in this case, is an <TT>accesskey</TT>.    user front end application level:</p>
    <ul>
<P><I>Example 11-1: <A NAME="77008"></A></I>      <li>Mozilla is Unicode-enabled for Latin-based languages,
<I>XUL menu with entity references for text and accesskeys</I>      Cyrillic, Greek, Chinese, Japanese, and Korean. Mozilla
<PRE> &lt;menu label="&amp;menuFile.label;</TD>" accesskey="&amp;menuFile.accesskey;"&gt;      widgets and HTML rendering can support the input and display
       of these languages. Unicode-enabling for other languages and
       character sets is an ongoing process.</li>
       <li>Mozilla can be easily localized into different languages,
       even if not supported by the underlying operating
       system.</li>
       <li>Most Mozilla localization work involves translating
       strings as entities in Document Type Definition (DTD) format
       and properties file format (an idea taken from Java), which
       are based on open standards.</li>
       <li>Localization can be done once and run on Windows,
       Macintosh, Unix, and other platforms-something we have come
       to expect from the Mozilla framework. This is a great time
       saver, and indeed a cost saver if you come at it from that
       perspective.</li>
       <li>Mozilla supports BIDI, the display and input of text in a
       bidirectional format for such languages as Arabic and Hebrew,
       yet the capabilities for this in the UI were not mature when
       we were writing this book.</li>
       <li>The UI locale DTD files use UTF-8 as the default encoding
       for translated items. Mozilla then maps to Unicode or
       non-Unicode fonts, depending on which platform you're running
       on or what fonts you installed in your system. You are
       encouraged to encode your DTD files as UTF-8 when
       possible.</li>
     </ul>
     <p>Recalling the architecture of the XPFE toolkit described in
     <a href="ch02.html#77048">Chapter 2</a>, the locale component
     can be easily plugged in and out of the application that you
     are working on without impacting any other components. This
     functionality is ideal, for instance, for people with
     linguistic skills and less experience with technical issues to
     become involved in a Mozilla-related project.</p>
     <h3><a name="77030"></a> For the Developer</h3>
     <p>Many available <!--INDEX localization:resources --> 
     <!--INDEX resources:localization --> resources show you how to
     help localize an existing application into a specific language
     or to find out how to add localization support to your own
     application. <!--INDEX newsgroups, localization --> 
     <!--INDEX development:localization resources -->
     </p>
     <p>The Mozilla Localization Project hosts various localization
     teams and provides help whenever possible. The Mozilla
     community includes a discussion group that uses many languages
     to discuss Mozilla development issues. The
     <i>netscape.public.mozilla.l10n</i> and
     <i>netscape.public.mozilla.i18n</i> newsgroups are a great
     place to discuss these issues with other developers.</p>
     <p>When developing an application, some words and phrases that
     developers like to hear (according to the Mozilla organization,
     at <i><a href=
     "http://www.mozilla.org/projects/l10n/xul-l10n.html">http://www.mozilla.org/projects/l10n/xul-l10n.html</a></i>)
     are: standards compliant, simple, leveragable, portable,
     extensible, separable, consistent, dynamic, valid, parser
     friendly, invisible (part of the XUL authoring process), and
     efficient. The following sections will help you understand how
     these terms and goals impact the chosen technologies and how to
     use those technologies. The ultimate aim is to help you
     localize your application easily.</p>
     <h3><a name="77031"></a> Files and File Formats</h3>
     <p>Here are the <!--INDEX localization:file types --> 
     <!--INDEX files:localization file types --> main file types
     you'll see when learning about locale and that you will use
     when localizing your Mozilla application. A good home for all
     of these resources is in the <i>locale</i> area of the
     application <i>chrome</i>.</p>
     <dl>
       <dt>DTD (<i>.dtd</i>)</dt>
       <dd>Files containing entities that host the strings from XUL
       content files.</dd>
       <dt>Property (<i>.properties</i>) or string bundles</dt>
       <dd>Files containing strings that are accessed by JavaScript,
       C++, and possibly other scripting or component files.</dd>
       <dt>RDF</dt>
       <dd>RDF files are described in XML syntax, so use
       entities.</dd>
       <dt>HTML and text</dt>
       <dd>Suitable for long text, HTML and XML documents and other
       content that needs to be localized.</dd>
     </dl>
     <p>The next two sections will help you start localizing your
     application. The sections focus on DTD files and string
     bundles, which are the core formats for XUL-localizable
     content. Before getting started, here is a review of some
     general principles that might help you design and implement the
     locale component.</p>
     <h3><a name="77032"></a> UI Aesthetics and Principles</h3>
     <p>To put locale in context, this section looks at some issues
     you may encounter when localizing your Mozilla application.
     Some are universal principles and others are unique to the
     environment. This reference is by no means exhaustive, but it
     contains some scenarios and tips the authors came across in
     their experience with locale in Mozilla.</p>
     <h4><a name="77033"></a> Space management</h4>
     <p>One of the 
     <!--INDEX localization:UI aesthetics, space management --> 
     <!--INDEX user interface:localization:space management --> 
     <!--INDEX design issues, user interfaces:localization and space management -->
     guiding principles in UI design is for your interface to not
     get too crowded. Although estimates are not specific, it is
     wise to leave about 30 percent expansion space in your window
     and dialogs. To achieve this flexibility, you have to ensure
     that the XUL window has ample space in the first place for all
     the widgets to fit.</p>
     <p>More specifically, the application needs to have space for
     widgets to expand or contract without detracting from the
     overall look and feel. Intuitive use of the XUL box model
     (refer to <a href="ch03.html#77084">Chapter 3</a> for more
     information) and correct choice of widgets goes a long way in
     achieving this goal.</p>
     <p>The factors that can cause this space to be filled include
     using languages/character sets that are more verbose than the
     one that was there originally, and the users changing their
     font size settings. Some safeguards that have been built into
     Mozilla already handle this problem. Much of it is done in CSS,
     but other methods are available. The section "Language Quirks,"
     later in this chapter, outlines one of these methods.</p>
     <h4><a name="77034"></a> Help system</h4>
     <p>If you <!--INDEX help system, localization and --> 
     <!--INDEX localization:help system --> 
     <!--INDEX user interface:localization:help system --> choose to
     integrate a Help system into your application, a localizable
     resource will be most content. Opinions differ within technical
     writing circles, but having screenshots in your documents is
     generally not considered advantageous. For example, they can
     get out of date easily in the constantly evolving world of
     software, or they need to be retaken frequently when new
     features are added to the UI.</p>
     <h4><a name="77035"></a> Tooltips</h4>
     <p>Tooltips <!--INDEX tooltips:localization and --> 
     <!--INDEX localization:tooltips --> 
     <!--INDEX user interface:localization:tooltips --> are a
     sometimes overlooked yet valuable way of relaying information
     to the user. They can be used as an alternative to a help
     system if you are looking for something simpler. They can also
     expand an explanation of something that was annotated in the UI
     text. Sometimes text can have multiple meanings in context, and
     expanding it with a tooltip can clear up any confusion. In an
     editor or multifile browser, for example, you might have a find
     button. A tooltip can clear up the confusion about whether the
     results of the action searches in the current file or in all
     files.</p>
     <p>Most XUL widgets support tooltips. Implementation is as
     straightforward as adding a <tt>tooltip</tt> attribute to the
     widget with an associated value. For it to be localizable, it
     must be in the form of a DTD entity.</p>
 <pre>
 &lt;tab id="config" label="&amp;config.label;" tooltip="&amp;config.tooltip;" /&gt;
 </pre>
     <p>The <a href="#77040">"Inserting Entities</a>" section, later
     in this chapter, provides more information on the rationale for
     using entities and how to insert them into XUL content.</p>
     <h4><a name="77036"></a> Grammar</h4>
     <p>In any user <!--INDEX grammar, localization and --> 
     <!--INDEX localization:user interface:grammar considerations -->
     <!--INDEX user interface:localization:grammar considerations -->
     interface, there is limited screen space. When possible,
     however, provide complete or near-complete sentences. These
     sentences are better than using text based on phrases or
     acronyms. They provide meaning to the translator and clearer
     instructions to the user.</p>
     <h4><a name="77037"></a> Commenting</h4>
     <p>Commenting <!--INDEX comments:localization and --> 
     <!--INDEX localization:user interface:commenting --> 
     <!--INDEX user interface:localization:commenting --> was
     mentioned before, but is worth stressing again. The translators
     may have not even seen the software that you are working on,
     but you hope that is not the case! Commenting is very useful
     for giving context and flagging strings that should not be
     commented. You can comment your HTML, XML, or DTD files by
     wrapping it in a <tt>&lt;!-- comment --&gt;</tt> block.</p>
 <pre>
 &lt;!--NOTE to Translators: Do NOT change the next string --&gt;
 &lt;!ENTITY appName.label "My Application"&gt;
 </pre>
     <p>Note that a bundle file uses the <tt>#</tt> notation at the
     beginning of each line to signify a comment.</p>
 <pre>
 # This text is used in the view menu for launching the page choices dialog
 pageChoices=Go To...
 </pre>
     <h4><a name="77038"></a> Web resources</h4>
     <p>Localizable <!--INDEX web resources, localization and --> 
     <!--INDEX localization:user interface:web resources --> 
     <!--INDEX user interface:localization:web resources -->
     resources are not only strings of text that need to be
     translated into different languages; they are any variable
     information that is liable to change over the lifetime of your
     application. The handling of URLs is a case in point. You may
     have references interspersed throughout your UI that point to
     web resources. These references can be explicit listings or
     widgets that, once activated, launch a client to bring you to a
     certain location.</p>
     <p>Images are another resource commonly used in documentation.
     A tutorial on your application may have screenshots of the UI
     in action. If you do use images, keep an eye out for
     localizable content in them.</p>
     <h2><a name="77039"></a> DTD Entities</h2>
     <p>Entities in XUL <!--INDEX DTD entities --> work the same way
     as they do in any other XML application. They are used to
     reference data that was abstracted from the content. This
     process encourages reuse of data, but in the context of
     Mozilla's XPFE, it is used to extract visible text in interface
     widgets. This extraction ensures that the content can remain
     untouched during the localization process.</p>
     <h3><a name="77040"></a> Inserting Entities</h3>
     <p><a href="#77008">Example 11-1</a> shows 
     <!--INDEX DTD entities:inserting into XUL code --> 
     <!--INDEX XUL (XML-based User-interface Language):DTD entities, inserting into code -->
     how to put DTD entities into your XUL code by using attribute
     values for the text of a menu item (<tt>label</tt>) and the
     keyboard access shortcuts (<tt>accesskey</tt>). The syntax
     requires that an entity be placed in quotes as the value of the
     attribute. This is a useful example because it highlights the
     localization of a widget label, which is common to many
     widgets, and a supplementary attribute, which, in this case, is
     an <tt>accesskey</tt>.</p>
     <p><i>Example 11-1: <a name="77008"></a></i> <i>XUL menu with
     entity references for text and accesskeys</i></p>
 <pre>
  &lt;menu label="&amp;menuFile.label;&lt;/td&gt;" accesskey="&amp;menuFile.accesskey;"&gt;
    &lt;menupopup&gt;     &lt;menupopup&gt;
     &lt;menuitem accesskey="&amp;menuNew.accesskey;</TD>" label="&amp;menuNew.label;"         oncommand="doNew( );"/&gt;     &lt;menuitem accesskey="&amp;menuNew.accesskey;&lt;/td&gt;" label="&amp;menuNew.label;"         oncommand="doNew( );"/&gt;
      &lt;menuitem accesskey="&amp;menuOpen.accesskey;" label="&amp;menuOpen.label;"        oncommand="doOpen( );"/&gt;       &lt;menuitem accesskey="&amp;menuOpen.accesskey;" label="&amp;menuOpen.label;"        oncommand="doOpen( );"/&gt;
      &lt;menuseparator /&gt;       &lt;menuseparator /&gt;
      &lt;menuitem accesskey="&amp;menuClose.accesskey;" label="&amp;menuClose.label;"        oncommand="doClose( );"/&gt;       &lt;menuitem accesskey="&amp;menuClose.accesskey;" label="&amp;menuClose.label;"        oncommand="doClose( );"/&gt;
Line 84  pageChoices=Go To...</PRE> Line 304  pageChoices=Go To...</PRE>
      &lt;menuitem accesskey="&amp;menuExit.accesskey;" label="&amp;menuExit.label;"       &lt;menuitem accesskey="&amp;menuExit.accesskey;" label="&amp;menuExit.label;"
          oncommand="doExit( );"/&gt;           oncommand="doExit( );"/&gt;
    &lt;/menupopup&gt;     &lt;/menupopup&gt;
 &lt;/menu&gt;</PRE> &lt;/menu&gt;
</pre>
<P>Note that each entity in <A HREF="#77008">Example 11-1</A> has a text value associated with it in the DTD entities declarations. The entity that appears on the menu is <TT>&amp;menuFile.label;</TT>. Note that this entity mirrors the correct syntax for referencing a value, which is: <TT>&amp;get.text;</TT>.    <p>Note that each entity in <a href="#77008">Example 11-1</a>
<P>The entity reference (or name, in this context) must be preceded by an ampersand (<TT>&amp;</TT>) and end with a semicolon (<TT>;</TT>). The period is optional, but conventional. Typically, the period separates the entity's element or target (<TT>menuFile</TT>) from the type of entity (<TT>label</TT>). Refer to the<A HREF="#77052">"Programming and Localization</A>" section later in this chapter for more information on naming conventions.    has a text value associated with it in the DTD entities
<P>For some widgets, including <TT>&lt;description&gt;</TT> and <TT>&lt;label&gt;</TT>, the entity can be placed inside the element tags, as opposed to being values of attributes.    declarations. The entity that appears on the menu is
<PRE>&lt;description&gt;&amp;explanation.text;&lt;/description&gt;</PRE>    <tt>&amp;menuFile.label;</tt>. Note that this entity mirrors
<P><A HREF="#77006">Table 11-1</A> represents the DTD files that accompany the XUL content in <A HREF="#77008">Example 11-1</A>. Two languages, English and Spanish, are separated into different files. These files have the same name as the DTD file referenced in the XUL file that contains the entities. However, each file for every different language exists in a separate locale folder. Each entry, or entity, in the DTD file has a name that matches the name referenced in the XUL and a value to be filled in for that entity. The value is enclosed in quotes. When generating these files, you will need to create the file only once and copy it to a different directory where you can replace the values in the entities. A good tool would carry out this process for you. Refer to the <A HREF="#92113">"Localization Tools</A>" sidebar later in the chapter for more information.    the correct syntax for referencing a value, which is:
    <tt>&amp;get.text;</tt>.</p>
<P><I>Table 11-1: <A NAME="77006"></A></I>    <p>The entity reference (or name, in this context) must be
<I>Entity definitions for the XUL menu</I>    preceded by an ampersand (<tt>&amp;</tt>) and end with a
<P><TABLE WIDTH=100% BORDER=1><TR><TD><B>  English DTD</B></TD> <TD><B>  Spanish DTD</B></TD></TR>    semicolon (<tt>;</tt>). The period is optional, but
<TR><TD> &lt;!ENTITY menuFile.label "File"&gt;</TD></TR>    conventional. Typically, the period separates the entity's
<TR><TD> &lt;!ENTITY menuNew.label "New"&gt;</TD></TR>    element or target (<tt>menuFile</tt>) from the type of entity
<TR><TD> &lt;!ENTITY menuOpen.label "Open..."&gt;</TD></TR>    (<tt>label</tt>). Refer to the<a href="#77052">"Programming and
<TR><TD> &lt;!ENTITY menuClose.label "Close"&gt;</TD></TR>    Localization</a>" section later in this chapter for more
<TR><TD> &lt;!ENTITY menuSave.label "Save"&gt;</TD></TR>    information on naming conventions.</p>
<TR><TD> &lt;!ENTITY menuSaveAs.label "Save As..."&gt;</TD></TR>    <p>For some widgets, including <tt>&lt;description&gt;</tt> and
<TR><TD> &lt;!ENTITY menuPrint.label "Print..."&gt;</TD></TR>    <tt>&lt;label&gt;</tt>, the entity can be placed inside the
<TR><TD> &lt;!ENTITY menuExit.label "Exit"&gt;</TD></TR>    element tags, as opposed to being values of attributes.</p>
<TR><TD> &lt;!ENTITY menuFile.accesskey "f"&gt;</TD></TR><pre>
<TR><TD> &lt;!ENTITY menuNew.accesskey "n"&gt;</TD></TR>&lt;description&gt;&amp;explanation.text;&lt;/description&gt;
<TR><TD> &lt;!ENTITY menuOpen.accesskey "o"&gt;</TD></TR></pre>
<TR><TD> &lt;!ENTITY menuClose.accesskey "c"&gt;</TD></TR>    <p><a href="#77006">Table 11-1</a> represents the DTD files
<TR><TD> &lt;!ENTITY menuSave.accesskey "s"&gt;</TD></TR>    that accompany the XUL content in <a href="#77008">Example
<TR><TD> &lt;!ENTITY menuSaveAs.accesskey "a"&gt;</TD></TR>    11-1</a>. Two languages, English and Spanish, are separated
<TR><TD> &lt;!ENTITY menuPrint.accesskey "p"&gt;</TD></TR>    into different files. These files have the same name as the DTD
<TR><TD> &lt;!ENTITY menuExit.accesskey "x"&gt;</TD>     <TD> &lt;!ENTITY menuFile.label "Archivo"&gt;</TD></TR>    file referenced in the XUL file that contains the entities.
<TR><TD> &lt;!ENTITY menuNew.label "Nuevo"&gt;</TD></TR>    However, each file for every different language exists in a
<TR><TD> &lt;!ENTITY menuOpen.label "Abrir Archivo..."&gt;</TD></TR>    separate locale folder. Each entry, or entity, in the DTD file
<TR><TD> &lt;!ENTITY menuClose.label "Cerrar"&gt;</TD></TR>    has a name that matches the name referenced in the XUL and a
<TR><TD> &lt;!ENTITY menuSave.label "Salvar"&gt;</TD></TR>    value to be filled in for that entity. The value is enclosed in
<TR><TD> &lt;!ENTITY menuSaveAs.label "Salvar Como..."&gt;</TD></TR>    quotes. When generating these files, you will need to create
<TR><TD> &lt;!ENTITY menuPrint.label "Imprimir..."&gt;</TD></TR>    the file only once and copy it to a different directory where
<TR><TD> &lt;!ENTITY menuExit.label "Salir"&gt;</TD></TR>    you can replace the values in the entities. A good tool would
<TR><TD> &lt;!ENTITY menuFile.accesskey "a"&gt;</TD></TR>    carry out this process for you. Refer to the <a href=
<TR><TD> &lt;!ENTITY menuNew.accesskey "n"&gt;</TD></TR>    "#92113">"Localization Tools</a>" sidebar later in the chapter
<TR><TD> &lt;!ENTITY menuOpen.accesskey "o"&gt;</TD></TR>    for more information.</p>
<TR><TD> &lt;!ENTITY menuClose.accesskey "c"&gt;</TD></TR>    <p><i>Table 11-1: <a name="77006"></a></i> <i>Entity
<TR><TD> &lt;!ENTITY menuSave.accesskey "s"&gt;</TD></TR>    definitions for the XUL menu</i></p>
<TR><TD> &lt;!ENTITY menuSaveAs.accesskey "a"&gt;</TD></TR>    <table width="100%" border="1">
<TR><TD> &lt;!ENTITY menuPrint.accesskey "i"&gt;</TD></TR>      <tr>
<TR><TD> &lt;!ENTITY menuExit.accesskey "r"&gt;</TD></TR></TABLE><P>        <td><b>English DTD</b></td>
        <td><b>Spanish DTD</b></td>
<P><A HREF="#77002">Figure 11-1</A> shows the resulting XUL menus. There can only be one value for each entity and only one language taking precedence, or appearing in the UI, at a time.      </tr>
<P><CENTER><IMG SRC="foo.gif"></CENTER>      <tr>
<P><I>Figure 11-1: <A NAME="77002"></A></I>        <td>&lt;!ENTITY menuFile.label "File"&gt;</td>
<I>Localized menus in English and Spanish</I>      </tr>
      <tr>
<P>This example presents only two languages, but theoretically, you can have as many languages as you require. The locale-switching mechanism and the chrome registry must determine which one should be used, which is explained later in the section "The Chrome Registry and Locale."        <td>&lt;!ENTITY menuNew.label "New"&gt;</td>
<H3><A NAME="77041"></A> External and Inline Entities</H3>      </tr>
<P>You may ask,  <!--INDEX DTD entities:types -->  <!--INDEX external DTD entities -->  <!--INDEX internal DTD entities --> how are the entities accessed? You can associate the DTD with your XUL file in two ways. The first is internally, which involves wrapping the strings in a DTD data type enclosure by using the <TT>DOCTYPE</TT> declaration.      <tr>
<PRE>&lt;!DOCTYPE window [        <td>&lt;!ENTITY menuOpen.label "Open..."&gt;</td>
       </tr>
       <tr>
         <td>&lt;!ENTITY menuClose.label "Close"&gt;</td>
       </tr>
       <tr>
         <td>&lt;!ENTITY menuSave.label "Save"&gt;</td>
       </tr>
       <tr>
         <td>&lt;!ENTITY menuSaveAs.label "Save As..."&gt;</td>
       </tr>
       <tr>
         <td>&lt;!ENTITY menuPrint.label "Print..."&gt;</td>
       </tr>
       <tr>
         <td>&lt;!ENTITY menuExit.label "Exit"&gt;</td>
       </tr>
       <tr>
         <td>&lt;!ENTITY menuFile.accesskey "f"&gt;</td>
       </tr>
       <tr>
         <td>&lt;!ENTITY menuNew.accesskey "n"&gt;</td>
       </tr>
       <tr>
         <td>&lt;!ENTITY menuOpen.accesskey "o"&gt;</td>
       </tr>
       <tr>
         <td>&lt;!ENTITY menuClose.accesskey "c"&gt;</td>
       </tr>
       <tr>
         <td>&lt;!ENTITY menuSave.accesskey "s"&gt;</td>
       </tr>
       <tr>
         <td>&lt;!ENTITY menuSaveAs.accesskey "a"&gt;</td>
       </tr>
       <tr>
         <td>&lt;!ENTITY menuPrint.accesskey "p"&gt;</td>
       </tr>
       <tr>
         <td>&lt;!ENTITY menuExit.accesskey "x"&gt;</td>
         <td>&lt;!ENTITY menuFile.label "Archivo"&gt;</td>
       </tr>
       <tr>
         <td>&lt;!ENTITY menuNew.label "Nuevo"&gt;</td>
       </tr>
       <tr>
         <td>&lt;!ENTITY menuOpen.label "Abrir Archivo..."&gt;</td>
       </tr>
       <tr>
         <td>&lt;!ENTITY menuClose.label "Cerrar"&gt;</td>
       </tr>
       <tr>
         <td>&lt;!ENTITY menuSave.label "Salvar"&gt;</td>
       </tr>
       <tr>
         <td>&lt;!ENTITY menuSaveAs.label "Salvar Como..."&gt;</td>
       </tr>
       <tr>
         <td>&lt;!ENTITY menuPrint.label "Imprimir..."&gt;</td>
       </tr>
       <tr>
         <td>&lt;!ENTITY menuExit.label "Salir"&gt;</td>
       </tr>
       <tr>
         <td>&lt;!ENTITY menuFile.accesskey "a"&gt;</td>
       </tr>
       <tr>
         <td>&lt;!ENTITY menuNew.accesskey "n"&gt;</td>
       </tr>
       <tr>
         <td>&lt;!ENTITY menuOpen.accesskey "o"&gt;</td>
       </tr>
       <tr>
         <td>&lt;!ENTITY menuClose.accesskey "c"&gt;</td>
       </tr>
       <tr>
         <td>&lt;!ENTITY menuSave.accesskey "s"&gt;</td>
       </tr>
       <tr>
         <td>&lt;!ENTITY menuSaveAs.accesskey "a"&gt;</td>
       </tr>
       <tr>
         <td>&lt;!ENTITY menuPrint.accesskey "i"&gt;</td>
       </tr>
       <tr>
         <td>&lt;!ENTITY menuExit.accesskey "r"&gt;</td>
       </tr>
     </table>
     <p><a href="#77002">Figure 11-1</a> shows the resulting XUL
     menus. There can only be one value for each entity and only one
     language taking precedence, or appearing in the UI, at a
     time.</p>
     <div class="c23">
       <img src="foo.gif">
     </div>
     <p><i>Figure 11-1: <a name="77002"></a></i> <i>Localized menus
     in English and Spanish</i></p>
     <p>This example presents only two languages, but theoretically,
     you can have as many languages as you require. The
     locale-switching mechanism and the chrome registry must
     determine which one should be used, which is explained later in
     the section "The Chrome Registry and Locale."</p>
     <h3><a name="77041"></a> External and Inline Entities</h3>
     <p>You may ask, <!--INDEX DTD entities:types --> 
     <!--INDEX external DTD entities --> 
     <!--INDEX internal DTD entities --> how are the entities
     accessed? You can associate the DTD with your XUL file in two
     ways. The first is internally, which involves wrapping the
     strings in a DTD data type enclosure by using the
     <tt>DOCTYPE</tt> declaration.</p>
 <pre>
 &lt;!DOCTYPE window [
 &lt;!ENTITY windowTitle.label "Greetings"&gt;  &lt;!ENTITY windowTitle.label "Greetings"&gt;
 &lt;!ENTITY fileMenu.label "File"&gt;  &lt;!ENTITY fileMenu.label "File"&gt;
]&gt;</PRE>]&gt;
<P>The second is an external DTD file, which is associated with your XUL that also uses the <TT>DOCTYPE</TT> declaration, and a reference pointing to the file:</pre>
<PRE>&lt;!DOCTYPE window SYSTEM "chrome://xfly/locale/xfly.dtd"&gt;</PRE>    <p>The second is an external DTD file, which is associated with
<P>The node referenced in the <TT>DOCTYPE</TT> declaration is usually followed by the XUL document's root node. In this case, it is <TT>window</TT>, but can be other elements like <TT>page</TT> or <TT>dialog</TT> (however, it is not actually validated so it can be any value).    your XUL that also uses the <tt>DOCTYPE</tt> declaration, and a
<P>If you have a small application, the DTD files can reside in the same folder as your XUL files, but putting them into their own locale directory within your chrome structure is good practice.    reference pointing to the file:</p>
<P>Consider the main Editor window in Mozilla. Its declaration in <A HREF="#77010">Example 11-2</A> is flexible enough to associate multiple DTD files with your content.<pre>
&lt;!DOCTYPE window SYSTEM "chrome://xfly/locale/xfly.dtd"&gt;
<P><I>Example 11-2: <A NAME="77010"></A></I></pre>
<I>The Editor's Doctype definitions</I>    <p>The node referenced in the <tt>DOCTYPE</tt> declaration is
<PRE> &lt;!DOCTYPE window </TD>[    usually followed by the XUL document's root node. In this case,
     it is <tt>window</tt>, but can be other elements like
     <tt>page</tt> or <tt>dialog</tt> (however, it is not actually
     validated so it can be any value).</p>
     <p>If you have a small application, the DTD files can reside in
     the same folder as your XUL files, but putting them into their
     own locale directory within your chrome structure is good
     practice.</p>
     <p>Consider the main Editor window in Mozilla. Its declaration
     in <a href="#77010">Example 11-2</a> is flexible enough to
     associate multiple DTD files with your content.</p>
     <p><i>Example 11-2: <a name="77010"></a></i> <i>The Editor's
     Doctype definitions</i></p>
 <pre>
  &lt;!DOCTYPE window &lt;/td&gt;[
    &lt;!ENTITY % editorDTD SYSTEM "chrome://editor/locale/editor.dtd" &gt;     &lt;!ENTITY % editorDTD SYSTEM "chrome://editor/locale/editor.dtd" &gt;
    %editorDTD;     %editorDTD;
    &lt;!ENTITY % editorOverlayDTD SYSTEM "chrome://editor/locale/editorOverlay.dtd" &gt;     &lt;!ENTITY % editorOverlayDTD SYSTEM "chrome://editor/locale/editorOverlay.dtd" &gt;
    %editorOverlayDTD;     %editorOverlayDTD;
    &lt;!ENTITY % brandDTD SYSTEM "chrome://global/locale/brand.dtd" &gt;     &lt;!ENTITY % brandDTD SYSTEM "chrome://global/locale/brand.dtd" &gt;
    %brandDTD;     %brandDTD;
 ]&gt;</PRE> ]&gt;
</pre>
<P>The declaration first stores the document associated with the chrome URL in an associated parameter entity. It then simply uses it. XML does not have a one-step way of storing and using the entity as in other languages. In other words, the declaration is the equivalent of the <TT>import foo</TT> in Python, or <TT>#include "foo.h"</TT> in C.    <p>The declaration first stores the document associated with
<P>Certain localizable resources lend themselves to reuse. It makes sense to use the same strings across different content, which explains the inclusion of a DTD file in more than one XUL document. In Mozilla, this includes brand information, build ID numbers, and help resources.    the chrome URL in an associated parameter entity. It then
<P>Which is more appropriate to use: internal or external entities? Using the external approach is preferable because the content (XUL) does not have to be touched during the translation process. If someone opts to create a tool to extract and/or insert strings, their job would be much easier if they had to parse one less file type. This may remove context somewhat, but it can be overcome by actively commenting the DTD file.    simply uses it. XML does not have a one-step way of storing and
<H2><A NAME="77042"></A> String Bundles</H2>    using the entity as in other languages. In other words, the
<P>String bundles  <!--INDEX localization:string bundles -->  <!--INDEX string bundles:localization -->  <!--INDEX user interface:localization:string bundles --> are flat text files that contain text for the UI that is accessed in JavaScript, C++, and theoretically any language that fits within the Mozilla framework. These bundles are strings that can be presented visually to the user via some functionality in the application at any time. This may be anything from a dynamically changing menu item to an alert box, or from a URL to a placeholder that is filled depending on the context in which it is accessed. The bundle files are given an extension of <I>.properties</I> and they commonly reside in the locale directory with the DTD files.    declaration is the equivalent of the <tt>import foo</tt> in
<P>A user interface can use one or more string bundles, each of which is defined in a <TT>&lt;stringbundle&gt;</TT> element and surrounded by a <TT>&lt;stringbundleset&gt;</TT> element. <A HREF="#77012">Example 11-3</A> contains the bundles used by the Mozilla browser.    Python, or <tt>#include "foo.h"</tt> in C.</p>
    <p>Certain localizable resources lend themselves to reuse. It
<P><I>Example 11-3: <A NAME="77012"></A></I>    makes sense to use the same strings across different content,
<I>String bundles used by the Mozilla browser</I>    which explains the inclusion of a DTD file in more than one XUL
<PRE> &lt;stringbundleset id="stringbundleset"&gt;    document. In Mozilla, this includes brand information, build ID
     numbers, and help resources.</p>
     <p>Which is more appropriate to use: internal or external
     entities? Using the external approach is preferable because the
     content (XUL) does not have to be touched during the
     translation process. If someone opts to create a tool to
     extract and/or insert strings, their job would be much easier
     if they had to parse one less file type. This may remove
     context somewhat, but it can be overcome by actively commenting
     the DTD file.</p>
     <h2><a name="77042"></a> String Bundles</h2>
     <p>String bundles <!--INDEX localization:string bundles --> 
     <!--INDEX string bundles:localization --> 
     <!--INDEX user interface:localization:string bundles --> are
     flat text files that contain text for the UI that is accessed
     in JavaScript, C++, and theoretically any language that fits
     within the Mozilla framework. These bundles are strings that
     can be presented visually to the user via some functionality in
     the application at any time. This may be anything from a
     dynamically changing menu item to an alert box, or from a URL
     to a placeholder that is filled depending on the context in
     which it is accessed. The bundle files are given an extension
     of <i>.properties</i> and they commonly reside in the locale
     directory with the DTD files.</p>
     <p>A user interface can use one or more string bundles, each of
     which is defined in a <tt>&lt;stringbundle&gt;</tt> element and
     surrounded by a <tt>&lt;stringbundleset&gt;</tt> element. <a
     href="#77012">Example 11-3</a> contains the bundles used by the
     Mozilla browser.</p>
     <p><i>Example 11-3: <a name="77012"></a></i> <i>String bundles
     used by the Mozilla browser</i></p>
 <pre>
  &lt;stringbundleset id="stringbundleset"&gt;
      &lt;stringbundle id="bundle_navigator"       &lt;stringbundle id="bundle_navigator"
          src="chrome://navigator/locale/navigator.properties"/&gt;           src="chrome://navigator/locale/navigator.properties"/&gt;
      &lt;stringbundle id="bundle_brand"       &lt;stringbundle id="bundle_brand"
Line 176  pageChoices=Go To...</PRE> Line 553  pageChoices=Go To...</PRE>
          src="chrome://global-region/locale/region.properties"/&gt;           src="chrome://global-region/locale/region.properties"/&gt;
      &lt;stringbundle id="findBundle"       &lt;stringbundle id="findBundle"
          src="chrome://global/locale/finddialog.properties"/&gt;           src="chrome://global/locale/finddialog.properties"/&gt;
 &lt;/stringbundleset&gt;</PRE> &lt;/stringbundleset&gt;
</pre>
<P>As you can see from their names and their locations in the chrome, each bundle serves a different purpose. They include a file that contains the bulk of the strings for the browser (<I>navigator.properties</I>), a file that includes branding strings, and a couple of files for regional information. This model is useful if you need to output many strings to the UI from your source code and would like to organize them into meaningful groups.    <p>As you can see from their names and their locations in the
<H3><A NAME="77043"></A> Inside a Bundle</H3>    chrome, each bundle serves a different purpose. They include a
<P>A string  <!--INDEX localization:string bundles:file format -->  <!--INDEX string bundles:localization:file format -->  <!--INDEX user interface:localization:string bundle file format --> bundle (<I>.properties</I>) file has a very simple format. It contains one or more lines that have the identifier associated with the localizable string. The format of a string bundle string with an identifier is:    file that contains the bulk of the strings for the browser
<PRE>Identifier=String</PRE>    (<i>navigator.properties</i>), a file that includes branding
<P>The format for comments in a bundle file requires the hash notation (<TT>#</TT>). Comments are useful for notifying translators of the context of strings, or flagging a string that should be left as is and not localized. Comments in properties files are formatted in the following manner.    strings, and a couple of files for regional information. This
<PRE># DO NOT TRANSLATE    model is useful if you need to output many strings to the UI
applicationTitle=xFly</PRE>    from your source code and would like to organize them into
<P>Spaces in bundles are treated literally-spaces between words are observed, with the exception of the start and the end of the string.    meaningful groups.</p>
<P>The next section shows the methods and properties specific to the <TT>&lt;stringbundle&gt;</TT> element that are available to you when you use it. The implementations are contained in the binding for the element.    <h3><a name="77043"></a> Inside a Bundle</h3>
<H3><A NAME="77044"></A> String Bundle Methods and Properties</H3>    <p>A string 
<P>Defining your bundle in XUL and then creating the file with the values is only half the story. This section shows how to extract the values from the bundle and place them in UI. The language of choice in these examples is JavaScript. This process is necessary when you have to change values in the UI because DTD entities can not be updated dynamically.    <!--INDEX localization:string bundles:file format --> 
<H4><A NAME="77045"></A> Methods</H4>    <!--INDEX string bundles:localization:file format --> 
<P>Our bundle  <!--INDEX methods:string bundles -->  <!--INDEX localization:string bundles:methods -->  <!--INDEX string bundles:localization:methods -->  <!--INDEX user interface:localization:string bundle methods --> is defined in XUL like this:    <!--INDEX user interface:localization:string bundle file format -->
<PRE>&lt;stringbundle id="bundle_xfly"    bundle (<i>.properties</i>) file has a very simple format. It
src="chrome://xfly/locale/xfly.properties"/&gt;</PRE>    contains one or more lines that have the identifier associated
<P>To access the methods of the bundle object in your script, you have to get a handle on the XUL element by using its <TT>id</TT>. First declare the variable globally that will be holding the bundle:    with the localizable string. The format of a string bundle
<PRE>var xFlyBundle;</PRE>    string with an identifier is:</p>
<P>Then assign the variable to the bundle. A good place to do this is in the load handler function of your XUL window, or in the constructor for your binding if you are using it from there:<pre>
<PRE>xFlyBundle = document.getElementById("bundle_xfly");</PRE>Identifier=String
<P>Now that you have access to the bundle, you can use the available methods to retrieve the strings. The two main functions are <TT>getString</TT> and <TT>getFormattedString</TT>.</pre>
<H5><A NAME="77046"></A> getString</H5>    <p>The format for comments in a bundle file requires the hash
<P>The most  <!--INDEX getString method --> straightforward string access method, <TT>getString</TT>, takes one parameter (namely the identifier of the string) and returns the localizable string value for use in the UI:    notation (<tt>#</tt>). Comments are useful for notifying
<PRE>var readonly = xFlyBundle.getString(`readonlyFile');    translators of the context of strings, or flagging a string
alert(readonly);</PRE>    that should be left as is and not localized. Comments in
<P>The string bundle entry looks like this:    properties files are formatted in the following manner.</p>
<PRE>readonlyfile=This file is read only</PRE><pre>
<H5><A NAME="77047"></A> getFormattedString</H5># DO NOT TRANSLATE
<P>This  <!--INDEX getFormattedString method --> function takes an extra parameter-an array of string values, which are substituted into the string in the bundle. Then the full string with the substituted values is returned:applicationTitle=xFly
<PRE>var numFiles = numberInEditor</pre>
numFilesMsg = xflyBundle.getFormattedString("numFilesMessage", [numFiles]);</PRE>    <p>Spaces in bundles are treated literally-spaces between words
<P>You can have more than one value replaced in the string, each one delimited within the square brackets by using a comma:    are observed, with the exception of the start and the end of
<PRE>fileInfo = xflyBundle.getFormattedString("fileInformation",    the string.</p>
[fileName, fileSize]);</PRE>    <p>The next section shows the methods and properties specific
<P>The string bundle entry looks like this:    to the <tt>&lt;stringbundle&gt;</tt> element that are available
<PRE>flyFileInformation=The file is called %1$s and its size is %2$s</PRE>    to you when you use it. The implementations are contained in
<P>The <TT>%x</TT> numerical value refers to the ordering of the values to be substituted in the string. The type of the value is determined by the dollar ($) symbol. In this case, there are two possibilities-<TT>$s</TT> is a string value and <TT>$d</TT> is an integer value.    the binding for the element.</p>
<H4><A NAME="77048"></A> Properties</H4>    <h3><a name="77044"></a> String Bundle Methods and
<P>Some  <!--INDEX properties:string bundles -->  <!--INDEX localization:string bundles:properties -->  <!--INDEX string bundles:localization:properties -->  <!--INDEX user interface:localization:string bundle properties --> binding properties that are exposed to your script accompany the methods. These properties are not often needed for routine retrieval of string values, but are useful to know nonetheless if you ever need to discover or share the meta information related to your bundle and locale.    Properties</h3>
<H5><A NAME="77049"></A> stringBundle</H5>    <p>Defining your bundle in XUL and then creating the file with
<P>This  <!--INDEX StringBundle property --> property is the string bundle object that queries the <I>nsIStringBundleService</I> interfaces and initializes the XPCOM interface, making methods available to it. It is the direct way of getting a string from a bundle:    the values is only half the story. This section shows how to
<PRE>var appBundle = document.getElementById("bundle_app");    extract the values from the bundle and place them in UI. The
return appBundle.stringBundle.GetStringFromName("chapter11");</PRE>    language of choice in these examples is JavaScript. This
<H5><A NAME="77050"></A> src</H5>    process is necessary when you have to change values in the UI
<P>This property <!--INDEX src property -->  is the attribute used to get and set the properties file that will be used as a string bundle:    because DTD entities can not be updated dynamically.</p>
<PRE>var appBundle = document.getElementById("bundle_app");    <h4><a name="77045"></a> Methods</h4>
dump("You are using the properties file " + appBundle.src);</PRE>    <p>Our bundle <!--INDEX methods:string bundles --> 
<H3><A NAME="77051"></A> Creating Your Own Bundle</H3>    <!--INDEX localization:string bundles:methods --> 
<P>The implementation  <!--INDEX string bundles:creating -->  <!--INDEX localization:string bundles:creating --> for setting up your string bundle just described is hidden from the XUL author. You only need to point at the bundle you want to use by using the source attribute. There is however, an alternative way to do this if you do not favor using <TT>&lt;stringbundle&gt;</TT> or would like to extend that binding.    <!--INDEX string bundles:localization:methods --> 
<P>The alternative is to use utility routines that come bundled with Mozilla and are contained in a string resources JavaScript file: <I>strres.js</I>. With this file, creating a bundle is a three-step process.    <!--INDEX user interface:localization:string bundle methods -->
<OL><P><LI>Include the JavaScript file:<P></OL>    is defined in XUL like this:</p>
<PRE>&lt;script type="application/x-javascript"<pre>
src="chrome://global/content/strres.js"/&gt;</PRE>&lt;stringbundle id="bundle_xfly"
<OL><P><LI>Set up your bundle:<P></OL>src="chrome://xfly/locale/xfly.properties"/&gt;
<PRE>var bundle =</pre>
srGetStrBundle("chrome://mypackage/locale/mypackage.properties");</PRE>    <p>To access the methods of the bundle object in your script,
<OL><P><LI>Access the strings:<P></OL>    you have to get a handle on the XUL element by using its
<PRE>var greeting = bundle.GetStringFromName( "hello" );</PRE>    <tt>id</tt>. First declare the variable globally that will be
<P>The result retrieves the string corresponding to "hello" in your bundle file and is the equivalent of the <TT>getString</TT> call when using the XUL bundle method.    holding the bundle:</p>
<P>If your chrome is independent of Mozilla's chrome and you do not want to use their UI files, you can create the bundle directly by using the <I>nsIStringBundleService</I> XPCOM interface, as seen in <A HREF="#77014">Example 11-4</A>.<pre>
var xFlyBundle;
<P><I>Example 11-4: <A NAME="77014"></A></I></pre>
<I>Creating the bundle via XPConnect</I>    <p>Then assign the variable to the bundle. A good place to do
<PRE> var src = 'chrome://packagexfly/content/packagebundle.properties';    this is in the load handler function of your XUL window, or in
     the constructor for your binding if you are using it from
     there:</p>
 <pre>
 xFlyBundle = document.getElementById("bundle_xfly");
 </pre>
     <p>Now that you have access to the bundle, you can use the
     available methods to retrieve the strings. The two main
     functions are <tt>getString</tt> and
     <tt>getFormattedString</tt>.</p>
     <h5><a name="77046"></a> getString</h5>
     <p>The most <!--INDEX getString method --> straightforward
     string access method, <tt>getString</tt>, takes one parameter
     (namely the identifier of the string) and returns the
     localizable string value for use in the UI:</p>
 <pre>
 var readonly = xFlyBundle.getString(`readonlyFile');
 alert(readonly);
 </pre>
     <p>The string bundle entry looks like this:</p>
 <pre>
 readonlyfile=This file is read only
 </pre>
     <h5><a name="77047"></a> getFormattedString</h5>
     <p>This <!--INDEX getFormattedString method --> function takes
     an extra parameter-an array of string values, which are
     substituted into the string in the bundle. Then the full string
     with the substituted values is returned:</p>
 <pre>
 var numFiles = numberInEditor
 numFilesMsg = xflyBundle.getFormattedString("numFilesMessage", [numFiles]);
 </pre>
     <p>You can have more than one value replaced in the string,
     each one delimited within the square brackets by using a
     comma:</p>
 <pre>
 fileInfo = xflyBundle.getFormattedString("fileInformation",
 [fileName, fileSize]);
 </pre>
     <p>The string bundle entry looks like this:</p>
 <pre>
 flyFileInformation=The file is called %1$s and its size is %2$s
 </pre>
     <p>The <tt>%x</tt> numerical value refers to the ordering of
     the values to be substituted in the string. The type of the
     value is determined by the dollar ($) symbol. In this case,
     there are two possibilities-<tt>$s</tt> is a string value and
     <tt>$d</tt> is an integer value.</p>
     <h4><a name="77048"></a> Properties</h4>
     <p>Some <!--INDEX properties:string bundles --> 
     <!--INDEX localization:string bundles:properties --> 
     <!--INDEX string bundles:localization:properties --> 
     <!--INDEX user interface:localization:string bundle properties -->
     binding properties that are exposed to your script accompany
     the methods. These properties are not often needed for routine
     retrieval of string values, but are useful to know nonetheless
     if you ever need to discover or share the meta information
     related to your bundle and locale.</p>
     <h5><a name="77049"></a> stringBundle</h5>
     <p>This <!--INDEX StringBundle property --> property is the
     string bundle object that queries the
     <i>nsIStringBundleService</i> interfaces and initializes the
     XPCOM interface, making methods available to it. It is the
     direct way of getting a string from a bundle:</p>
 <pre>
 var appBundle = document.getElementById("bundle_app");
 return appBundle.stringBundle.GetStringFromName("chapter11");
 </pre>
     <h5><a name="77050"></a> src</h5>
     <p>This property <!--INDEX src property --> is the attribute
     used to get and set the properties file that will be used as a
     string bundle:</p>
 <pre>
 var appBundle = document.getElementById("bundle_app");
 dump("You are using the properties file " + appBundle.src);
 </pre>
     <h3><a name="77051"></a> Creating Your Own Bundle</h3>
     <p>The implementation <!--INDEX string bundles:creating --> 
     <!--INDEX localization:string bundles:creating --> for setting
     up your string bundle just described is hidden from the XUL
     author. You only need to point at the bundle you want to use by
     using the source attribute. There is however, an alternative
     way to do this if you do not favor using
     <tt>&lt;stringbundle&gt;</tt> or would like to extend that
     binding.</p>
     <p>The alternative is to use utility routines that come bundled
     with Mozilla and are contained in a string resources JavaScript
     file: <i>strres.js</i>. With this file, creating a bundle is a
     three-step process.</p>
     <ol>
       <li>Include the JavaScript file:</li>
     </ol>
 <pre>
 &lt;script type="application/x-javascript"
 src="chrome://global/content/strres.js"/&gt;
 </pre>
     <ol>
       <li>Set up your bundle:</li>
     </ol>
 <pre>
 var bundle =
 srGetStrBundle("chrome://mypackage/locale/mypackage.properties");
 </pre>
     <ol>
       <li>Access the strings:</li>
     </ol>
 <pre>
 var greeting = bundle.GetStringFromName( "hello" );
 </pre>
     <p>The result retrieves the string corresponding to "hello" in
     your bundle file and is the equivalent of the
     <tt>getString</tt> call when using the XUL bundle method.</p>
     <p>If your chrome is independent of Mozilla's chrome and you do
     not want to use their UI files, you can create the bundle
     directly by using the <i>nsIStringBundleService</i> XPCOM
     interface, as seen in <a href="#77014">Example 11-4</a>.</p>
     <p><i>Example 11-4: <a name="77014"></a></i> <i>Creating the
     bundle via XPConnect</i></p>
 <pre>
  var src = 'chrome://packagexfly/content/packagebundle.properties';
  var localeService =   var localeService =
     Components.classes</TD>["@mozilla.org/intl/nslocaleservice;1"]     Components.classes&lt;/td&gt;["@mozilla.org/intl/nslocaleservice;1"]
     .getService(Components.interfaces.nsILocaleService</TD>);     .getService(Components.interfaces.nsILocaleService&lt;/td&gt;);
  var appLocale =  localeService.GetApplicationLocale( );   var appLocale =  localeService.GetApplicationLocale( );
  var stringBundleService =   var stringBundleService =
     Components.classes</TD>["@mozilla.org/intl/stringbundle;1"]     Components.classes&lt;/td&gt;["@mozilla.org/intl/stringbundle;1"]
     .getService(Components.interfaces.nsIStringBundleService</TD>);     .getService(Components.interfaces.nsIStringBundleService&lt;/td&gt;);
 bundle = stringBundleService.CreateBundle(src, appLocale);</PRE> bundle = stringBundleService.CreateBundle(src, appLocale);
</pre>
<P>The first step is to get the application locale-the language that is currently registered with the chrome service. This is done via the <TT>nsILocalService</TT> component. The <I>nsIStringBundleService</I> is then initialized and the <TT>CreateBundle</TT> method is called, returning an instance of <I>nsIStringBundle</I> that provides access to the methods for querying strings.    <p>The first step is to get the application locale-the language
<H2><A NAME="77052"></A> Programming and Localization</H2>    that is currently registered with the chrome service. This is
<P>This section provides little nuggets of information, not necessarily related, that show how to work around common problems when programming locale-related information in your application. It strays a little from the main path of string replacement and translation, and the topics vary from recommended naming conventions for your string identifiers to locale in XBL bindings and what tools you can use to be more productive.    done via the <tt>nsILocalService</tt> component. The
<H3><A NAME="77053"></A> Naming Conventions</H3>    <i>nsIStringBundleService</i> is then initialized and the
<P>The decision <!--INDEX programming localization:naming conventions -->  <!--INDEX localization:programming:naming conventions -->  <!--INDEX     <tt>CreateBundle</tt> method is called, returning an instance
naming conventions, localization -->  of what to call your code internals emerged more than once in this book. In <A HREF="ch08.html#77048">Chapter 8</A>, you decided the name of the component IDL interface IDL file and its associated implementation. In locale, it is the entity names and string identifiers contained in bundles.    of <i>nsIStringBundle</i> that provides access to the methods
<P>Naming conventions in localization are useful because they provide some context to the translator. In this spirit, it is good for the reference to be as descriptive as possible. You can choose your route for naming or stick with the way that Mozilla does it. Examining the files in the Mozilla source base, common naming conventions for entities include the following:    for querying strings.</p>
<BLOCKQUOTE>id.label    <h2><a name="77052"></a> Programming and Localization</h2>
id.tooltip    <p>This section provides little nuggets of information, not
id.text    necessarily related, that show how to work around common
id.accesskey    problems when programming locale-related information in your
id.commandkey</BLOCKQUOTE>    application. It strays a little from the main path of string
<P>Certain XUL widgets can contain multiple localizable resources, including a text <TT>label</TT> or <TT>description</TT>, a <TT>tooltip</TT>, and an <TT>accesskey</TT>. A button is a prime example:    replacement and translation, and the topics vary from
<PRE>&lt;button id="flyBtn" label="&amp;flyBtn.label;" accesskey="&amp;flyBtn.accesskey;"    recommended naming conventions for your string identifiers to
tooltip="&amp;flyBtn.tooltip;" /&gt;</PRE>    locale in XBL bindings and what tools you can use to be more
<P>The naming convention is consistent, using the value of the <TT>id</TT> attribute appended by the name of the UI feature. The attribute and name are delimited by a period. Not only does using this value flag the resource as being associated with a certain widget, but it also permits logical grouping in the DTD:    productive.</p>
<PRE>&lt;!ENTITY flyBtn.label "Fly Away"&gt;    <h3><a name="77053"></a> Naming Conventions</h3>
     <p>The decision 
     <!--INDEX programming localization:naming conventions --> 
     <!--INDEX localization:programming:naming conventions --> 
     <!--INDEX 
     naming conventions, localization --> of what to call your code
     internals emerged more than once in this book. In <a href=
     "ch08.html#77048">Chapter 8</a>, you decided the name of the
     component IDL interface IDL file and its associated
     implementation. In locale, it is the entity names and string
     identifiers contained in bundles.</p>
     <p>Naming conventions in localization are useful because they
     provide some context to the translator. In this spirit, it is
     good for the reference to be as descriptive as possible. You
     can choose your route for naming or stick with the way that
     Mozilla does it. Examining the files in the Mozilla source
     base, common naming conventions for entities include the
     following:</p>
     <blockquote>
       id.label id.tooltip id.text id.accesskey id.commandkey
     </blockquote>
     <p>Certain XUL widgets can contain multiple localizable
     resources, including a text <tt>label</tt> or
     <tt>description</tt>, a <tt>tooltip</tt>, and an
     <tt>accesskey</tt>. A button is a prime example:</p>
 <pre>
 &lt;button id="flyBtn" label="&amp;flyBtn.label;" accesskey="&amp;flyBtn.accesskey;"
 tooltip="&amp;flyBtn.tooltip;" /&gt;
 </pre>
     <p>The naming convention is consistent, using the value of the
     <tt>id</tt> attribute appended by the name of the UI feature.
     The attribute and name are delimited by a period. Not only does
     using this value flag the resource as being associated with a
     certain widget, but it also permits logical grouping in the
     DTD:</p>
 <pre>
 &lt;!ENTITY flyBtn.label "Fly Away"&gt;
 &lt;!ENTITY flyBtn.accesskey "f"&gt;  &lt;!ENTITY flyBtn.accesskey "f"&gt;
&lt;!ENTITY flyBtn.tooltip "Click here to take to the air"&gt;</PRE>&lt;!ENTITY flyBtn.tooltip "Click here to take to the air"&gt;
<P>Naming string identifiers in bundle files fits less into a pattern like that in DTDs, and in the Mozilla, source files may appear random. If a pattern must be found, you could look at two things: filenames and identifier descriptions.</pre>
<P>In a filename, the association of a single <I>.properties</I> file is with a logical part of the application. If a string appears in a certain dialog or window, you know where to go to translate the strings or add more strings. Example files in the Mozilla tree worth examining include <I>editor.properties</I>, <I>commonDialogs.properties</I>, and <I>wizardManager.properties</I>.    <p>Naming string identifiers in bundle files fits less into a
<P>With identifier descriptions, the text used on the identifier describes what the text actually refers to. The goal is to be as descriptive as possible by using as brief text as possible:    pattern like that in DTDs, and in the Mozilla, source files may
<PRE>dontDeleteFiles=Don't Delete Files</PRE>    appear random. If a pattern must be found, you could look at
<P>The descriptor is the same as the value, although in a different format. The opportunity was taken here to be as descriptive as possible.    two things: filenames and identifier descriptions.</p>
<H3><A NAME="77054"></A> Breaking Up the Text</H3>    <p>In a filename, the association of a single
<P>Under certain  <!--INDEX programming localization:line breaks in messages -->  <!--INDEX localization:programming:line breaks in messages -->  <!--INDEX message localization, line breaks --> circumstances, you may need to pop up your own alert messages as XUL dialogs. Some messages may involve multiple lines of text that need to be put on new lines. There is no natural delimiter that breaks up the text contained within <TT>&lt;description&gt;</TT> or <TT>&lt;label&gt;</TT> elements in XUL, so following are a couple of tricks to get around this problem.    <i>.properties</i> file is with a logical part of the
<H4><A NAME="77055"></A> Method 1: Multiple &lt;description&gt; elements</H4>    application. If a string appears in a certain dialog or window,
<P>First, create  <!--INDEX description element, localization programming considerations --> the placeholder in your XUL where the generated elements will be inserted:    you know where to go to translate the strings or add more
<PRE>&lt;vbox id="main-message" flex="1" style="max-width: 40em;"/&gt;    strings. Example files in the Mozilla tree worth examining
     include <i>editor.properties</i>,
     <i>commonDialogs.properties</i>, and
     <i>wizardManager.properties</i>.</p>
     <p>With identifier descriptions, the text used on the
     identifier describes what the text actually refers to. The goal
     is to be as descriptive as possible by using as brief text as
     possible:</p>
 <pre>
 dontDeleteFiles=Don't Delete Files
 </pre>
     <p>The descriptor is the same as the value, although in a
     different format. The opportunity was taken here to be as
     descriptive as possible.</p>
     <h3><a name="77054"></a> Breaking Up the Text</h3>
     <p>Under certain 
     <!--INDEX programming localization:line breaks in messages --> 
     <!--INDEX localization:programming:line breaks in messages --> 
     <!--INDEX message localization, line breaks --> circumstances,
     you may need to pop up your own alert messages as XUL dialogs.
     Some messages may involve multiple lines of text that need to
     be put on new lines. There is no natural delimiter that breaks
     up the text contained within <tt>&lt;description&gt;</tt> or
     <tt>&lt;label&gt;</tt> elements in XUL, so following are a
     couple of tricks to get around this problem.</p>
     <h4><a name="77055"></a> Method 1: Multiple &lt;description&gt;
     elements</h4>
     <p>First, create 
     <!--INDEX description element, localization programming considerations -->
     the placeholder in your XUL where the generated elements will
     be inserted:</p>
 <pre>
 &lt;vbox id="main-message" flex="1" style="max-width: 40em;"/&gt;
 &lt;!-- insert elements here --&gt;  &lt;!-- insert elements here --&gt;
&lt;/vbox&gt;</PRE>&lt;/vbox&gt;
<P>The script in <A HREF="#77016">Example 11-5</A> generates the needed text elements, fills in the text, and appends all the items to the containing box.</pre>
    <p>The script in <a href="#77016">Example 11-5</a> generates
<P><I>Example 11-5: <A NAME="77016"></A></I>    the needed text elements, fills in the text, and appends all
<I>Using multiple &lt;description&gt; elements</I>    the items to the containing box.</p>
<PRE> var text = window.arguments</TD>[0];    <p><i>Example 11-5: <a name="77016"></a></i> <i>Using multiple
     &lt;description&gt; elements</i></p>
 <pre>
  var text = window.arguments&lt;/td&gt;[0];
  var holder = document.getElementById("main-message");   var holder = document.getElementById("main-message");
  var lines = text.split("\n");   var lines = text.split("\n");
  for (var i = 0; i &lt; lines.length; i++) {   for (var i = 0; i &lt; lines.length; i++) {
    var descriptionNode = document.createElement("description");     var descriptionNode = document.createElement("description");
   var linetext = document.createTextNode(messageParagraphs</TD>[i]);   var linetext = document.createTextNode(messageParagraphs&lt;/td&gt;[i]);
    descriptionNode.appendChild(linetext);     descriptionNode.appendChild(linetext);
    holder.appendChild(descriptionNode);     holder.appendChild(descriptionNode);
 }</PRE> }
</pre>
<P>The text is passed into the window that is used for the message. It presumes that the <TT>\n</TT> delimiter is used to signify a new line in the text and is split thus. Then it loops through each line, creating a description element for each line and populating it with a text node with the message inside. Then each element is appended to the main container that lives in the XUL file.    <p>The text is passed into the window that is used for the
<H4><A NAME="77056"></A> Method 2: HTML &lt;br&gt; tag</H4>    message. It presumes that the <tt>\n</tt> delimiter is used to
<P>For this example,  <!--INDEX br element, localization programming considerations --> create the XUL placeholder similar to the example in Method 1, and then slot the script in <A HREF="#77018">Example 11-6</A> into your load handler.    signify a new line in the text and is split thus. Then it loops
    through each line, creating a description element for each line
<P><I>Example 11-6: <A NAME="77018"></A></I>    and populating it with a text node with the message inside.
<I>Using the HTML break tag</I>    Then each element is appended to the main container that lives
<PRE> var text = window.arguments</TD>[0];    in the XUL file.</p>
     <h4><a name="77056"></a> Method 2: HTML &lt;br&gt; tag</h4>
     <p>For this example, 
     <!--INDEX br element, localization programming considerations -->
     create the XUL placeholder similar to the example in Method 1,
     and then slot the script in <a href="#77018">Example 11-6</a>
     into your load handler.</p>
     <p><i>Example 11-6: <a name="77018"></a></i> <i>Using the HTML
     break tag</i></p>
 <pre>
  var text = window.arguments&lt;/td&gt;[0];
  var holder = document.getElementById("main-message");   var holder = document.getElementById("main-message");
  var lines = text.split("\n");   var lines = text.split("\n");
  var descriptionNode = document.createElement("description");   var descriptionNode = document.createElement("description");
  for (var i = 0; i &lt; lines.length; i++) {   for (var i = 0; i &lt; lines.length; i++) {
   var linetext = document.createTextNode(messageParagraphs</TD>[i]);   var linetext = document.createTextNode(messageParagraphs&lt;/td&gt;[i]);
    var breakNode = document.createElement("html:br");     var breakNode = document.createElement("html:br");
    descriptionNode.appendChild(linetext);     descriptionNode.appendChild(linetext);
    descriptionNode.appendChild(breakNode);     descriptionNode.appendChild(breakNode);
  }   }
 holder.appendChild(descriptionNode);</PRE> holder.appendChild(descriptionNode);
</pre>
<P>This way is similar to the code in <A HREF="#77016">Example 11-5</A>, with some notable differences. First, there is only one <TT>&lt;description&gt;</TT> element created outside the loop for each new line. In that loop, the break occurs when an HTML <TT>&lt;br&gt;</TT> element is inserted after a piece of text.    <p>This way is similar to the code in <a href="#77016">Example
<P>With both methods, you need to put some sort of width constraint on the window at the level where you want the text to wrap. Method 1 is recommended because it is a true XUL solution, but the second method is also a good example of mixed markup in a XUL document (HTML).    11-5</a>, with some notable differences. First, there is only
<H3><A NAME="77057"></A> Anonymous Content and Locale</H3>    one <tt>&lt;description&gt;</tt> element created outside the
<P>Entities are everywhere. Well, not quite everywhere. However, as entity references and DTD constructs are part of the XML language, they can be used for localization purposes in other files in your package, such as RDF and XBL files.    loop for each new line. In that loop, the break occurs when an
<P>In the case of XBL, it is common for  <!--INDEX binding content, localization -->  <!--INDEX localization:binding content --> binding content to inherit its locale information from the base widget. Take the <A HREF="#77020">Example 11-7</A> as a case in point. Here is the bound element in the XUL document; the binding for the bound element is shown:    HTML <tt>&lt;br&gt;</tt> element is inserted after a piece of
<PRE>&lt;article id="artheader" class="articleheader" title="Common Garden Flies" author="Brad Buzzworth"/&gt;</PRE>    text.</p>
<P>The attributes of note here are <TT>title</TT> and <TT>author</TT>, both user-defined, because they contain the localizable values that will be used in the binding.    <p>With both methods, you need to put some sort of width
    constraint on the window at the level where you want the text
<P><I>Example 11-7: <A NAME="77020"></A></I>    to wrap. Method 1 is recommended because it is a true XUL
<I>Binding with attribute inheritance</I>    solution, but the second method is also a good example of mixed
<PRE> &lt;binding id="articleheader"&gt;    markup in a XUL document (HTML).</p>
     <h3><a name="77057"></a> Anonymous Content and Locale</h3>
     <p>Entities are everywhere. Well, not quite everywhere.
     However, as entity references and DTD constructs are part of
     the XML language, they can be used for localization purposes in
     other files in your package, such as RDF and XBL files.</p>
     <p>In the case of XBL, it is common for 
     <!--INDEX binding content, localization --> 
     <!--INDEX localization:binding content --> binding content to
     inherit its locale information from the base widget. Take the
     <a href="#77020">Example 11-7</a> as a case in point. Here is
     the bound element in the XUL document; the binding for the
     bound element is shown:</p>
 <pre>
 &lt;article id="artheader" class="articleheader" title="Common Garden Flies" author="Brad Buzzworth"/&gt;
 </pre>
     <p>The attributes of note here are <tt>title</tt> and
     <tt>author</tt>, both user-defined, because they contain the
     localizable values that will be used in the binding.</p>
     <p><i>Example 11-7: <a name="77020"></a></i> <i>Binding with
     attribute inheritance</i></p>
 <pre>
  &lt;binding id="articleheader"&gt;
    &lt;content&gt;     &lt;content&gt;
      &lt;xul:hbox flex="1"&gt;       &lt;xul:hbox flex="1"&gt;
       &lt;xul:label class="flybox-homeheader-text" xbl:inherits="value=title"</TD>/&gt;       &lt;xul:label class="flybox-homeheader-text" xbl:inherits="value=title"&lt;/td&gt;/&gt;
        &lt;xul:spacer flex="1"/&gt;         &lt;xul:spacer flex="1"/&gt;
       &lt;xul:label class="flybox-homeheader-text" xbl:inherits="value=author"</TD>/&gt;       &lt;xul:label class="flybox-homeheader-text" xbl:inherits="value=author"&lt;/td&gt;/&gt;
      &lt;/xul:hbox&gt;       &lt;/xul:hbox&gt;
    &lt;/content&gt;     &lt;/content&gt;
    &lt;implementation&gt;     &lt;implementation&gt;
      &lt;property name="title"&gt;       &lt;property name="title"&gt;
        &lt;setter&gt;         &lt;setter&gt;
         &lt;!</TD>[CDATA[         &lt;!&lt;/td&gt;[CDATA[
            this.setAttribute('title',val); return val;             this.setAttribute('title',val); return val;
          ]]&gt;           ]]&gt;
        &lt;/setter&gt;         &lt;/setter&gt;
        &lt;getter&gt;         &lt;getter&gt;
         &lt;!</TD>[CDATA[         &lt;!&lt;/td&gt;[CDATA[
            return this.getAttribute('title');             return this.getAttribute('title');
          ]]&gt;           ]]&gt;
        &lt;/getter&gt;         &lt;/getter&gt;
      &lt;/property&gt;       &lt;/property&gt;
      &lt;property name="author"&gt;       &lt;property name="author"&gt;
        &lt;setter&gt;         &lt;setter&gt;
         &lt;!</TD>[CDATA[         &lt;!&lt;/td&gt;[CDATA[
            this.setAttribute('author',val); return val;             this.setAttribute('author',val); return val;
          ]]&gt;           ]]&gt;
        &lt;/setter&gt;         &lt;/setter&gt;
        &lt;getter&gt;         &lt;getter&gt;
         &lt;!</TD>[CDATA[         &lt;!&lt;/td&gt;[CDATA[
            return this.getAttribute('author');             return this.getAttribute('author');
          ]]&gt;           ]]&gt;
        &lt;/getter&gt;         &lt;/getter&gt;
      &lt;/property&gt;       &lt;/property&gt;
    &lt;/implementation&gt;     &lt;/implementation&gt;
 &lt;/binding&gt;</PRE> &lt;/binding&gt;
</pre>
<P>The binding in <A HREF="#77020">Example 11-7</A> illustrates a binding whose content inherits its locale from the bound element. The attributes used on the bound element, namely <TT>title</TT> and <TT>author</TT>, are descriptive, enabling the author to be specific about what they are setting a value to. The rest is taken care of in the binding, where the <TT>inherits</TT> attribute sets the value on the anonymous content to the value of the more descriptive attributes on the bound element. You can retrieve the values or set them by using the getter and setter.    <p>The binding in <a href="#77020">Example 11-7</a> illustrates
<BLOCKQUOTE><HR><A NAME="92113"></A> Localization  <!--INDEX localization:tools --> Tools    a binding whose content inherits its locale from the bound
<P>To translate your XUL interface strings, just change the text that corresponds to your entity reference or string bundle value. For a small application, this step should be simple, but for large applications, it can be a big task.    element. The attributes used on the bound element, namely
<P>The good news is that tools are available to help localize your applications. The most popular tool is MozillaTranslator, which is discussed in     <tt>title</tt> and <tt>author</tt>, are descriptive, enabling
more detail in <A HREF="appb.html#77021">Appendix B</A>.    the author to be specific about what they are setting a value
<P>There is also a handy command line utility for Unicode conversion called nsconv, bundled in the Mozilla <I>bin</I> folder in any distribution. (If you are unfamiliar with Unicode, the section <A HREF="#77067">"XPFE and Unicode</A>" later in this chapter provides more information.) Although it is broken at the time of this writing, it is worth mentioning. Let's look at a simple conversion of ASCII text to UTF-8:    to. The rest is taken care of in the binding, where the
<PRE>&lt;!ENTITY PrintPreviewCmd.label    "Print Preview"&gt;</PRE>    <tt>inherits</tt> attribute sets the value on the anonymous
Replace the string in the entity with the Spanish version:    content to the value of the more descriptive attributes on the
<PRE>&lt;!ENTITY PrintPreviewCmd.label    "Presentacin preliminar..."&gt;</PRE>    bound element. You can retrieve the values or set them by using
Then run the conversion.    the getter and setter.</p>
<PRE>&gt; nsconv -f ascii -t utf-8 foo.dtd bar.dtd</PRE>    <blockquote>
The accented characters are converted into the Unicode for you:      <hr>
<PRE>&lt;!ENTITY PrintPreviewCmd.label   "Presentaci&amp;#243;n preliminar..."&gt;</PRE>      <a name="92113"></a> Localization 
Using the NCR or CER value as well is also acceptable, if appropriate. A NCR is an entity that contains a hex (<TT>&amp;#x61;</TT>) or decimal (<TT>&amp;#97;</TT>) value, while a CER is also an entity containing an abbreviation (<TT>&amp;eacute;</TT>). This assumes, though, that you know what the code is! String bundles accept only one form of encoding, which is known as <TT>escape-unicode</TT>. If using nsconv, the name for this encoding is <TT>x-u-escaped</TT>.      <!--INDEX localization:tools --> Tools 
<P>Various third-party conversion tools that do the same thing are available. A freeware editor called Unipad that lets you import multiple types of native encoding documents and then save as Unicode. Unipad is available from <I><A HREF="http://www.unipad.org/">http://www.unipad.org/</A></I>.<HR></BLOCKQUOTE>      <p>To translate your XUL interface strings, just change the
      text that corresponds to your entity reference or string
<H3><A NAME="77058"></A> Localizable Resources in HTML</H3>      bundle value. For a small application, this step should be
<P>As a web  <!--INDEX localization:HTML and -->  <!--INDEX HTML (Hypertext Markup Language):localization and --> application, Mozilla permits seamless integration of web content, both local and remote, in many formats. If you have verbose text that just needs to be displayed somewhere in the framework of your application, HTML or XML content may be ideal for this purpose. Through the use of XUL content widgets, such as <TT>&lt;iframe&gt;</TT> and <TT>&lt;browser&gt;</TT>, you have ready-made frames to slot your content into:      simple, but for large applications, it can be a big task.</p>
<PRE>&lt;iframe src="xFly.html" flex="1"/&gt;</PRE>      <p>The good news is that tools are available to help localize
<P>Therefore, a simple modification of <I>xFly.html</I> with a local language leaves the main application untouched. Some other uses of HTML or XML content include an "About" dialog/page, Help pages, a wizard interface, or a getting started/introduction page.      your applications. The most popular tool is
<H3><A NAME="77059"></A> Localizable Resources in RDF</H3>      MozillaTranslator, which is discussed in more detail in <a
<P>Strings to be <!--INDEX RDF (Resource Description Framework):localization and -->  <!--INDEX localization:RDF and -->  converted in RDF content can take more than one form. You can use entities directly in your RDF file or have the text inline in your node descriptions. Whichever method you choose, you must ensure that the file is installed in the right place in the tree and registered correctly for the application to pick up on it.      href="appb.html#77021">Appendix B</a>.</p>
<P>As an XML markup, RDF can handle inline entity definitions. These entity definitions have been covered thoroughly in the chapter so far. <A HREF="#77022">Example 11-8</A> looks at localizable strings contained directly in RDF node descriptions. This example is taken from the Help table of contents in the Mozilla tree.      <p>There is also a handy command line utility for Unicode
      conversion called nsconv, bundled in the Mozilla <i>bin</i>
<P><I>Example 11-8: <A NAME="77022"></A></I>      folder in any distribution. (If you are unfamiliar with
<I>RDF Description node with localizable text</I>      Unicode, the section <a href="#77067">"XPFE and Unicode</a>"
<PRE> &lt;rdf:Description about="#nav-doc"&gt;      later in this chapter provides more information.) Although it
       is broken at the time of this writing, it is worth
       mentioning. Let's look at a simple conversion of ASCII text
       to UTF-8:</p>
 <pre>
 &lt;!ENTITY PrintPreviewCmd.label    "Print Preview"&gt;
 </pre>
       Replace the string in the entity with the Spanish version: 
 <pre>
 &lt;!ENTITY PrintPreviewCmd.label    "Presentaci&oacute;n preliminar..."&gt;
 </pre>
       Then run the conversion. 
 <pre>
 &gt; nsconv -f ascii -t utf-8 foo.dtd bar.dtd
 </pre>
       The accented characters are converted into the Unicode for
       you: 
 <pre>
 &lt;!ENTITY PrintPreviewCmd.label   "Presentaci&amp;#243;n preliminar..."&gt;
 </pre>
       Using the NCR or CER value as well is also acceptable, if
       appropriate. A NCR is an entity that contains a hex
       (<tt>&amp;#x61;</tt>) or decimal (<tt>&amp;#97;</tt>) value,
       while a CER is also an entity containing an abbreviation
       (<tt>&amp;eacute;</tt>). This assumes, though, that you know
       what the code is! String bundles accept only one form of
       encoding, which is known as <tt>escape-unicode</tt>. If using
       nsconv, the name for this encoding is <tt>x-u-escaped</tt>. 
       <p>Various third-party conversion tools that do the same
       thing are available. A freeware editor called Unipad that
       lets you import multiple types of native encoding documents
       and then save as Unicode. Unipad is available from <i><a
       href=
       "http://www.unipad.org/">http://www.unipad.org/</a></i>.</p>
       <hr>
     </blockquote>
     <h3><a name="77058"></a> Localizable Resources in HTML</h3>
     <p>As a web <!--INDEX localization:HTML and --> 
     <!--INDEX HTML (Hypertext Markup Language):localization and -->
     application, Mozilla permits seamless integration of web
     content, both local and remote, in many formats. If you have
     verbose text that just needs to be displayed somewhere in the
     framework of your application, HTML or XML content may be ideal
     for this purpose. Through the use of XUL content widgets, such
     as <tt>&lt;iframe&gt;</tt> and <tt>&lt;browser&gt;</tt>, you
     have ready-made frames to slot your content into:</p>
 <pre>
 &lt;iframe src="xFly.html" flex="1"/&gt;
 </pre>
     <p>Therefore, a simple modification of <i>xFly.html</i> with a
     local language leaves the main application untouched. Some
     other uses of HTML or XML content include an "About"
     dialog/page, Help pages, a wizard interface, or a getting
     started/introduction page.</p>
     <h3><a name="77059"></a> Localizable Resources in RDF</h3>
     <p>Strings to be 
     <!--INDEX RDF (Resource Description Framework):localization and -->
     <!--INDEX localization:RDF and --> converted in RDF content can
     take more than one form. You can use entities directly in your
     RDF file or have the text inline in your node descriptions.
     Whichever method you choose, you must ensure that the file is
     installed in the right place in the tree and registered
     correctly for the application to pick up on it.</p>
     <p>As an XML markup, RDF can handle inline entity definitions.
     These entity definitions have been covered thoroughly in the
     chapter so far. <a href="#77022">Example 11-8</a> looks at
     localizable strings contained directly in RDF node
     descriptions. This example is taken from the Help table of
     contents in the Mozilla tree.</p>
     <p><i>Example 11-8: <a name="77022"></a></i> <i>RDF Description
     node with localizable text</i></p>
 <pre>
  &lt;rdf:Description about="#nav-doc"&gt;
    &lt;nc:subheadings&gt;     &lt;nc:subheadings&gt;
      &lt;rdf:Seq&gt;       &lt;rdf:Seq&gt;
        &lt;rdf:li&gt;         &lt;rdf:li&gt;
          &lt;rdf:Description ID="nav-doc-language"           &lt;rdf:Description ID="nav-doc-language"
                </TD>nc:name="Language and Translation Services"                &lt;/td&gt;nc:name="Language and Translation Services"
                 nc:link="chrome://help/locale/nav_help.html#nav_language"/&gt;                  nc:link="chrome://help/locale/nav_help.html#nav_language"/&gt;
        &lt;/rdf:li&gt;         &lt;/rdf:li&gt;
      &lt;/rdf:Seq&gt;       &lt;/rdf:Seq&gt;
    &lt;/nc:subheadings&gt;     &lt;/nc:subheadings&gt;
 &lt;/rdf:Description&gt;</PRE> &lt;/rdf:Description&gt;
</pre>
<P>The text in the <TT>nc:name</TT> attribute is the text that will be changed. Note that this issue of text in RDF is separate from the topic of using RDF as the mechanism in the chrome registry to register your locale and set up a switching mechanism. This difference is addressed in the next section.    <p>The text in the <tt>nc:name</tt> attribute is the text that
<H2><A NAME="77060"></A> The Chrome Registry and Locale</H2>    will be changed. Note that this issue of text in RDF is
<P>Your application is built and you're ready to upload your shiny new Mozilla program to your server for download. The last piece of the puzzle, locale versions, has been put in place. With the structures that Mozilla has in place, it no longer has to be an afterthought. Once you have the translated files, you need to make the decision about how you want to distribute your language versions, the languages you want to make available to the users, and the level of customization that you want to give to them.    separate from the topic of using RDF as the mechanism in the
<P>In this section, we look at how the Mozilla application suite handles the chrome's locale component. Then you see how to apply these chrome registry structures and utilities on a more generic level for your application.    chrome registry to register your locale and set up a switching
<H3><A NAME="77061"></A> The Directory Structure</H3>    mechanism. This difference is addressed in the next
<P>A typical  <!--INDEX localization:chrome directory structure -->  <!--INDEX chrome:localization:directory structure --> application chrome structure looks like the directory structure in <A HREF="#77004">Figure 11-2</A>. A folder for each language is under the <I>locale</I> directory. The general format is that each language has a unique identifier based on country code and the region. This conforms to the ISO-639 two-letter code with ISO-3166 two-letter country code standards.    section.</p>
<BLOCKQUOTE><CENTER><B>NOTE</B></CENTER>    <h2><a name="77060"></a> The Chrome Registry and Locale</h2>
<P>The W3C site has good resources that provide information about the ISO-639 and ISO-3166 standards at <I><A HREF="http://www.w3.org/International/O-HTML-tags.html">http://www.w3.org/International/O-HTML-tags.html</A></I>.<P></BLOCKQUOTE>    <p>Your application is built and you're ready to upload your
<P>For example, the unique identifier for Scots, Great Britain, is <I>Sc-GB</I>. The first code, <I>Sc</I>, is for the Scots (Scottish) dialect, and the second code, <I>GB</I>, is for the country code for Great Britain. This is the standard that Mozilla follows.    shiny new Mozilla program to your server for download. The last
<P><CENTER><IMG SRC="foo.gif"></CENTER>    piece of the puzzle, locale versions, has been put in place.
<P><I>Figure 11-2: <A NAME="77004"></A></I>    With the structures that Mozilla has in place, it no longer has
<I>Locale's placement in typical chrome layout</I>    to be an afterthought. Once you have the translated files, you
    need to make the decision about how you want to distribute your
<P>The folder that is registered is the language folder, which is what has to be changed on an install. Thus, the URL <I>chrome://package/locale</I> actually points to <I>package/locale/en-US</I> or whichever language is turned on at the time. The language folder may in turn include subfolders that contain logical units for your application.    language versions, the languages you want to make available to
<H3><A NAME="77062"></A> Interaction with the Chrome Registry</H3>    the users, and the level of customization that you want to give
<P>As pointed  <!--INDEX localization:chrome registry -->  <!--INDEX chrome:localization:registry --> out in <A HREF="ch06.html#77063">Chapter     to them.</p>
6</A>, your packages directories need to be registered as chrome with the chrome registry. The first step is to ensure that the entry for your package component is in the file <I>chrome.rdf</I> in the root chrome directory.    <p>In this section, we look at how the Mozilla application
<P>A <I>resource:/</I> URL points to the folder for your files to be picked up and recognized by the chrome mechanism and accessed via <I>chrome://</I> URLs in your application code. The locale is no exception.    suite handles the chrome's locale component. Then you see how
<PRE>&lt;RDF:Description about="urn:mozilla:locale:en-US:xfly"    to apply these chrome registry structures and utilities on a
     more generic level for your application.</p>
     <h3><a name="77061"></a> The Directory Structure</h3>
     <p>A typical 
     <!--INDEX localization:chrome directory structure --> 
     <!--INDEX chrome:localization:directory structure -->
     application chrome structure looks like the directory structure
     in <a href="#77004">Figure 11-2</a>. A folder for each language
     is under the <i>locale</i> directory. The general format is
     that each language has a unique identifier based on country
     code and the region. This conforms to the ISO-639 two-letter
     code with ISO-3166 two-letter country code standards.</p>
     <blockquote>
       <div class="c24">
         NOTE
       </div>
       <p>The W3C site has good resources that provide information
       about the ISO-639 and ISO-3166 standards at <i><a href=
       "http://www.w3.org/International/O-HTML-tags.html">http://www.w3.org/International/O-HTML-tags.html</a></i>.</p>
     </blockquote>
     <p>For example, the unique identifier for Scots, Great Britain,
     is <i>Sc-GB</i>. The first code, <i>Sc</i>, is for the Scots
     (Scottish) dialect, and the second code, <i>GB</i>, is for the
     country code for Great Britain. This is the standard that
     Mozilla follows.</p>
     <div class="c23">
       <img src="foo.gif">
     </div>
     <p><i>Figure 11-2: <a name="77004"></a></i> <i>Locale's
     placement in typical chrome layout</i></p>
     <p>The folder that is registered is the language folder, which
     is what has to be changed on an install. Thus, the URL
     <i>chrome://package/locale</i> actually points to
     <i>package/locale/en-US</i> or whichever language is turned on
     at the time. The language folder may in turn include subfolders
     that contain logical units for your application.</p>
     <h3><a name="77062"></a> Interaction with the Chrome
     Registry</h3>
     <p>As pointed <!--INDEX localization:chrome registry --> 
     <!--INDEX chrome:localization:registry --> out in <a href=
     "ch06.html#77063">Chapter 6</a>, your packages directories need
     to be registered as chrome with the chrome registry. The first
     step is to ensure that the entry for your package component is
     in the file <i>chrome.rdf</i> in the root chrome directory.</p>
     <p>A <i>resource:/</i> URL points to the folder for your files
     to be picked up and recognized by the chrome mechanism and
     accessed via <i>chrome://</i> URLs in your application code.
     The locale is no exception.</p>
 <pre>
 &lt;RDF:Description about="urn:mozilla:locale:en-US:xfly"
 c:baseURL="resource:/chrome/xfly/locale/en-US/"&gt;  c:baseURL="resource:/chrome/xfly/locale/en-US/"&gt;
 c:localeVersion="0.1.0.0"  c:localeVersion="0.1.0.0"
 &lt;c:package resource="urn:mozilla:package:xfly"/&gt;  &lt;c:package resource="urn:mozilla:package:xfly"/&gt;
&lt;/RDF:Description&gt;</PRE>&lt;/RDF:Description&gt;
<P>A built-in versioning system in the chrome registry uses <I>c:localeVersion</I> descriptor, if you plan on distributing multiple language packs for your application. Other descriptors are available if you choose to use them: display name (<I>c:displayName</I>), internal name (<I>c:name</I>), location type (<I>c:locType</I>), and author (<I>c:author</I>).</pre>
<H3><A NAME="77063"></A> Distribution</H3>    <p>A built-in versioning system in the chrome registry uses
<P>Language d <!--INDEX localization:distrubution issues -->  <!--INDEX distribution:localization issues --> istribution may not be an issue for you. If, for example, your application were only going to be localized into a finite number of languages, bundling each of them up with the main installer would be most convenient. If, however, the need for new language versions arises at various intervals in the release process, you need to find a way to make them available and install them on top of an existing installation.    <i>c:localeVersion</i> descriptor, if you plan on distributing
<P>For example, as more people from various locations in the world are becoming aware of the Mozilla project, they want to customize it into their own language. Here are the steps that you need to take to set up your version.    multiple language packs for your application. Other descriptors
<OL><P><LI>Register as a contributor and set up the resources that you need, if any (web page, mailing list). This will ensure that you are added to the project page on the mozilla.org site.<P>    are available if you choose to use them: display name
<P><LI>Get a copy of Mozilla to test either via a binary distribution or by downloading and building your own source (see <    (<i>c:displayName</i>), internal name (<i>c:name</i>), location
HREF="appa.html#90096">Appendix A</A> for more information).<P>    type (<i>c:locType</i>), and author (<i>c:author</i>).</p>
<P><LI>Translate the files.<P>    <h3><a name="77063"></a> Distribution</h3>
<P><LI>Package your new files for distribution.<P>    <p>Language d <!--INDEX localization:distrubution issues --> 
<P><LI>Test and submit your work.<P></OL>    <!--INDEX distribution:localization issues --> istribution may
<P>Step 4, the packaging of the new language pack, is discussed next. Mozilla's Cross-Platform Install (XPI) is the ideal candidate for achieving     not be an issue for you. If, for example, your application were
this packaging. This method is discussed extensively in <A HREF="ch06.html#77063">Chapter 6</A>. This distribution method provides great flexibility and has the benefit of being native to Mozilla, thus bypassing the search for external install technologies for your application.    only going to be localized into a finite number of languages,
<H4><A NAME="77064"></A> The anatomy of an install script</H4>    bundling each of them up with the main installer would be most
<P><A HREF="#77024">Example 11-9</A> presents <!--INDEX localization:install scripts -->  <!--INDEX installation:localization and install scripts -->  <!--INDEX scripts:install, localization and -->  a script that is based on the Mozilla process that distributes localized language packs. It presumes that there is a single JAR file for the language that is installed and registered in the Mozilla binary's chrome root.    convenient. If, however, the need for new language versions
<P>The XPI archive consists of the JAR file in a <I>bin/chrome</I> directory and the <I>install.js</I> file, together in a compressed archive with an <I>.xpi</I> extension. Simply clicking on a web page link to this file invokes the Mozilla software installation service and installs your language. For convenience, inline comments in <A HREF="#77024">Example 11-9</A> explain what is happening.    arises at various intervals in the release process, you need to
    find a way to make them available and install them on top of an
<P><I>Example 11-9: <A NAME="77024"></A></I>    existing installation.</p>
<I>The locale XPI install script, install.js</I>    <p>For example, as more people from various locations in the
<PRE> function verifyDiskSpace(dirPath, spaceRequired)    world are becoming aware of the Mozilla project, they want to
     customize it into their own language. Here are the steps that
     you need to take to set up your version.</p>
     <ol>
       <li>Register as a contributor and set up the resources that
       you need, if any (web page, mailing list). This will ensure
       that you are added to the project page on the mozilla.org
       site.</li>
       <li>Get a copy of Mozilla to test either via a binary
       distribution or by downloading and building your own source
       (see <a href="appa.html#90096">Appendix A</a> for more
       information).</li>
       <li>Translate the files.</li>
       <li>Package your new files for distribution.</li>
       <li>Test and submit your work.</li>
     </ol>
     <p>Step 4, the packaging of the new language pack, is discussed
     next. Mozilla's Cross-Platform Install (XPI) is the ideal
     candidate for achieving this packaging. This method is
     discussed extensively in <a href="ch06.html#77063">Chapter
     6</a>. This distribution method provides great flexibility and
     has the benefit of being native to Mozilla, thus bypassing the
     search for external install technologies for your
     application.</p>
     <h4><a name="77064"></a> The anatomy of an install script</h4>
     <p><a href="#77024">Example 11-9</a> presents 
     <!--INDEX localization:install scripts --> 
     <!--INDEX installation:localization and install scripts --> 
     <!--INDEX scripts:install, localization and --> a script that
     is based on the Mozilla process that distributes localized
     language packs. It presumes that there is a single JAR file for
     the language that is installed and registered in the Mozilla
     binary's chrome root.</p>
     <p>The XPI archive consists of the JAR file in a
     <i>bin/chrome</i> directory and the <i>install.js</i> file,
     together in a compressed archive with an <i>.xpi</i> extension.
     Simply clicking on a web page link to this file invokes the
     Mozilla software installation service and installs your
     language. For convenience, inline comments in <a href=
     "#77024">Example 11-9</a> explain what is happening.</p>
     <p><i>Example 11-9: <a name="77024"></a></i> <i>The locale XPI
     install script, install.js</i></p>
 <pre>
  function verifyDiskSpace(dirPath, spaceRequired)
  {   {
    var spaceAvailable;     var spaceAvailable;
    spaceAvailable = fileGetDiskSpaceAvailable(dirPath);     spaceAvailable = fileGetDiskSpaceAvailable(dirPath);
Line 511  this packaging. This method is discussed Line 1274  this packaging. This method is discussed
    fProgram,     fProgram,
    "");     "");
    logComment("addDirectory( ) returned: " + err);     logComment("addDirectory( ) returned: " + err);
   </TD>// register chrome   &lt;/td&gt;// register chrome
    var cf = getFolder(fProgram, "chrome/"+chromeName);     var cf = getFolder(fProgram, "chrome/"+chromeName);
    var pf = getFolder(fProgram, "chrome/"+platformName);     var pf = getFolder(fProgram, "chrome/"+platformName);
    var rf = getFolder(fProgram, "chrome/"+regionFile);     var rf = getFolder(fProgram, "chrome/"+regionFile);
Line 544  this packaging. This method is discussed Line 1307  this packaging. This method is discussed
    registerChrome(chromeType, rf, regionName + "navigator-region/");     registerChrome(chromeType, rf, regionName + "navigator-region/");
    if (err == SUCCESS)     if (err == SUCCESS)
    {     {
     </TD>// complete the installation     &lt;/td&gt;// complete the installation
      err = performInstall( );       err = performInstall( );
      logComment("performInstall( ) returned: " + err);       logComment("performInstall( ) returned: " + err);
    }     }
    else     else
    {     {
     </TD>// cancel the installation     &lt;/td&gt;// cancel the installation
      cancelInstall(err);       cancelInstall(err);
      logComment("cancelInstall due to error: " + err);       logComment("cancelInstall due to error: " + err);
    }     }
  }   }
  else   else
  {   {
   </TD>// if we enter this section,   &lt;/td&gt;// if we enter this section,
    // there is not enough disk space for installation     // there is not enough disk space for installation
    cancelInstall(INSUFFICIENT_DISK_SPACE);     cancelInstall(INSUFFICIENT_DISK_SPACE);
 }</PRE> }
</pre>
<P>By changing some values of the changeable fields, you can tailor this script to handle the install in any directory in the chrome (<I>cf</I>) that you want and register the chrome URL (<I>localeName</I>) for use. The rest is handled by the built-in functionality in XPI provided by such functions as <TT>initInstall</TT> and <TT>performInstall</TT>.    <p>By changing some values of the changeable fields, you can
<H4><A NAME="77065"></A> Switching languages</H4>    tailor this script to handle the install in any directory in
<P>The mechanism  <!--INDEX localization:switching languages --> for switching languages can take many forms. Mozilla switches languages by updating an RDF datasource when a language pack is installed. The UI for switching languages in Mozilla is in the main Preferences (Edit &gt; Preferences). Within the preferences area, the language/content panel (Appearance &gt; Languages/Content) interacts with the chrome registry when loaded, reading in the installed language packs and populating a selectable list with the available language identifier. Selecting one language and restarting Mozilla changes the interface for the user. <A HREF="#77026">Example 11-10</A> is a simple script for switching locales.    the chrome (<i>cf</i>) that you want and register the chrome
    URL (<i>localeName</i>) for use. The rest is handled by the
Example 11-10<A NAME="77026"></A>    built-in functionality in XPI provided by such functions as
<I>Locale-switching script</I>    <tt>initInstall</tt> and <tt>performInstall</tt>.</p>
<PRE> function switchLocale(langcode)    <h4><a name="77065"></a> Switching languages</h4>
     <p>The mechanism <!--INDEX localization:switching languages -->
     for switching languages can take many forms. Mozilla switches
     languages by updating an RDF datasource when a language pack is
     installed. The UI for switching languages in Mozilla is in the
     main Preferences (Edit &gt; Preferences). Within the
     preferences area, the language/content panel (Appearance &gt;
     Languages/Content) interacts with the chrome registry when
     loaded, reading in the installed language packs and populating
     a selectable list with the available language identifier.
     Selecting one language and restarting Mozilla changes the
     interface for the user. <a href="#77026">Example 11-10</a> is a
     simple script for switching locales. Example 11-10<a name=
     "77026"></a> <i>Locale-switching script</i></p>
 <pre>
  function switchLocale(langcode)
  {   {
    try {     try {
     var chromeRegistry = Components.classes</TD>["@mozilla.org/chrome/chrome-registry;1"].getService(Components.interfaces.nsIChromeRegistry);     var chromeRegistry = Components.classes&lt;/td&gt;["@mozilla.org/chrome/chrome-registry;1"].getService(Components.interfaces.nsIChromeRegistry);
      chromeRegistry.selectLocale(langcode, true);       chromeRegistry.selectLocale(langcode, true);
     var observerService = Components.classes</TD>["     var observerService = Components.classes&lt;/td&gt;["
          @mozilla.org/observer-service;1"].           @mozilla.org/observer-service;1"].
          getService(Components.interfaces.nsIObserverService);           getService(Components.interfaces.nsIObserverService);
      observerService.notifyObservers(null, "locale-selected", null);       observerService.notifyObservers(null, "locale-selected", null);
Line 585  Example 11-10<A NAME="77026"></A> Line 1363  Example 11-10<A NAME="77026"></A>
      var titleText = prefUtilBundle.GetStringFromName("languageTitle");       var titleText = prefUtilBundle.GetStringFromName("languageTitle");
      alertText = alertText.replace(/%brand%/g,       alertText = alertText.replace(/%brand%/g,
          brandBundle.GetStringFromName("brandShortName"));           brandBundle.GetStringFromName("brandShortName"));
     var promptService = Components.classes</TD>["     var promptService = Components.classes&lt;/td&gt;["
          @mozilla.org/embedcomp/prompt-service;1"].getService( );           @mozilla.org/embedcomp/prompt-service;1"].getService( );
      promptService = promptService.QueryInterface       promptService = promptService.QueryInterface
          (Components.interfaces.nsIPromptService)           (Components.interfaces.nsIPromptService)
Line 595  Example 11-10<A NAME="77026"></A> Line 1373  Example 11-10<A NAME="77026"></A>
      return false;       return false;
    }     }
    return true;     return true;
 }</PRE> }
</pre>
<P>The language code is passed in as a parameter to the <TT>switchLocale</TT> JavaScript method in <A HREF="#77026">Example 11-10</A>. The locale is set via the <TT>nsIChromeRegistry</TT> component, which uses a method named <TT>selectLocale</TT>. This locale selection is located in the first few lines, and the rest of the code prepares and shows a prompt to the user. This prompt reminds you to restart Mozilla to ensure that the new locale takes effect.    <p>The language code is passed in as a parameter to the
<H2><A NAME="77066"></A> Localization Issues</H2>    <tt>switchLocale</tt> JavaScript method in <a href=
<P>This section aims to dig a little deeper into the issues of UI aesthetics and principles, in order to provide some background into the underlying encoding of documents in the XPFE framework. The main portion is taken up by a discussion of Unicode. There is some background to what Unicode is, how Mozilla uses it, and some practical conversion utilities to ensure that your files are in the correct encoding.    "#77026">Example 11-10</a>. The locale is set via the
<H3><A NAME="77067"></A> XPFE and Unicode</H3>    <tt>nsIChromeRegistry</tt> component, which uses a method named
<P>Unicode is <!--INDEX localization:Unicode -->  <!--INDEX Unicode:overview -->  a broad topic and we cannot hope to give you anywhere near a full understanding of what it is. However, a brief introduction will highlight its importance in the software world and show how it is used as one of the internationalization cornerstones in the Mozilla project.    <tt>selectLocale</tt>. This locale selection is located in the
<BLOCKQUOTE><CENTER><B>NOTE</B></CENTER>    first few lines, and the rest of the code prepares and shows a
<P>For more in-depth information, refer to the book <I>The Unicode Standard, Version 3.0</I> by the Unicode Consortium, published by Addison Wesley Longman. Another useful reference is <I>Unicode: A Primer</I> by Tony Graham, published by M&amp;T Books.<P></BLOCKQUOTE>    prompt to the user. This prompt reminds you to restart Mozilla
<P>Unicode is an encoding system used to represent every character with a unique number. It is a standard that came about when multiple encoding systems were merged. It became clear that keeping separate systems was hindering global communication, and applications were not able to exchange information with one another successfully. Now all major systems and applications are standardizing on Unicode. Most major operating systems, such as Windows, AIX, Solaris, and Mac OS, have already adopted it. The latest browsers, including Mozilla, support it. This quote from the Unicode Consortium (<I><A HREF="http://www.unicode.org/unicode/standard/WhatIsUnicode.html">http://www.unicode.org/unicode/standard/WhatIsUnicode.html</A></I>) sums it up the best:    to ensure that the new locale takes effect.</p>
<BLOCKQUOTE>Unicode enables a single software significant cost savings over the use of legacy character sets. Unicode enables a single software product or a single web site to be targeted across multiple platforms, languages and countries without re-engineering. It allows data to be transported through many different systems without corruption.</BLOCKQUOTE>    <h2><a name="77066"></a> Localization Issues</h2>
<P>There are seven character-encoding schemes in Unicode: UTF-8, UTF-16, UTF-16BE, UTF-16LE, UTF-32, UTF-32BE, and UTF-32LE. UTF is an abbreviation for Unicode Transformation Format. The size of the character's internal representation can range from 8 bits (UTF-8) to 32 bits (UTF-32).    <p>This section aims to dig a little deeper into the issues of
<P>One of Unicode's core principles is that it be able to handle any character set and that clients supporting it provide the tools necessary to convert. This conversation can be from Unicode to native character sets and vice versa. The number of native character sets is extensive and ranges from Central European (ISO-8859-2) to Thai (TIS-620).    UI aesthetics and principles, in order to provide some
<P>The default encoding of XUL, XML, and RDF documents in Mozilla is UTF-8. If no encoding is specified in the text declaration, this is the encoding that is used. In the Mozilla tree, you will usually see no encoding specified in this instance and UTF-8 is the default. To use a different encoding, you need to change the XML text declaration at the top of your file. To change your encoding to Central European, include:    background into the underlying encoding of documents in the
<PRE>&lt;?xml version="1.0" encoding="ISO-8859-2" ?&gt;</PRE>    XPFE framework. The main portion is taken up by a discussion of
<H3><A NAME="77068"></A> Language Quirks</H3>    Unicode. There is some background to what Unicode is, how
<P>The size and  <!--INDEX localization:language display issues --> proportion of your windows can come into play when you know your application will be localized into more than one language. In some languages, it takes more words or characters, hence more physical space, to bring meaning to some text. This is especially the case in widgets that contain more text, such as when you want to provide usage guidelines in a panel.    Mozilla uses it, and some practical conversion utilities to
<P>One solution that Mozilla uses in at least one place is to make the actual size of the window or make the widget into a localizable entity.    ensure that your files are in the correct encoding.</p>
<PRE>&lt;window style="&amp;window.size;" ...&gt;    <h3><a name="77067"></a> XPFE and Unicode</h3>
&lt;!ENTITY  window.size             "width: 40em; height: 40em;"&gt;</PRE>    <p>Unicode is <!--INDEX localization:Unicode --> 
<P>The translator or developer can anticipate the size based on the number of words or preview their changes in the displayed UI. If there is an overflow, they can overflow or do the reverse in the case of empty space.    <!--INDEX Unicode:overview --> a broad topic and we cannot hope
<P>As you begin to localize your application, especially if it is a web-related application, you will encounter words and phrases that have universal meaning and may not require translation. If you translate the whole Mozilla application, for example, you'll find that some words or phrases remain untouched. These items include terms that are used for branding, or universal web browsing terms, such as Bookmarks, Tasks, and Tools. In some instances, the choice to translate some of these terms is purely subjective.    to give you anywhere near a full understanding of what it is.
<HR><BR><BR>    However, a brief introduction will highlight its importance in
File a <a href="http://mozdev.org/bugs/enter_bug.cgi?product=books">Bug</a> for chapter 11.    the software world and show how it is used as one of the
<!-- ?php require(NOTES); ? -->    internationalization cornerstones in the Mozilla project.</p>
<?php $post_to_list=NO; $author='reviewers@mozdev.org'; $target_page='ch11'; require(NOTES); ?>    <blockquote>
</BODY>      <div class="c24">
</HTML>        NOTE
       </div>
       <p>For more in-depth information, refer to the book <i>The
       Unicode Standard, Version 3.0</i> by the Unicode Consortium,
       published by Addison Wesley Longman. Another useful reference
       is <i>Unicode: A Primer</i> by Tony Graham, published by
       M&amp;T Books.</p>
     </blockquote>
     <p>Unicode is an encoding system used to represent every
     character with a unique number. It is a standard that came
     about when multiple encoding systems were merged. It became
     clear that keeping separate systems was hindering global
     communication, and applications were not able to exchange
     information with one another successfully. Now all major
     systems and applications are standardizing on Unicode. Most
     major operating systems, such as Windows, AIX, Solaris, and Mac
     OS, have already adopted it. The latest browsers, including
     Mozilla, support it. This quote from the Unicode Consortium
     (<i><a href=
     "http://www.unicode.org/unicode/standard/WhatIsUnicode.html">http://www.unicode.org/unicode/standard/WhatIsUnicode.html</a></i>)
     sums it up the best:</p>
     <blockquote>
       Unicode enables a single software significant cost savings
       over the use of legacy character sets. Unicode enables a
       single software product or a single web site to be targeted
       across multiple platforms, languages and countries without
       re-engineering. It allows data to be transported through many
       different systems without corruption.
     </blockquote>
     <p>There are seven character-encoding schemes in Unicode:
     UTF-8, UTF-16, UTF-16BE, UTF-16LE, UTF-32, UTF-32BE, and
     UTF-32LE. UTF is an abbreviation for Unicode Transformation
     Format. The size of the character's internal representation can
     range from 8 bits (UTF-8) to 32 bits (UTF-32).</p>
     <p>One of Unicode's core principles is that it be able to
     handle any character set and that clients supporting it provide
     the tools necessary to convert. This conversation can be from
     Unicode to native character sets and vice versa. The number of
     native character sets is extensive and ranges from Central
     European (ISO-8859-2) to Thai (TIS-620).</p>
     <p>The default encoding of XUL, XML, and RDF documents in
     Mozilla is UTF-8. If no encoding is specified in the text
     declaration, this is the encoding that is used. In the Mozilla
     tree, you will usually see no encoding specified in this
     instance and UTF-8 is the default. To use a different encoding,
     you need to change the XML text declaration at the top of your
     file. To change your encoding to Central European, include:</p>
 <pre>
 &lt;?xml version="1.0" encoding="ISO-8859-2" ?&gt;
 </pre>
     <h3><a name="77068"></a> Language Quirks</h3>
     <p>The size and 
     <!--INDEX localization:language display issues --> proportion
     of your windows can come into play when you know your
     application will be localized into more than one language. In
     some languages, it takes more words or characters, hence more
     physical space, to bring meaning to some text. This is
     especially the case in widgets that contain more text, such as
     when you want to provide usage guidelines in a panel.</p>
     <p>One solution that Mozilla uses in at least one place is to
     make the actual size of the window or make the widget into a
     localizable entity.</p>
 <pre>
 &lt;window style="&amp;window.size;" ...&gt;
 &lt;!ENTITY  window.size             "width: 40em; height: 40em;"&gt;
 </pre>
     <p>The translator or developer can anticipate the size based on
     the number of words or preview their changes in the displayed
     UI. If there is an overflow, they can overflow or do the
     reverse in the case of empty space.</p>
     <p>As you begin to localize your application, especially if it
     is a web-related application, you will encounter words and
     phrases that have universal meaning and may not require
     translation. If you translate the whole Mozilla application,
     for example, you'll find that some words or phrases remain
     untouched. These items include terms that are used for
     branding, or universal web browsing terms, such as Bookmarks,
     Tasks, and Tools. In some instances, the choice to translate
     some of these terms is purely subjective.</p>
     <hr>
     <br>
     <br>
     File a <a href=
     "http://mozdev.org/bugs/enter_bug.cgi?product=books">Bug</a>
     for chapter 11. <!-- ?php require(NOTES); ? -->
     <?php $post_to_list=NO; $author='reviewers@mozdev.org'; $target_page='ch11'; require(NOTES); ?>

Removed from v.1.7  
changed lines
  Added in v.1.8


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>