Repository resource bundles
This page introduces repository resource bundles, how they are used in the Bloomreach Experience Manager product and how to use them in your own plugins.
Repository resource bundles are used to provide translations for strings that are introduced through configuration in the repository. Examples are:
- Translations for document type names, fields names and hints
- Translations for image set names and field names
- Translations for validator feedback texts
Repository resource bundles are one source for providing translations for the CMS UI. For more details, see CMS UI localization.
Bootstrapping
Repository resource bundles are imported using the configuration management mechanism and can be exported using the auto-export plugin. To import a resource bundle, specify YAML definitions like the following example:
definitions: config: /hippo:configuration/hippo:translations/myproject:translations jcr:primaryType: hipposys:resourcebundles /channelmanager: jcr:primaryType: hipposys:resourcebundles /awesomecomponent: jcr:primaryType: hipposys:resourcebundles /en: jcr:primaryType: hipposys:resourcebundle name: value workshopPeriod: The workshop starts on ${startday} and ends on ${endday}. /hippo:configuration/hippo:translations/hippo:types/myproject:book: jcr:primaryType: hipposys:resourcebundles /en: jcr:primaryType: hipposys:resourcebundle myproject:title: Book title /nl: jcr:primaryType: hipposys:resourcebundle myproject:title: Boek titel
The above example loads several resource bundles providing translations for the document type myproject:book, and for a project specific section for a project specific plugin. The resource bundle can be placed any level deep.
Using resource bundles in code
To use translated labels in Wicket code, the helper class org.hippoecm.frontend.l10n.ResourceBundleModel can be used such as in the following code snippet. This snippet could be used by the fictitious custom plugin in the example in section “Bootstrapping” to load the translation for the key “name” for the locale of the current user:
final String bundleName = "myproject:translations.channelmanager.awesomecomponent"; final String key = "name"; final Label label = new Label("label-wicket-id", new ResourceBundleModel(bundleName, key));
In case the label could not be found due to a coding or configuration error, the ResourceBundleModel returns “???” + key + “???” so you get visual feedback while setting up your Bloomreach Experience Manager project. See also the rules for the ResourceBundle below.
Under the hood, the ResourceBundleModel loads its data using the LocalizationService. It is also possible to call the LocalizationService directly such as in the following code snippet. This snippet shows how to obtain the English resource bundle containing the translations for the fictitious custom plugin in the example in section “Bootstrapping”:
final String bundleName = "myproject:translations.channelmanager.awesomecomponent"; final String locale = "en"; final LocalizationService localizationService = HippoServiceRegistry.getService(LocalizationService.class); if (localizationService != null) { final ResourceBundle bundle = localizationService.getResourceBundle(bundleName, locale); if (bundle != null) { // ... } } // …
Using variables
When working in Wicket you can replace variables defined in the string by supplying parameters, as in the following example:
Map<String, String> parameters = new HashMap<>(); parameters.put("startday", "Monday"); parameters.put("endday", "Wednesday"); ResourceBundleModel model = new ResourceBundleModel .Builder("myproject:translations.channelmanager.awesomecomponent", "workshopPeriod") .parameters(parameters) .build();
Which will result in a model containing the string "The workshop starts on Monday and ends on Wednesday.".
When using the LocalizationService and a ResourceBundle directly you can supply the parameters as second parameter like this:
String string = bundle.getString(key, parameters);
Conventions
When you examine the resource bundles that are bootstrapped by the product, you’ll notice two conventions:
- The # character is used to separate a label and a sub label for document field hints. For example when you enable the “blog” feature from Essentials, you see that for the type “myproject:author” a hint is defined for several fields, for instance for “account”: “myproject:accounts#hint”.
- The = character is used to separate a label and possible sub values, for instance in the resource bundle for the type “hippostd:date” which contains keys such as “hippostd:dayofweek=1”.