Tải bản đầy đủ (.pdf) (19 trang)

Tài liệu Creating Applications with Mozilla-Chapter 11. Localization-P3 pdf

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (38.99 KB, 19 trang )


Chapter 11. Localization-P3

11.4.4. Localizable Resources in HTML
As a web 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 <iframe> and <browser>, you have
ready-made frames to slot your content into:
<iframe src="xFly.html" flex="1"/>
Therefore, a simple modification of xFly.html 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.
11.4.5. Localizable Resources in RDF
Strings to be 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.
As an XML markup, RDF can handle inline entity definitions. These entity
definitions have been covered thoroughly in the chapter so far. Example 11-
8 looks at localizable strings contained directly in RDF node descriptions.
This example is taken from the Help table of contents in the Mozilla tree.
Example 11-8. RDF Description node with localizable text
<rdf:Description about="#nav-doc">
<nc:subheadings>
<rdf:Seq>
<rdf:li>
<rdf:Description ID="nav-doc-language"


nc:name="Language and Translation
Services"

nc:link="chrome://help/locale/nav_help.html#nav_lan
guage"/>
</rdf:li>
</rdf:Seq>
</nc:subheadings>
</rdf:Description>
The text in the nc:name 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.
11.5. The Chrome Registry and Locale
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.
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.
11.5.1. The Directory Structure
A typical application chrome structure looks like the directory structure in
Figure 11-2
. A folder for each language is under the locale 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.

The W3C site has good resources that provide information about the
ISO-639 and ISO-3166 standards at />HTML-tags.html.
For example, the unique identifier for Scots, Great Britain, is Sc-GB. The
first code, Sc, is for the Scots (Scottish) dialect, and the second code, GB, is
for the country code for Great Britain. This is the standard that Mozilla
follows.
Figure 11-2. Locale's placement in typical chrome layout

The folder that is registered is the language folder, which is what has to be
changed on an install. Thus, the URL chrome://package/locale actually
points to package/locale/en-US or whichever language is turned on at the
time. The language folder may in turn include subfolders that contain logical
units for your application.
11.5.2. Interaction with the Chrome Registry
As pointed out in Chapter 6
, 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 chrome.rdf in the root chrome
directory.
A resource:/ URL points to the folder for your files to be picked up and
recognized by the chrome mechanism and accessed via chrome:// URLs
in your application code. The locale is no exception.
<RDF:Description about="urn:mozilla:locale:en-
US:xfly"
c:baseURL="resource:/chrome/xfly/locale/en-
US/">
c:localeVersion="0.1.0.0"
<c:package resource="urn:mozilla:package:xfly"/>

</RDF:Description>
A built-in versioning system in the chrome registry uses
c:localeVersion descriptor, if you plan on distributing multiple
language packs for your application. Other descriptors are available if you
choose to use them: display name (c:displayName), internal name
(c:name), location type (c:locType), and author (c:author).
11.5.3. Distribution
Language distribution 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.
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.
1. 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.
2. Get a copy of Mozilla to test either via a binary distribution or by
downloading and building your own source (see Appendix A
for more
information).
3. Translate the files.
4. Package your new files for distribution.
5. Test and submit your work.
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 Chapter 6

. 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.
11.5.3.1. The anatomy of an install script
Example 11-9
presents 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.
The XPI archive consists of the JAR file in a bin/chrome directory and
the install.js file, together in a compressed archive with an .xpi
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 Example 11-9
explain what is happening.
Example 11-9. The locale XPI install script, install.js
function verifyDiskSpace(dirPath, spaceRequired)
{
var spaceAvailable;
spaceAvailable =
fileGetDiskSpaceAvailable(dirPath);
spaceAvailable = parseInt(spaceAvailable / 1024);
if(spaceAvailable < spaceRequired)
{
logComment("Insufficient disk space: " +
dirPath);
logComment(" required : " + spaceRequired + "
K");
logComment(" available: " + spaceAvailable + "

K");
return(false);
}
return(true);
}
// platform detection
function getPlatform( ) {
var platformStr;
var platformNode;
if('platform' in Install) {
platformStr = new String(Install.platform);
if (!platformStr.search(/^Macintosh/))
platformNode = 'mac';
else if (!platformStr.search(/^Win/))
platformNode = 'win';
else
platformNode = 'unix';
}
else {
var fOSMac = getFolder("Mac System");
var fOSWin = getFolder("Win System");
logComment("fOSMac: " + fOSMac);
logComment("fOSWin: " + fOSWin);
if(fOSMac != null)
platformNode = 'mac';
else if(fOSWin != null)
platformNode = 'win';
else
platformNode = 'unix';
}

return platformNode;
}
// Size in KB of JAR file
var srDest = 500;
var err;
var fProgram;
var platformNode;
platformNode = getPlatform( );
// - LOCALIZATION NOTE: translate only these -
- -
// These fields are changeable in this generic
script
var prettyName = "Irish";
var langcode = "ie";
var regioncode = "GA";
var chromeNode = langcode + "-" + regioncode;
// - END LOCALIZABLE RESOURCES -
// build the paths and file names for registry and
chrome:// url access
var regName = "locales/mozilla/" + chromeNode;
var chromeName = chromeNode + ".jar";
var regionFile = regioncode + ".jar";
var platformName = langcode + "-" + platformNode +
".jar";
var localeName = "locale/" + chromeNode + "/";
// Start the installation
err = initInstall(prettyName, regName, "0.1.0.0");
logComment("initInstall: " + err);
fProgram = getFolder("Program");
logComment("fProgram: " + fProgram);

// Check disk space using utility function at the
start of the script
if (verifyDiskSpace(fProgram, srDest))
{
err = addDirectory("",
"bin",
fProgram,
"");
logComment("addDirectory( ) returned: " + err);
// register chrome
var cf = getFolder(fProgram,
"chrome/"+chromeName);
var pf = getFolder(fProgram,
"chrome/"+platformName);
var rf = getFolder(fProgram,
"chrome/"+regionFile);
var chromeType = LOCALE | DELAYED_CHROME;
registerChrome(chromeType, cf, localeName +
"global/");
registerChrome(chromeType, cf, localeName +
"communicator/");
registerChrome(chromeType, cf, localeName +
"content-packs/");
registerChrome(chromeType, cf, localeName +
"cookie/");
registerChrome(chromeType, cf, localeName +
"editor/");
registerChrome(chromeType, cf, localeName +
"forms/");
registerChrome(chromeType, cf, localeName +

"help/");
registerChrome(chromeType, cf, localeName +
"messenger/");
registerChrome(chromeType, cf, localeName +
"messenger-smime/");
registerChrome(chromeType, cf, localeName +
"mozldap/");
registerChrome(chromeType, cf, localeName +
"navigator/");
registerChrome(chromeType, cf, localeName +
"necko/");
registerChrome(chromeType, cf, localeName +
"pipnss/");
registerChrome(chromeType, cf, localeName +
"pippki/");
registerChrome(chromeType, cf, localeName +
"wallet/");
registerChrome(chromeType, pf, localeName +
"global-platform/");
registerChrome(chromeType, pf, localeName +
"communicator-platform/");
registerChrome(chromeType, pf, localeName +
"navigator-platform/");
if (platformNode == "win") {
registerChrome(chromeType, pf, localeName +
"messenger-mapi/");
}
registerChrome(chromeType, rf, regionName +
"global-region/");
registerChrome(chromeType, rf, regionName +

"communicator-region/");
registerChrome(chromeType, rf, regionName +
"editor-region/");
registerChrome(chromeType, rf, regionName +
"messenger-region/");
registerChrome(chromeType, rf, regionName +
"navigator-region/");
if (err == SUCCESS)
{
// complete the installation
err = performInstall( );
logComment("performInstall( ) returned: " +
err);
}
else
{
// cancel the installation
cancelInstall(err);
logComment("cancelInstall due to error: " +
err);
}
}
else
{
// if we enter this section,
// there is not enough disk space for
installation
cancelInstall(INSUFFICIENT_DISK_SPACE);
}
By changing some values of the changeable fields, you can tailor this script

to handle the install in any directory in the chrome (cf) that you want and
register the chrome URL (localeName) for use. The rest is handled by the
built-in functionality in XPI provided by such functions as initInstall
and performInstall.
11.5.3.2. Switching languages
The mechanism 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 > Preferences). Within the preferences area, the
language/content panel (Appearance > 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.
Example 11-10
is a simple script for switching locales.
Example 11-10. Locale-switching script
function switchLocale(langcode)
{
try {
var chromeRegistry =
Components.classes["@mozilla.org/chrome/chrome-
registry;1"].getService(Components.interfaces.nsICh
romeRegistry);
chromeRegistry.selectLocale(langcode, true);
var observerService = Components.classes["
@mozilla.org/observer-service;1"].

getService(Components.interfaces.nsIObserverService
);
observerService.notifyObservers(null, "locale-

selected", null);
var prefUtilBundle = srGetStrBundle

("chrome://communicator/locale/pref/prefutilities.p
roperties");
var brandBundle = srGetStrBundle

("chrome://global/locale/brand.properties");
var alertText =
prefUtilBundle.GetStringFromName("languageAlert");
var titleText =
prefUtilBundle.GetStringFromName("languageTitle");
alertText = alertText.replace(/%brand%/g,

brandBundle.GetStringFromName("brandShortName"));
var promptService = Components.classes["
@mozilla.org/embedcomp/prompt-
service;1"].getService( );
promptService = promptService.QueryInterface
(Components.interfaces.nsIPromptService)
promptService.alert(window, titleText,
alertText);
}
catch(e) {
return false;
}
return true;
}
The language code is passed in as a parameter to the switchLocale
JavaScript method in Example 11-10

. The locale is set via the
nsIChromeRegistry component, which uses a method named
selectLocale. 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.
11.6. Localization Issues
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.
11.6.1. XPFE and Unicode
Unicode is 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.

For more in-depth information, refer to the book The Unicode
Standard, Version 3.0 by the Unicode Consortium, published by
Addison Wesley Longman. Another useful reference is Unicode: A
Primer by Tony Graham, published by M&T Books.
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
( sums it up
the best:
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.
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).
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).
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:
<?xml version="1.0" encoding="ISO-8859-2" ?>
11.6.2. Language Quirks
The size and 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.
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.
<window style="&window.size;" >
<!ENTITY window.size "width: 40em;
height: 40em;">
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.
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.


×