From IBM Connect 2014, Making Localization of XPages as easy as 1-2-3. We show what comes "out of the box" and also how to localize what isn't "out of the box".
2. ¿quiénes somos (Who are we?)
▪ Brad Balassaitis
– PSC Group, LLC
– Blogger, Author, Wordfeud Addict
– IBM Champion for IBM Collaboration Solutions
– @Balassaitis
– xcellerant.net
!
▪ Kathy Brown
– PSC Group, LLC
– Blogger, Author, Runner, Geek, and Loud Laugher
– IBM Champion for IBM Collaboration Solutions
– @RunningKathy
– runningnotes.net
2
3. Perché Questa Sessione (Why This Session)
▪ The enterprise is global
▪ We will demonstrate:
– what is built-in
– what is NOT built-in
▪ How to do both
▪ Special considerations, tips, and gotchas
3
4. As Easy As 1-2-3
▪ 1. Enabling Localization
▪ 2. Using Built-In Localization
▪ 3. Improving Localization
4
6. Enabling Localization
▪ Enable Localization Support
▪ Generate Localized Resource Bundles
▪ Verify Localization Support
6
7. I. Enable Localization Support
▪ Application Properties > XPages > Localization Options
▪ Select Enable Localization
▪ Add languages (including native language)
▪ Set Source language (development)
▪ Set Default language (display)
7
20. Using Built-In Localization
▪ Built-In Features
▪ Resource Bundles
▪ Translating
– Export Resource Bundles
– Send Resource Bundles for Translation
– Import Translations
– Test Supported Languages
▪ Specifying the Browser Language
14
21. I. Built-In Features
▪ Sets up many properties for translation
– Static Text
• Field Labels, View Column Titles, Hard-Coded String Properties (Default Values)
– Hard-coded keyword lists
• Comboboxes, Listboxes, Radio Buttons, Checkboxes
– Hard-coded Text on Page
• Caveat: No component ID
• Properties file key is based on position and can change
– Hard-coded Validation Messages
▪ Automatically loads locale-specific resource bundles
Tip! Make IDs descriptive so translators know what they are translating
15
23. I. Built-In Features
▪ Some localization is performed even without enabling localization application-wide
– Date and Number formats
– Currency symbols
– Standard component label strings
• File Download control headers, default error messages
– Dojo translations
17
24. I. Built-In Features
▪ Locale class
– getCountry()
– getDecimalSeparator()
– getDefault()
– getDisplayCountry()
– getDisplayLanguage()
▪ TimeZone class
– getDefault()
– getDisplayName()
– inDaylightTime()
▪ Create new Locale or TimeZone object from XSP context
– context.getLocale().getDecimalSeparator()
– context.getTimeZone().getDisplayName()
18
25. I. Built-In Features
▪ Programmatically Change Session Locale
– This overrides browser language setting for the current session
!
– context.setLocaleString(‘de’)
– context.reloadPage()
19
26. I. Built-In Features
▪ Property: Merge source file changes into property files
– Automatically updates properties files with additions, changes, or removals to XPage/CC
– Add: will be added to all resource bundles and will get the default translation (with the
language prefix)
– Remove: will remove it from the properties files
– Modify: get a default translation for it and the original translation will move to the top of the
file and be commented out
• If the default translation was still in place, it would be updated
22
27. I. Built-In Features
▪ In Notes9, you can specify the Character set for the properties file
– In 8.x you were limited to ASCII and Unicode escape sequences
23
28. II. Resource Bundles
▪ Plain text file with a .properties extension
▪ Filename format: filename_locale.properties
– Ex: MyProperties_fr.properties
▪ When localization is enabled, locale-specific copies of properties files are created for each
created for each XPage and custom control
20
29. II. Resource Bundles
▪ Consist of key-value pairs and comments
– key=value
• formRow1/@label=[de| Name ]
• label3/@value=[de| Status: ]
– Comment lines start with #
– Blank lines are ignored
21
30. III. Translation
▪ Translate files in DDE or export to send to translators
▪ Sending files for translation
– Export resource bundles
– Send for translation
– Import resource bundles
– Test
24
31. 1. Export Resource Bundles
▪ Right-click on DB in Package Explorer and select Export
▪ General > File System
25
32. 1. Export Resource Bundles
▪ Select Create directory structure for files
▪ Click Filter Types… and select *.properties
26
33. 1. Export Resource Bundles
▪ Deselect Unnecessary Files
– Mastering XPages suggests deselecting the following files, since they don’t need to be
translated:
• <root>build.properties
• AppPropertiesdatabase.properties
• AppPropertiesxspdesign.properties
• WebContentWEB-INFxsp.properties
▪ Click Finish
27
34. 1. Export Resource Bundles
▪ Check exported files
– Look for properties files for old/unused design elements
28
35. 2. Send Resource Bundles for Translation
▪ Send files for each language to each translator
29
36. 3. Import Translations
▪ Ensure that files are in same directory structure as exported
▪ Right click on application in Package Explorer and select Import
▪ Select General > File System
▪ Select directory with the app name
– Ex: Do not select C:My Translations
– Ex: Select C:My TranslationsLocalization_OneUI_Connect2014.nsf
▪ Click Select All button
▪ Click Finish
▪ Click Yes to All when prompted to overwrite existing files
30
37. 4. Test Supported Languages
▪ Change browser language to test each supported language
31
38. IV. Specifying the Browser Language
▪ *Application display language is determined based on browser settings
– Setting the XSP locale directly will override the browser language setting
!
▪ Rules
– If the application supports the first browser language, then that’s what will display
– If not, then it checks the next browser language and so on until there’s a match
– If the application does not support any browser languages, it displays in the default
– If there is not a match for a specific regional setting, it will roll up to the local
• Ex: en_US and en_GB would both roll up to en if that’s what the language supports
32
39. IV. Specifying the Browser Language
▪ IE Language Settings
– Internet Options > General tab > Languages
33
40. IV. Specifying the Browser Language
▪ Firefox Language Settings
– Options > Content tab
– Languages section > “Choose…” button
34
41. IV. Specifying the Browser Language
▪ Chrome Language Settings
– Settings > Show advanced settings
– Languages > Language and Input Settings…
– Page display language can be different from browser configuration language!
35
42. IV. Specifying the Notes Browser Language
▪ File > Preferences > Regional Settings
– Select the language from Regional Profile
– Click OK
– A prompt will inform you to restart the program
35
45. I. What XPages Localization Does Not Translate
▪ Computed values
– Labels, link/button titles, menu options, application layout tabs/module title
▪ Programmatic messages
– Form-level messages
– Popup help text
– E-mail text
– Field validation messages raised by code
▪ List Fields with computed values
– Comboboxes, Listboxes, Radio Buttons, Checkboxes
38
46. I. What XPages Localization Does Not Translate
▪ Demo!
39
48. II. Approach
▪ Create another Resource Bundle (properties file) with all additional translations
▪ Manually create a copy of the Resource Bundle with each supported locale code suffix
▪ Create a script library with functions to use the Resource Bundle
1. Retrieve/cache the custom resource bundle
2. Retrieve a translated string value
3. Retrieve a translated keyword list (edit mode)
4. Retrieve a translated keyword value (read mode)
41
49. III. Retrieving a Custom Resource Bundle
▪ Logic
– Check for properties in a sessionScope variable
– If not found, retrieve properties and store in sessionScope
– Return a handle to the properties HashMap
▪ Full function available in Mastering XPages Book (pg 640-641)
▪ Example
getTranslations();
42
50. III. Retrieving a Custom Resource Bundle
▪ Magic!
!
43
var resource = new com.ibm.xsp.resource.BundleResource();
resource.src = "/MyTranslations.properties";
resource.component = view;
keys = resource.contents;
51. IV. Translating Computed Values
▪ Computed labels, links, menu titles, etc must be localized
▪ Any code that returns a message to display to the user must be localized
▪ Call a function and pass it the name of a key and it will return the translated value
!
function getTranslatedString(key) {
return getTranslations()[key];
}
▪ Example
!
getTranslatedString(“ErrorMessage”)
Tip! Put the code in a try-catch block to prevent errors
44
52. Improving Localization
▪ Sample errors when a key is not found in the resource bundle
– Better to trap for this ahead of time
52
53. Improving Localization
▪ Sample errors when a key is not found in the resource bundle
– Better to trap for this ahead of time
53
54. IV. Translating Computed Values
▪ Parameterized Messages
– Greeting that includes the user’s name
– Error message that includes error count
▪ I18n.format()
– Add placeholders to value in properties file
– Properties File:
!
ErrorMessage=Uh oh, {0}, there are {1} errors!
!
– SSJS:
!
45
var msg = getTranslations()[‘ErrorMessage’];
return I18n.format(msg, session.getCommonUserName(), numErrors);
55. V. Translating Keyword Lists
▪ Critically Important
– Documents are classified on predefined status or type values
– Views are generally filtered or categorized on keyword values
– Charts are based on keywords
47
56. V. Translating Keyword Lists
▪ Best Practice: Aliased Keyword Lists in Resource Bundle
– Store the alias in the field and display the translated value in the current language
– Aliasing allows for filtering and categorization in any language
▪ Resource Bundle Example
– # My Form Keywords
– Division=1_Division A|^|2_Division B|^|3_Division C|^|4_Division D
– Status=1_New|^|2_Current|^|3_Expiring|^|4_Late
!
▪ Tips!
– Consistent pattern for alias
– Don’t use comma (,) as a separator
– No spaces around equals sign (=) or between options
48
57. V. Translating Keyword Lists
▪ Create SSJS function to retrieve aliased keyword list:
– Retrieve the specified property value
– Parse the options, based on the alias and separator
– Return array of aliased keywords
▪ Example
getKeywordList(“Status”);
▪ Code snippet
…
var intPosition = thisOption.indexOf("_");
// Process each option to reformat as [DisplayOption]|[Alias]
var alias = thisOption.substring(0, intPosition);
var display = thisOption.substring(intPosition + 1);
listOptions[i+1] = display + "|" + alias;
…
49
58. VI. Displaying Selected Keyword in Read Mode
▪ Create SSJS function to display a keyword value in read mode
– Use string parsing to retrieve keyword list and get translated value based on alias
– Used for views, charts, etc.
getKeywordDisplay(key, alias);
▪ Example
!
getKeywordDisplay(“Status”, “1”);
50
59. IV. Translating Computed Values
▪ Tip! Only define common sets of choices one time
– Examples:
• Yes, No, Maybe, N/A
• Strongly Disagree, Disagree, Neutral, Agree, Strongly Agree
46
62. Additional Considerations
▪ What we’re not translating
– User-entered text
• We’re managing controlled sets of values
– Proper nouns
• Names, locations, etc
56
63. Additional Considerations
▪ Numeric default values in text fields
– A default of 0 would be translated
– Compute the value as: return ‘0’
▪ Text within pass-through HTML tags in page source
– Tags are untouched, but text within them is set up for translation
• Problematic with <script> tags – use Output Script controls instead
57
64. Additional Considerations
▪ Currency symbol will be automatically modified based on the locale
▪ Override by computing currency codes and symbols
– They can only be computed on page load – they cannot be refreshed dynamically
• Cannot work in a view display on a per-document basis
– If both are set, symbol overrides code
55
65. Additional Considerations
▪ Client-Side JavaScript
– Client JS within an <xp:> tag can use EL syntax
!
"#{javascript:return getKeywordDisplay('Status', '1');}“
!
– If you need a translated value outside of <xp:>, use SSJS to write out client-side JS vars
▪ Scheduled LotusScript agents
– Cannot read properties files
58
66. Additional Considerations
▪ Search
– Full-text search will not work as expected – keyword values are all stored as aliases
– Solution: Set up translated drop-down lists for filtering
• Programmatically build search string looking for the selected alias in the field
• Notify users that full-text search will work only on plain text fields
▪ Beyond Your Control
– “Browse” button in File Upload control from Extension Library
• Does not get automatically translated by browser and does not have a parameter to
programmatically translate
• Hacktastic
59
67. Additional Considerations
▪ Tip! Build the application with localization in mind, but do not send files for translation until
design is stable
59
68. ▪ Access Connect Online to complete your session surveys using any:
– Web or mobile browser
– Connect Online kiosk onsite
!
68