ddraper

Localization Considerations

Blog Post created by ddraper on Mar 1, 2013

Introduction

In my second post in this series I showed how to create a page from existing widgets and in my last post I showed how to create a custom widget. In custom widget showed how to specify i18n properties files of different locales in order to ensure that the widget labels could be rendered in different languages, however I didn't demonstrate how to localize pages nor how the two approaches work together.

 

How it Works Currently...

If you’re familiar with WebScripts you’ll know that you can provide i18n properties files with the same prefix that can then be accessed in the JavaScript controller by calling:

msg.get(<key>)

 

or from the FreeMarker template by calling:

${msg(“<key>”)}


You may also know that traditionally Share would pass all of the messages from a WebScript into the widgets that it instantiated by calling its '.setMessages()' function.

Finally, you should also be aware that there is a global properties files that can be used throughout Share (“common.properties” and “slingshot.properties” that can be found in '/share/WEB-INF/classes/alfresco/messages').

The contents of all of these files ultimately end up on the page in the JavaScript global variable “Alfresco.messages”. This is a map with the following attributes, “global” and “scope”.

    • “global” contains all the messages from the global properties
    • “scope” is a map of widget name to messages map

 

The Share widgets “.setMessages()” function adds its own name as a key into the scope map and assigns all the supplied messages as an object against that key. For example, if the “Alfresco.DocumentList” widget is instantiated then “Alfresco.messages.scope['Alfresco.DocumentList']' can be used to access it’s messages.

 

How the Updated Approach Works...

We've ensured that the updated development approach is consistent with this old pattern and have intentionally not followed the standard Dojo pattern. The new approach uses the same “Alfresco.messages” object (although this can be reconfigured if you want to use a different root variable) and still sets the “global” and “scope” attributes.

If you create a widget with an “i18nScope” attribute then this is the scope into which the widgets encapsulated messages will be added. If no “i18nScope' attribute is defined then the messages will go into a scope called “default” (unless the widget extends another widget in which case it will inherit its “i18nScope” attribute).

The i18n properties from the WebScript that processes the JSON model will automatically be placed into a new attribute of “Alfresco.messages” called “page”.

Whenever the “.message” function is called from “Alfresco/core/Core” (see previous post) all applicable scopes are searched, e.g.

    • global
    • page
    • default scope
    • all inherited scopes
    • widget scopes


...and the most specific result will “win”.


When creating a custom widgets there is obviously a distinction to be drawn between

    • labels that never change
    • variable labels that can be selected from
    • completely custom labels

 

For example, the label for a menu item cannot realistically be included as part of the widget but an error message could be. When accepting configurable labels its worth passing them through the “.message()” function in case a message key (rather than a localized message) has been provided as if no match has found then the supplied value is returned.

 

This means that when constructing the JSON model for a page you could provide:

config: {
   label: “message.key”
}

or

config: {
   label: msg.get('message.key')
}

 

At first glance these might appear identical, but if the widget defines a message with the key “message.key” then this will “win” over any message that the WebScript might be able to resolve.

 

Language Variations

It’s also worth bearing in mind that because the widgets process locale specific properties files in exactly the same way as WebScripts it is possible to simply reference a WebScripts properties file in the “i18nRequirements” attribute of a Widget. In a future post you’ll see how this can help you to wrap existing widgets easily so that they can be mixed with the our new library of widgets.

 

Summary

Hopefully this post has explained how i18n properties are handled in the new approach to page and widget construction. We have made efforts to ensure that the updates are compatible with the existing messages handling and have deliberately kept with the Alfresco approach rather than adopting the standard Dojo approach to avoid creating a divide. Ultimately we've done as much as possible to ensure that Surf takes care of all of the hard work for you.

Outcomes