Saturday 19 May 2018

Internationalization (I18n) in AEM using Sightly, JS and Java

AEM enables you to internationalize strings which allows you to display localized strings in your UI.
Internationalization (i18n) is a process of translating your content (strings) in different languages according to your requirement.
You can internationalize strings in the following types of resources:
  • Java source files.
  • HTML using Sightly
  • Javascript in client-side libraries or in page source.
First of all, create a i18n folder of type sling:folder under your project folder in apps, then create a json file of your language name and add jcr:mixinTypes as mix:language from tools option in crx bar and then add a property jcr:language and value as your language code as shown below:

The content of en.json will be key-value pairs in json format for each language file. eg:
en.json

{
 "Hello {0} !! This is coming from {1}" : "Hello {0} !! This is coming from {1}",
 "key.java" : "This is coming from Java"
}
fr.json
{
 "Hello {0} !! This is coming from {1}" : "Bonjour {0} !! cela vient de {1}",
 "key.java" : "Cela vient de Java"
}
The advantage of having the above json approach over creating sling:messageEntry node and then adding sling:key and sling:message property is, in a single json file you can enter as much key-value entries for your message instead of creating node each time for each message entry.

Translator to manage Dictionaries in AEM -


AEM provides a console for managing the various translations of texts used in component UI.
Use the translator tool to manage English strings and their translations. The dictionaries are created in the repository, for eg. in our cas/apps/training/i18n.

The tranlsator console is available at http://localhost:4502/libs/cq/i18n/translator.html

Below is the screenshot of our entries in i18n folder shown in this console:


















Using i18n in Java code -


The com.day.cq.i18n Java package enables you to display localized strings in your UI. The I18n class provides the get method that retrieves localized strings from the AEM dictionary. To include this package, add the below dependency in your pom.xml
<dependency>
    <groupId>com.day.cq</groupId>
    <artifactId>cq-i18n</artifactId>
    <version>5.4.0</version>
    <scope>provided</scope>
</dependency>
Below java class demonstrate the use of I18n class and how to translate content:
package com.foo.community.core;

import java.util.Locale;
import java.util.ResourceBundle;
import com.day.cq.i18n.I18n;
import com.adobe.cq.sightly.WCMUsePojo;

public class I18nUtility extends WCMUsePojo{
 
 private String val;
 Locale locale;
 ResourceBundle resourceBundle;
 
 @Override
 public void activate() throws Exception {
  
     locale = new Locale("en");
     if(getResourcePage().getPath().contains("fr")){
  locale = new Locale("fr"); 
     }
     resourceBundle = getRequest().getResourceBundle(locale);
     I18n i18n = new I18n(resourceBundle);
     val = i18n.get("key.java"); 
 }
 public String getVal() {
  return val;
 }
}

You can also get the page locale by using:
Locale pageLang = currentPage.getLanguage(false);


Using i18n in Sightly code -


This is the simplest way to use i18n in aem, just you have to use the @i18n with the key name
and you will get output according to your page locale.
For eg.
<p> ${"Hello {0} !! This is coming from {1}" @ i18n, 
   format=['Prasanna','Sightly'], context='html'} </p>

<p data-sly-use.i18j = 'com.foo.community.core.I18nUtility'>${i18j.val}</p>
As you can see from the above code, I have passed 2 parameters as an argument to dynamically generate the translation content. So whatever will be inside {} will be treated as to be replaced by dynamic arguments.

Now I am printing the above value along with using java class and the value returned from it in sightly code. Below screenshot shows the output in English and French page-


Using i18n in Javascript code -


The Javascript API enables you to localize strings on the client. 
The granite.utils client library folder provides the Javascript API. To use the API, include this client library folder on your page. Localization functions use the Granite.I18n namespace.
Below is the example of using i18n in JS:
Granite.I18n.setLocale("en");
if(window.location.href.indexOf("fr")>=0){
   Granite.I18n.setLocale("fr"); 
}
alert(Granite.I18n.get("Hello {0} !! This is coming from {1}"
   ,['Prasanna', 'Javascript']));
Below screenshot of the English and French page shows the JS alert of how to use i18n in js by passing dynamic arguments as parameter:


Now you can pickup the method which ever you want to use and get started with the internationalization in AEM.

References https://helpx.adobe.com/experience-manager/6-3/sites/developing/using/i18n-dev.html

5 comments:

  1. how can we access project specific json?
    i have tried this way and getting all the projects keys
    http://localhost:4502/libs/cq/i18n/dict.fr.json

    ReplyDelete
  2. What if specific language json is not available? will it be default to English? In such case if dont want to print text when there is not specific language json, how can we do it? could you please help me out

    ReplyDelete