i18n implementation using Sightly

09 / Nov / 2015 by Arpit Gupta 6 comments

Internationalization (i18n) is the process of generalizing a product so that it can handle multiple languages and cultural conventions without the need for re-design .

a. Structure format required for i18n implementation :

1) Create a i18n node of type sling:Folder as below

i18n properties

2) Create a node of type sling:Folder under i18n of mixin type mix:language and add a property called jcr:language and assign value of lang code  as below

i18n-folder properties

3) Create a message node of type sling:MessageEntry and a property called sling:key which will used to pull the value of the variable and also add a property called sling:message which will specify the value of the key as below

i18n-message properties

As soon as you create this structure you can look in CQ5-Translator and you should have similar translations created :


b. Normal way to implement i18n in Sightly : 

We can implement i18n directly by using the below syntax :

${'key' @ i18n}
${'key' @ i18n, source='user', hint='Translation Hint'}
${'key' @ i18n, locale='en', hint='Translation Hint'}

The default source for the language is ‘resource’, meaning that the text gets translated to the same language as the content. If you specify it to ‘user’ than the language is taken from the browser locale or from the locale of the logged-in user.But when we provide an explicit locale than we overrides the source settings and would take the specified locale.

In Sightly if we don’t define the attribute locale than it would automatically convert the text according to current page locale .

The hint is used to provide information about the context for the translators.

Issue and it’s alternative approach :

When I tried using the above approach for i18n implementation in sightly, it didn’t worked in a usual manner for different locale as it should work on.

Solution : So if such a scenario happened with you, you can also achieve it by creating a local template to which you can pass the variable identifying your key and than calling it by using  data-sly-call :

Implementation for the same is as below :

<template data-sly-template.i18="${@ key}">
 ${key @ i18n}

<div data-sly-call="${i18 @ key='key-name'}"></div>

This approach holds good and worked for me in all use cases .



comments (6)

  1. Anoop

    Hi Arpit,

    I have multiple dictionaries under “/etc/project_name/i18n”(e.g “/etc/project_name/i18n/default” and “/etc/project_name/i18n/overlay”).
    My requirement is picking up the values first from overlay path and if the overlay dictionary is empty, select the default path.
    With the usage of internationalization in sightly, I am always getting the key values from “default” dictionary first. Is there a way to change this order of preference?


  2. Ang


    I have multiple dictionaries under the path “/etc/project_name/i18n”.

    For eg “/etc/project_name/i18n/dictionary1” and “/etc/project_name/i18n/dictionary2”

    Sightly is always giving preference to dictionary1 and my requirement is to get the dictionary2.

    Is there a way to do so?

    Thanks in advance

    1. Navrattan Yadav

      No, you can’t gave preference to a directory. However AEM follow this order ResourceBundle hierarchies
      The dictionary entries for one JcrResourceBundle are always ordered like the resource resolver search paths, so usually

      dictionary entries below /apps
      dictionary entries below /libs
      dictionary entries anywhere else (outside the search path)
      That means that the message for the same key in /apps overwrites the one in /libs (if both are for the same locale and base name). Within those categories the order is non-deterministic, so if there is more than one entry for the same key in /apps/… (for the same locale and base name), any of those entries may be used.

      The resource bundles of the same base name with different locales also form a hierarchy. Each key is looked up recursively first in the current resource bundle and then in its parent resource bundle. The parent resource bundle is the one having the same base name but the parent locale.

      The locale hierarchy is ordered like this:

      , usually en
      So for the locale de-DE-MAC the fallback order would be


  3. Imran

    Is there a way to make a re-usable variable from the outcome of your template call. Pseudo code example:

    ${key @ i18n}

    I know this is completely wrong but hopefully this is showing what I’m looking for. rather than calling the same value over and over within the same file… Any help would be great. Thanks

  4. Ankit

    Thanks Arpit, this solution is working in Author but not picking the I18N value on Publish. Any thought?


Leave a Reply

Your email address will not be published. Required fields are marked *