![]() UJML Language Reference |
UJML includes features that allow programs to adapt at run time to different locales.
UJML allows you to write programs that work in much the same way in many different languages. This is because UJML provides functions and entity argument values to determine the current locale of the device at run time. The Visual Elements sample is a good example of supporting run time localization. See Visual Elements Sample.
The first step in adapting your program to a locale is to determine the device locale. This is done by calling the _getStringProperty() function with the &_PROPERTY_STRING_LOCALE; device information entity. See _getStringProperty() function, String Device Information Entities. This returns a 'locale' string consistent with RFC1766.
Note: A language tag is always returned. The country tag (or any other subtag) is device-dependent.
You will need to localize anything in your application that is different from one language/locale to another. At a minimum this includes:
The next step to device independence involves your application design: make certain all of the text values and other locale-dependent aspects of your application are cached in variables. See Variables. If your application uses images or audio files that are locale dependent, you need to have variables for each of the media URLs as well. See Media Files. This way, you can set the values of these variables appropriately to the locale when the application starts.
UJML code that formats data for display should be locale aware. If possible, you should format the data once and cache it in a variable. If not, you should create a locale-aware function and call it as needed. See User Defined Functions. The datetime.ujml sample contains some simple locale-aware formatting functions.
An equally important consideration is the modularity of your application. A highly modular application, with its functionality in different files which are created, linked, or included will have multiple values which require localization. See Anatomy of a UJML Application, Types of UJML Files. In the case of UJML components and linked UJML modules, an application may even provide several different linkable subprograms coded with different locales.
Note: Each partition or component instance increases the memory usage of a UJML application. For this reason, you must balance modularity against memory requirements and available memory on the device. Included files also add to memory requirements, although not as much.
One of the best ways to do localization is to create components which provide localized values and perform other actions based on the locale. See Components. These locale components are loaded at run time, with the specific locale component being loaded based on the current locale string. See Resources. The easiest way to do this is to put the component files for each locale into a subdirectory named for the locale and then use the locale name at run time to build the URL used for linking the partition.
The locale components would implement standard interfaces designed to provide localization functionality and your code would create an instance of the appropriate component and assign it to an appropriate instance type variable at runtime. See Interfaces, Interface Types. Your code when then access the appropriate component method whenever it required a localized value or needed to perform a function in a localized way.
Using a linked partition to set your localized variables
Another way to do localization is to create linkable partitions which sets your localized variables and performs other actions based on the locale. The locale partitions are linked to at run time with the specific locale partition being linked based on the current locale string. See Linking Files. The easiest way to do this is to put the partition files for each locale into a subdirectory named for the locale and then use the locale name at run time to build the URL used for linking the partition.
Once loaded, a locale partition file sets the values of shared variables as needed for the locale. See Data Scoping and Sharing. A locale partition may also call back to shared functions in the parent file in order to set up menu items and the like. See Function Scoping and Sharing. Once this is complete, a shared state variable is set to true to indicate that the locale has been loaded and the parent file may continue processing. See State Transitions.
Sometimes a device will be running a locale which your application does not support. One way to handle this is to select a 'default' locale to use as a fall-back. Which locale is best to use as a fall-back to will vary from application to application.
Another way to handle locale failure is to display an appropriate error message in a default language during startup and then stop the program from continuing. This error message should include contact information and other pertinent data needed to help isolate the problem (for example, the current locale, your program version, and a description of problem encountered). Try to make certain even software failure is a good experience for the customer.
Sometimes a locale partition file may fail to load. At a minimum, you should provide a standard way to exit the program, which you then hide or supersede when the locale has loaded correctly.
Even if your UJML application is only going to run in one locale you should consider locale independence during the design process. Doing this protects your investment by:
In most cases, you will not have the luxury of designing for one language and locale, but rather will be targeting several different locales. So why not make your application as locale-independent as possible?
The following example shows how to format a date based on a locale value, with formats provided for Japanese, US English, and a default fall-back. It is part of the datetime.ujml sample.
// Format date based on the locale
if (_streq(mLocale, "ja-JP")) // yyyy/mm/dd
{
formattedDateTime = _strcat(Date.getYear(),
"/", Date.getMonth(), "/", Date.getDay(), " ",
Time.getHour24(), ":", Time.getMinute(), ":",
Time.getSecond());
}
else if (_streq(mLocale, "en-US")) // mm/dd/yyyy
{
if (Time.isAM())
{
formattedDateTime = "AM";
}
else
{
formattedDateTime = "PM";
}
formattedDateTime = _strcat(Date.getMonth(),
"/", Date.getDay(), "/", Date.getYear(), " ",
Time.getHour12(), ":", Time.getMinute(), ":",
Time.getSecond(), " ", formattedDateTime);
}
else // dd/mm/yyyy
{
formattedDateTime = _strcat(Date.getDay(),
"/", Date.getMonth(), "/", Date.getYear(), " ",
Time.getHour24(), ":", Time.getMinute(), ":",
Time.getSecond());
}
The following example shows how to get the device locale, extracts the language string from it, and links to a locale partition based on the language string. It is part of the visualelements.ujml sample.
// Get the locale and language
mLocale = _getStringProperty(&_PROPERTY_STRING_LOCALE;);
mLanguage = _substring(mLocale , 0, 2);
// Load the locale-setting partition
_link("Locale", _strcat(mLanguage, "/velocale.ujbc"));
The following example shows how to set shared variables and calls a shared function in the parent application to set the locale specific values. It then sets a shared state variable to indicate that localization is complete. It is part of the velocale.ujml sample.
// Load default text.
mDefaultLabelText = "Hello World!";
mDefaultMultiLabelText =
"We hold these truths to be self-evident, that all men are created equal, that they are endowed by their Creator with certain unalienable Rights, that among these are Life, Liberty, and the pursuit of Happiness.";
// Load UI labels.
mBackLabel = "Back";
mSettingsLabel = "Settings";
// Load menu items.
addMenuItem("Device");
addMenuItem("Label");
addMenuItem("Multi-Label");
addMenuItem("Box");
addMenuItem("Round-Box");
addMenuItem("X-Oval");
addMenuItem("Line");
addMenuItem("Polyline");
addMenuItem("Polygon 1");
addMenuItem("Polygon 2");
addMenuItem("Image");
addMenuItem("Combined");
// Done.
sLocaleLoaded = true;Anatomy of a UJML Application, Types of UJML Files, Media Files, Linking Files, Resources, Variables, Data Scoping and Sharing, Components, Interfaces, Interface Types, State Transitions, User Defined Functions, Function Scoping and Sharing, _getStringProperty(), String Device Information Entities, Visual Elements Sample, visualelements.ujml, velocale.ujml, datetime.ujml
|
Copyright (c) 2000-2007 UIEvolution, Inc. All rights reserved.
|
|
What do you think about this topic? Send feedback!
|