Handling different locales in a portlet

According to the JSR 286, Portlet Specification, each portlet manages the internationalization, also called i18n . In this recipe, you will see what WebUI adds to the i18n of a portlet and how the services work.

Getting ready

You need Version 3.2.0 of GateIn working on Tomcat or on JBOSS, the sample application, and two Resource Bundles to test the localization.

How to do it...

Start to add an internationalization sample to an existing project:

  1. Create two Resource Bundles in your sample application. The conventional name of the folder for the Resource Bundle of a portlet is: $APPLICATION_NAME/WEB-INF/classes/locale/portlet/$APPLICATION_NAME/$PORTLET_NAME_xx.properties.

    Write a double APPLICATION_NAME because you can write a Resource Bundle for an application and store it in another application. An example is the PORTAL_ROOT application that stores all Resource Bundles for other applications.

    XX represents one of the names of the locales available in $PORTAL_ROOT/WEB-INF/conf/common/locales-config.xml.

  2. Add to the MyPortlet_en.properties file in the MyApplication/WEB-INF/classes/locale/portlet/MyApplication folder:
    word1=Test
    word2=Test2
  3. Add also to the MyApplication/ WEB-INF/classes/locale/portlet/MyApplication/MyPortlet_it.properties file:
    word1=Prova
    word2=Prova2
  4. Add the chosen locale, in this case the Italian language, and the name of the Resource Bundle file in portlet.xml:
    <resource-bundle>
       locale.portlet.MyApplication.MyPortlet
    </resource-bundle>

    We can call the Resource Bundle from the portlet:

    import java.util.Locale;
    import java.util.ResourceBundle;
    import org.exoplatform.webui.application.*;
    import org.exoplatform.webui.application.portlet.*;
    ...
    public class MyPortlet extends UIPortletApplication  {
    
        public MyPortlet() {
           ...
           PortletRequestContext context = 
              (PortletRequestContext) WebuiRequestContext
                .getCurrentInstance();
           Locale locale = context.getLocale();
            ResourceBundle resourceBundle =  
               context.getApplicationResourceBundle();
            String word = resourceBundle.getString("word1");
           ...
        }
    }

    Alternatively, we can call the Resource Bundle from the Groovy script as follows:

    <%= _ctx.appRes("word1"); %>

    Now you need to test the Resource Bundle, changing the language for the demo user.

  5. Log in as root and go to Users and groups management:
    How to do it...
  6. Edit the demo user information. Select Italian from the Language drop-down for the demo user as shown in the following screenshot:
    How to do it...
  7. Now sign off, sign in as demo user, and go to the custom portlet where you have added the row in the Groovy script. You will see the value Prova.

How it works...

All supported languages are declared in the locales-config.xml file inside $PORTAL_ROOT/WEB-INF/conf/common.

The Locale Service represented by the org.exoplatform.services.resources.impl.LocaleConfigServiceImpl class registers this information in memory when the portal starts.

This is the configuration of the Locale Service:

<component>  
  <key>
org.exoplatform.services.resources.LocaleConfigService
  </key>
  <type>
org.exoplatform.services.resources.impl.LocaleConfigServiceImpl
  </type>
  <init-params>
     <value-param>
        <name>locale.config.file</name>
        <value>
           war:/conf/common/locales-config.xml
        </value>
     </value-param>
  </init-params>
</component>

This is the English configuration in the locales-config.xml:

<locale-config>
    <locale>en</locale>
    <output-encoding>UTF-8</output-encoding>
    <input-encoding>UTF-8</input-encoding>
    <description>
       Default configuration for english locale
    </description>
</locale-config>

The first locale in the file is automatically the default, unless it is configured manually.

When a page loads initially, the portal finds and registers the property lang of the HttpServletRequest as locale client-side and the locale server-side in the Portal Context. The default server-side in the Portal Context is the English.

The page requests the default locale from the Portal Context, and interrogates the Locale Config Service and sets all the locale properties for the page.

A Localization Lifecycle starts when the HttpRequest is processed. This is a listener configured in the file $PORTAL_ROOT/WEB-INF/webui-configuration.xml:

<application-lifecycle-listeners>       
      ...   
  <listener>
org.exoplatform.portal.application.localization.LocalizationLifecycle
  </listener>       
</application-lifecycle-listeners>

Here are the events, which are managed by the Localization Lifecycle from the org.exoplatform.web.application.ApplicationLifecycle interface :

public void onInit(Application app)
public void onStartRequest(Application app, E context)
public void onFailRequest(Application app, E context, RequestFailure failureType)
public void onEndRequest(Application app, E context)
public void onDestroy(Application app)

Here is the code from the org.exoplatform.web.application.ApplicationRequestPhaseLifecycle interface:

/**
    * Perform any processing required at the beginning of {@link Phase#ACTION} or {@link Phase#RENDER} phase.
    * @param app Application
    * @param context current RequestContext
    * @param phase starting phase
    */
   public void onStartRequestPhase(Application app, E context, Phase phase);

   /**
    * Perform any processing required at the end of {@link Phase#ACTION} or {@link Phase#RENDER} phase.
    * @param app Application
    * @param context current RequestContext
    * @param phase ending phase
    */
   public void onEndRequestPhase(Application app, E context, Phase phase);

The Localization Lifecycle creates LocalizationContext containing all local information from the browser, the request, the session, the portal, and the user profile.

The Localization Lifecycle will calculate the current locale through a policy mechanism.

The org.exoplatform.portal.application.localization.DefaultLocalePolicyService class represents the default locale policy.

It calculates the current locale according to whether the user is registered or anonymous. It decides whether to give priority to the session, to the request, or to the portal configuration locale.

As the first step, it verifies if a registered or anonymous user is logged on. If there is a registered user, it searches the current locale in the cookies, in the session, and then in the request. If the user is anonymous, the control is done only in the request.

The policy is customizable. Here is the default configuration taken from the $PORTAL_ROOT/WEB-INF/conf/portal/web-configuration.xml file:

<component>
  <key>
    org.exoplatform.services.resources.LocalePolicy
  </key>      
  <type>
org.exoplatform.portal.application.localization.DefaultLocalePolicyService
  </type>
</component>

Once the default locale is calculated, the Resource Bundles will always use it for the rendering of the words.

There's more...

See now how the Resource Bundle works.

Resource Bundle Service

The Resource Bundle is a Java object (java.util.ResourceBundle) used to register localized phrases and words callable through keys. GateIn provides a Resource Bundle Service that is represented by the class org.exoplatform.services.resources.impl.BaseResourceBundleService. It is tied to the Locale Service because each Resource Bundle has the proper path according to the used locale.

It registers in memory a set of files ending with the notation –xx, where xx represents the locale declared in the local-config tag of the locales-config.xml. The list of files that are loaded in memory can be found in the configuration of the Resource Bundle Service, in the same common-configuration.xml:

<component>
    <key>
org.exoplatform.services.resources.ResourceBundleService
    </key>
    <type> 
org.exoplatform.services.resources.impl.SimpleResourceBundleService
    </type>
    <value>locale.portal.expression</value>
    <value>locale.portal.services</value>
     ...

Each string present in the value tag represents a folder. For example, in the folder $PORTAL_ROOT/WEB-INF/classes/locale/portal, you have a set of Resource Bundles as:

Resource Bundle Service

All Resource Bundles are cached through an internal mechanism provided by eXo.

A part of the expression_it.properties:

word.cancel=Annulla
word.category=Categoria
word.change=Cambia
word.city=Cittu00E0
word.close=Chiudi
word.comment=Commento
word.content=Contenuto
word.country=Nazione
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.116.43.36