Localization in the Preferences Framework makes use of Message Bundles: JSON files containing the strings that are to be used in the interface.
Message Bundles
Message Bundles are JSON files containing key/value pairs representing the message key and the localized text associated with it. Each set of localized text should be contained in its own Message Bundle.
{
"slidingPanelShowText": "+ Show Display Preferences",
"slidingPanelHideText": "- Hide"
}
Message Bundles cannot contain arrays. Instead a namespace should be used to group message keys together. This will require extra processing when using the messages. (See Using Message Bundles below)
{
"contrast-default": "Default",
"contrast-bw": "Black on white",
"contrast-wb": "White on black",
"contrast-by": "Black on yellow",
"contrast-yb": "Yellow on black",
"contrast-lgdg": "Low contrast",
"contrastLabel": "Colour & Contrast"
}
Required Components
MessageLoader
The messageLoader is an instance of a fluid.prefs.resourceLoader
responsible for retrieving all of the Message Bundles
added to the Prefs Editor (See Adding Message Bundles below). Message Bundles are
automatically distributed to the Prefs Editor and Panels based on the configuration supplied in the auxiliary
schema. However, to access the Message Bundle from other components on the
IoC tree, the IoC reference {messageLoader}.resources.<messageBundle>.resourceText
can be used. Additionally the
defaultLocale
and locale
options are used to specify which localization to fetch for each bundle. (See: Specifying
a localization below)
MsgLookup
The fluid.prefs.msgLookup
grade is required for any component through which a message lookup is performed. The
msgLookup grade wires up the msgLookup
IoC reference and the lookup
method for retrieving messages from the Message
Bundle (See: Using Message Bundles). The msgLookup's message resolution is mediated by a
fluid.messageResolver
subcomponent and it is to this subcomponent that the messageBase
option, containing the
fetched Message Bundle, is set.
For a fluid.prefs.panel
component, all of the fluid.prefs.msgLookup
configuration is prewired. For other components
to make use of this functionality, the following configuration is needed:
- add
fluid.prefs.msgLookup
as a parent grade - add an instance of
fluid.messageResolver
as a subcomponent with the member namemsgResolver
- link the messageBase to the fetched Message Bundle.
- e.g. using an IoC reference to the messageLoader:
{messageLoader}.resources.<messageBundle>.resourceText
- e.g. using an IoC reference to the messageLoader:
- for an instance of
fluid.rendererComponent
it is also necessary to use the messageResolver'sresolve
method as themessageLocator
Adding MsgLookup to a Component
Note: Renderer components require additional configuration. (See: Adding MsgLookup to a Renderer Component)
fluid.defaults("my.component", {
gradeNames: ["fluid.prefs.msgLookup", "fluid.component"],
components: {
msgResolver: {
type: "fluid.messageResolver"
}
},
// should contain the strings loaded from a Message Bundle
// e.g. messageBase: "{messageLoader}.resources.messageBundleName.resourceText"
messageBase: {},
distributeOptions: {
source: "{that}.options.messageBase",
target: "{that > msgResolver}.options.messageBase"
}
});
Adding MsgLookup to a Renderer Component
fluid.defaults("my.renderer.component", {
gradeNames: ["fluid.prefs.msgLookup", "fluid.rendererComponent"],
components: {
msgResolver: {
type: "fluid.messageResolver"
}
},
rendererOptions: {
messageLocator: "{msgResolver}.resolve"
},
// should contain the strings loaded from a Message Bundle
// e.g. messageBase: "{messageLoader}.resources.messageBundleName.resourceText"
messageBase: {},
distributeOptions: {
source: "{that}.options.messageBase",
target: "{that > msgResolver}.options.messageBase"
}
});
Adding Message Bundles
Message Bundles can be specified through the auxiliary schema. The Preferences Framework will load all of the Message Bundles and automatically distribute them to the panels.
Example Auxiliary Schema
{
"namespace": "fluid.prefs.constructed",
"terms": {
"templatePrefix": "../../../framework/preferences/html",
"messagePrefix": "../../../framework/preferences/messages"
},
"template": "%templatePrefix/SeparatedPanelPrefsEditor.html",
"message": "%messagePrefix/prefsEditor.json", // Message Bundle for the preference editor itself
"textSize": {
"type": "fluid.prefs.textSize",
"enactor": {
"type": "fluid.prefs.enactor.textSize"
},
"panel": {
"type": "fluid.prefs.panels.textSize",
"container": ".flc-prefs-text-size",
"template": "%templatePrefix/PrefsEditorTemplate-textSize.html",
"message": "%messagePrefix/textSize.json" // Message Bundle for the fluid.prefs.panels.textSize component
}
},
"lineSpace": {
"type": "fluid.prefs.lineSpace",
"enactor": {
"type": "fluid.prefs.enactor.lineSpace",
"fontSizeMap": {
"xx-small": "9px",
"x-small": "11px",
"small": "13px",
"medium": "15px",
"large": "18px",
"x-large": "23px",
"xx-large": "30px"
}
},
"panel": {
"type": "fluid.prefs.panels.lineSpace",
"container": ".flc-prefs-line-space",
"template": "%templatePrefix/PrefsEditorTemplate-lineSpace.html",
"message": "%messagePrefix/lineSpace.json" // Message Bundle for the fluid.prefs.panels.lineSpace component
}
}
}
Using Message Bundles
In the ProtoTrees
When using a fluid.rendererComponent
, strings from the Message Bundles are rendered into the templates through a
protoTree
, using the messagekey
with a message key from the Message Bundle:
Example use in a ProtoTree | JSON Message Bundle |
---|---|
|
|
IoC References
Message Bundles can also be resolved directly through an IoC reference making use of the msgLookup
property, which is automatically created for any panel component. This process is quite similar to how IoC references to
selectors are resolved.
fluid.defaults("fluid.slidingPanel", {
// ...
strings: {
showText: "{that}.msgLookup.slidingPanelShowText",
hideText: "{that}.msgLookup.slidingPanelHideText"
}
// ...
});
There are other, more complex cases where an array of strings is required (for example, for a set of radio buttons or a
drop-down). In these cases, a stringArrayIndex
in the components options needs to be specified. This defines the
following:
- which strings to include
- the order in which they should be returned.
It is accessed the same way that an individual string is referenced, except that reference should point to the key in
the stringArrayIndex
instead of a single string name. In the example below, the stringArrayIndex
is used to define
the theme
string bundle, and the theme
string bundle is referenced within the protoTree.expander.tree
('optionnames: "${{that}.msgLookup.theme}"
'):
fluid.defaults("fluid.prefs.panel.contrast", {
// ...
stringArrayIndex: {
// the theme values correspond to message keys in the Message Bundle.
theme: ["contrast-default", "contrast-bw", "contrast-wb", "contrast-by", "contrast-yb", "contrast-lgdg"]
},
protoTree: {
label: {messagekey: "contrastLabel"},
expander: {
type: "fluid.renderer.selection.inputs",
rowID: "themeRow",
labelID: "themeLabel",
inputID: "themeInput",
selectID: "theme-radio",
tree: {
optionnames: "${{that}.msgLookup.theme}", // IoC reference to the array of strings
optionlist: "${{that}.options.controlValues.theme}",
selection: "${value}"
}
}
}
// ...
});
The values in the theme
array, within stringArrayIndex
, directly correspond to namespaced message keys from the
Message Bundle.
{
"contrast-default": "Default",
"contrast-bw": "Black on white",
"contrast-wb": "White on black",
"contrast-by": "Black on yellow",
"contrast-yb": "Yellow on black",
"contrast-lgdg": "Low contrast"
}
Direct Access
The strings can also be accessed directly, outside of the context of IoC references or renderer protoTrees (for example,
in an invoker function), by making function calls to the internal string bundle lookup()
method.
that.msgLookup.lookup(value); // where value is either the string name or the key in the stringArrayIndex to lookup.
Specifying a Localization
The messageLoader is implemented using fluid.resourceLoader. It takes defaultLocale
and locale
options for specifying which localized Message Bundle to fetch. The locale
option specifies the localization desired.
By default it is sourced from the prefsEditorLoader's settings object, "{prefsEditorLoader}.settings.locale"
. The
defaultLocale
provides a fallback to use if the desired localization cannot be located. By default it is sourced from
the prefsEditorLoader's defaultLocale
option.
See fluid.resourceLoader options for the accepted form of locale
and
defaultLocale
.
See fluid.resourceLoader fallback rules for fallback rules when attempting to locate a localization.
Bundle Naming
The Message Bundles should conform to the following naming convention to facilitate discovery by the messageResolver:
<bundle name>_<language code>_<country code>.json
The following are all valid Message Bundle names and will work with the above Fallback Rules:
- prefsEditor_fr_CA.json
- prefsEditor_fr.json
- prefsEditor.json