Using localized text from JavaScript and computed values
This details how to manually localize XPages text that is not automatically processed, such as text in JavaScript and computed values.
The document "
XPages: How to use the localization options" describes enabling an Application for translation, which automatically extracts most of the localizable strings into .properties files. Follow those steps first, and if there is remaining unlocalized text, consult this document. This explains how to use localized strings from JavaScript, computed values and from the other XPage-related design elements.
To use the bundle resource
There are no tools to automatically extract .properties files from in-line scripts. Instead, you can manually extract each string to a .properties file, load the .properties file in your XPage and reference the value from the .properties file. When translated copies of the .properties files are added to the Application, the correct .properties file will be loaded, based on the user's locale. A collection of translated .properties files is known as a bundle, so they are accessed using the bundle resource.
The bundle resource publishes a variable containing localized strings from .properties files. To configure a simple bundle:
1. First set up a sample to localize.
Drag a Computed Field control onto an XPage. In the Value tab, choose the JavaScript radio, click the Open Script Dialog button, and paste in the value:
'Welcome.'
2. Create a .properties file containing the localized strings.
3. Add a bundle resource to the root of the page, to publish the .properties file contents to a given variable name:
- In the XPage, Properties view, All Properties tab, click the property "resources".
- An add button appears, click and choose "xp:bundle" from the menu.
- In the "var" property, enter the variable name used to refer to the .properties file in JavaScript, e.g. strings.
- In the "src" property (expand bundle, basics), enter the file name like so: /strings.properties

4. Use the bundle variable to access the strings from the .properties file
- In the Computed Field control, edit the value, changing it to use the string from the bundle.
In 8.5.1 and later, the array syntax works:
// 'Welcome.'
return strings['greeting'];
but in the 8.5 release, you should use getString:
// 'Welcome.'
return strings.getString('greeting');
5. Create language copies of the strings.properties file. For example, for French, which has the language code "fr".
- Copy the file strings.properties to strings_fr.properties.
- To allow testing before the files are sent to the translators, put in some fake translations.
- Open strings_fr.properties. Open the Find/Replace dialog, available in the Edit menu.
- Check the check box "Regular expressions"
- In the Find box paste in: (.+=)([^\[].+)
- In the Replace box paste in the following, where fr corresponds to French: \\1[fr| \\2 ]
- Click Replace All.
- One translated file may be enough for initial testing, but eventually you will need a copy for every supported locale listed in the Application Properties, XPages tab.
(The supported locales were configured in Section 1 of XPages: How to use the localization options.)
Note on the syntax
In 8.5.1 and later, the array syntax can be used to reference bundle values:
strings['greeting']
but in the 8.5 release, you should use getString:
strings.getString('greeting')
Attempting to use the array syntax in 8.5 will give an error:
Unknown member 'greeting' in Java class 'java.util.PropertyResourceBundle'
In 8.5.1 you will only get that error when the key does not exist in the bundle.
The rest of the examples will use the 8.5.1 array syntax.
To use the I18n library
The I18n server script library has methods to format messages for localization, display dates in a locale-specific manner and miscellaneous Internationalization utilities. I18n means Internationalization, see the Glossary below. This example shows how use the I18n library to ensure that an entire phrase is localized in a single string, so that translators can change the word ordering as they like.
1. For this example string, you would need to extract the @UserName into a placeholder, so that the phrase can be localized in one string:
'Hello '+@UserName()+ ', Welcome.'
2. In the Reference tab on the right of the Script Dialog, in the Libraries dropdown, select "Runtime". If you toggle open the I18n library, you'll see the format method.
3. The first parameter to the method is the localizable string. Subsequent parameters are objects to be inserted at the placeholders {0}, {1} etc. Only a limited number of parameters are allowed, {0} to {4}, for more than that you should split the text into multiple strings.
Use the placeholders with the format method like so:
var message = 'Hello {0}, Welcome.';
message = I18n.format(message, @UserName());
return message;
4. Localizing the string as above gives this value in the computed field :
// 'Hello {0}, Welcome.'
var message = strings['greeting'];
message = I18n.format(message, @UserName());
return message;
5. The .properties file would contain contents like so:
##G11N This file contains translated messages
# {0} is the UserName
greeting=Hello {0}, Welcome.
Localizing Other New Design Elements
The instructions for localizing the following design elements generally depend on the instructions for localizing in-line scripts:
- Server JavaScript Libraries
To access localizable strings from a Server JavaScript library, create your .properties file and extract the strings as with in-line JavaScript, but instead of adding a Bundle Resource to every XPage using the library, you can programmatically create a BundleResource to load its contents.
The example below creates the BundleResource programmatically. You must set the "src" and "component" properties, where the "component" should be the root of the server-side control tree. The java.util.ResourceBundle contents is saved in the applicationScope, in a lookup depending on the locale of the current page. Here a Computed Field with JavaScript value libraryMessage() would read the 'libraryMessage' value from the strings bundle.
function libraryMessage(){
// 'Library message'
return getStrings()['libraryMessage'];
}
function getStrings(){
// see http://www-10.lotus.com/ldd/ddwiki.nsf/dx/JavaScriptInternationalization.htm
var locale = view.getLocale();
if( applicationScope.stringsPerLocale ){
var existingStrings = applicationScope.stringsPerLocale[locale];
if( existingStrings ){
return existingStrings;
}
}
var resource = new com.ibm.xsp.resource.BundleResource();
resource.src = "/strings.properties";
resource.component = view;
var strings = resource.contents;
synchronized(applicationScope){
if( ! applicationScope.stringsPerLocale ) {
applicationScope.stringsPerLocale = new java.util.HashMap();
}
applicationScope.stringsPerLocale[locale] = strings;
}
return strings;
}
- Client JavaScript Libraries.
There is no explicit plan for localization of Client JavaScript Libraries as yet. If you are using Dojo widgets then the Dojo mechanisms should work as the locale is written to the djConfig attribute. Otherwise you can usually pass localized strings from the server as arguments to the client script methods. For example:
<xp:button value="Click me" id="button2">
<xp:eventHandler event="onclick" submit="false">
<xp:this.handlers>
<xp:handler type="text/javascript">
<xp:this.script><![CDATA[
alert("#{javascript: strings['alertMessage'] }");
]]></xp:this.script>
</xp:handler>
</xp:this.handlers>
</xp:eventHandler>
</xp:button>
- Themes
You should try not to define localized strings in themes. The mechanism was mostly invented for styling purposes. If it is necessary you can use a computed value referencing an XPage bundle resource. Set the theme property to a computed value like the Server JavaScript Libraries example above. For example:
<control>
<name>mySubmitButton</name>
<property>
<name>value</name>
<value>${javascript:
function getThemeStrings(){
// see http://www-10.lotus.com/ldd/ddwiki.nsf/dx/JavaScriptInternationalization.htm
var locale = view.getLocale();
if( applicationScope.stringsPerLocale ){
var existingStrings = applicationScope.stringsPerLocale[locale];
if( existingStrings ){
return existingStrings;
}
}
var resource = new com.ibm.xsp.resource.BundleResource();
resource.src = "/strings.properties";
resource.component = view;
var strings = resource.contents;
synchronized(applicationScope){
if( ! applicationScope.stringsPerLocale ) {
applicationScope.stringsPerLocale = new java.util.HashMap();
}
applicationScope.stringsPerLocale[locale] = strings;
}
return strings;
}
return getThemeStrings()['submitButtonLabel'];
}</value>
</property>
</control>
- Style Sheets
There is no mechanism for defining or accessing localized strings in Style Sheets files. It shouldn't generally be necessary. If you do decide to put localizable text in a Style Sheet file you would have to create one copy of the file per locale and selectively output only the file for the current locale. That is similar to how you selectively output different css files when Supporting Bidi in XPages.
A more complicated localization mechanism
Another option is localize strings as normal, and then use scripts to manipulate that text. For example, you could have 2 different labels with different text to be shown, and compute which label is shown at the present time. That mechanism isn't encouraged, as there is a processing overhead for every control or text value in the page, which the use of bundles avoids. The bundle method is preferred as it is usually more readable.
An example of this is provided here. The label value is changed in the afterPageLoad script, from the initial value containing {0} placeholders, to an updated value with numbers inserted at the {0} and {1} locations.
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:this.afterPageLoad><![CDATA[#{javascript:
var created = java.lang.Integer.valueOf(2007);
var lastModified = java.lang.Integer.valueOf(@Year(@Today()));
// Copyright Example.com {0}, {1}
var copyright = getComponent('copyright');
copyright.value = I18n.format(copyright.value, created, lastModified );
}]]></xp:this.afterPageLoad>
The main contents of the page<xp:br></xp:br>
<xp:br></xp:br>
<xp:label id="copyright" value="Copyright Example.com {0}, {1}"/>
</xp:view>
Glossary
I18n Internationalization.
The combined processes of globalization and localization.
G11n Globalization.
The steps required to prepare your Application for use in different locales and for translation into multiple languages.
Examples include
1. Ensure all dates, numbers and currencies are displayed using the locale-specific formats, for the locale of the Application's user. For example, the locale "en_US" will format a short date like "12/31/2000" but the locale "en_UK" will format a short date like "31/12/2000"
2. Configure your style sheets and layout to handle bidi; bi-directional configurations. For example, Arabic text should be displayed from right to left instead of left to right. Search for information on the HTML "dir" attribute for more details.
3. Extracting all localizable strings into .properties files, and using those strings through a bundle, so that when translated versions of the .properties files are available, the bundle will choose which file to load based on the locale.
4. Ensuring that images do not contain text that would need to be translated, or if necessary, building mechanisms to load different images based on the current locale.
l10n Localization
Adding translated versions of existing resources to your Applications.
Examples include
1. Adding translated versions of the .properties files containing localized strings
2. Adding translated versions of any images that contain text.