Any text in a widget that does not come from a remote API call can be defined in a resource bundle so that it can be localized.

Note: You can include localized resources in your widgets/elements by including a locales/ directory. However, this is not necessary. You can just as easily hardcode strings inside the HTML templates or JavaScript source files.

Use resource files

The resources reside in the widget locales directory:

<WIDGET TYPE> : the root folder of your widget
        locales/
            de/
                ns.<widget type>.json
            en/
                ns.widget type>.json

You must create a directory per locale and add a resource file containing the resources. The resource file name format should include the widget name, for example, ns.footer.json. Refer to the Resource loading section for more information on this format.

Localizable resources are defined using JSON objects composed of string keys, the resource names, mapped to string values, and the localized versions of each resource. The i18next JavaScript library is used to perform the client-side translations. An example locale file is shown below:


  "resources": {   
    "siteNavigationFooter" : "Site Navigation Footer",
    "editFooterHeader" : "Select Header Links (multi-select allowed)"
  }
}
Use resources in widgets

Primarily, widget resources are used when text in a widget display template is translated. A Knockout custom binding named ‘widgetLocaleText’ is available on Storefront to invoke the translation of the resource using the WidgetViewModel’s current locale. This will ultimately call the i18next library, but that is invisible to the widget templates. An example is shown below using the widgetLocaleText binding in its simplest form, passing in the resource key:

<h2 data-bind="widgetLocaleText: 'cartHeader'"></h2>

The resource files defined for a widget for the current locale are used to replace the key with the right resource. The locale is defined for the Storefront when the page is loaded. In the current release of Oracle Commerce Cloud Service, the locale is defined for the Site. The resources for the current locale are returned with the widget data when a page is loaded. These resources are mapped onto a widget and also as a namespace for i18next.

If you need to translate text within a widget’s JavaScript, use the translate function in the widget view model. This would be required, for example, when sending a message for display on the notification bar.

notifier.sendSuccess(widget.WIDGET_ID, widget.translate('loginSuccessText'));
Use variable replacement

Rather than manually concatenating variables to localized strings, the i18next library has support for variable replacement.

For example, a welcome message using the user’s first name can be defined in a resource, such as, “Welcome __userName__”. Then in the display template the translation can be invoked using a knockout object to set the userName variable, such as:

<span data-bind="widgetLocaleText : {value:'welcome', attr:'innerText', params: {userName: firstName()}}"></span>

Note that in the JSON resource we use a __doubleUnderscore__ notation to mark the variables, but when we invoke the resource in HTML or JavaScript we omit the underscores. The i18Next library provides other mechanisms such as support for plurals. Refer to the i18next section for further information.

Resource loading

By following the structure defined above for a widget, and putting the widget resources under the locales directory of a widget, the resources will be loaded for the widget by the framework. The data to build a page in the Storefront is retrieved from the Pages Web API Endpoint. For the current page, this endpoint will return both context data and the data related to the layout of the page, such as the regions and widgets to load.

Included with the data about each widget are the resources. These resources are then mapped onto the widget and loaded when the widget is loaded. The i18next namespace used to load the resources is defined as part of the widget definition within the server-side Page Repository. When a new widget is created, the widget descriptor defines a property called i18nresources:

{
  "name": "Widget Name",
  "version": 1,
  "javascript": "widget-name-js",
  "i18nresources": "widget-name",
  "availableToAllPages": true,
  "jsEditable": true,
}

The i18nresources property for a widget should be used in the file name for each locale resource name, in the format ns.<i18nresources property>.json.

So, for the widget definition shown above, the resources file name would be ns.widget-name.json. This i18nresources property is used in the Storefront framework when loading the resources and expects the format to be as defined here. Since the resources are no longer loaded directly via a URL, the file name itself is less important, but following the convention allows for consistency.

Use common resources: i18next

Currently there are two sets of expected common resources:

Use common resources: moment

The moment.js library (see http://momentjs.com) is used in Storefront to format dates. This requires a resource file per language. The ‘en’ version comes with moment but other languages require a separate JavaScript file.

Bundle images/other assets within widget

The simplest way to use custom resources (for example images) in a widget is to host them on an external server. The visitor’s browser then accesses them from that location.

It is also possible to bundle custom images within the file structure of a widget. When the extension is uploaded, the images are copied to a directory on the VFS, and you can access them via the Widget Asset Mappings. If you have an image ‘image1.png’ stored in the images/ directory of your widget, you can reference that resource in JavaScript with the following snippet:

widget.assetMappings["/images/image1.png"]();

The asset mapping is an observable, so use parentheses in JS code to extract the value.

You can also access the assetMapping from a knockout template, and be aware of the current binding context (for example, if inside a loop, you may need to use $parent to get back to the widget context). The sample below shows the HTML for an asset mapping:

<img class="product-item-img" data-bind="attr: {src: assetMappings[ productImage ] }">

Copyright © 1997, 2016 Oracle and/or its affiliates. All rights reserved. Legal Notices