Expand my Community achievements bar.

AEM i18n from Javascript (try 2)

Avatar

Level 2

Apologies for the duplicate post. Seems like something in the original is breaking the page, so I'll try this again:

I'm trying to dynamically retrieve a translated message using Javascript from my created dictionary in AEM's translator (/libs/cq/i18n/translator.html).

We've got dictionary values set up like:

String               EN                  FR
========================================================
TEST-001        This is a Test1     FR:This is a Test1
TEST-002        This is a Test2     FR:This is a Test2
TEST-003        This is a Test3     FR:This is a Test3

I've looked through the Internationalizing UI Strings article (https://docs.adobe.com/docs/en/aem/6-2/develop/components/i18n/i18n-dev.html) but when I try to the following:

Granite.I18n.setLocale("en");
Granite.I18n.get("TEST-001");
or

Granite.I18n.setLocale("fr");
Granite.I18n.get("TEST-001");


I only get returned the string I've passed in (i.e. "TEST-001").

Could someone help me understand how to retrieve the translated value back?

Thanks!

18 Replies

Avatar

Employee

I'm not sure about the relationship between "String" and "EN" here, as the English string is typically the key. What do you get if you do:

Granite.I18n.setLocale("fr");
Granite.I18n.get("This is a Test1");

Avatar

Level 2

Hi Leandro,

The relationship between String and EN is based on the translator library found in /libs/cq/i18n/translator.html.

The String value is normally used as the lookup key in JSP or Sling and the EN is the actual translated value being returned if the locale is EN.

Regardless, if I pass the "This is a Test1" string into the Granite.I18n.get() function, with the locale set to FR, I still get back "This is a Test1"

Avatar

Level 3

Have you checked if your i18n works on JSP/Java? If it works there - I have no answer.

If not - make sure use set your dictionary correctly under /apps/your-app/i18n. 

Also, your page should be under /content/your-app/...

Avatar

Level 2
Hi Anton, Yes, I'm able to successfully use i18n using JSP, but we're looking to dynamically retrieve the string via javascript rather than preloading the string on page render.

Avatar

Level 3
  • Try to remove "-" from i18n key name.
  • Try to use CQ.I18n
  • Debug

Avatar

Level 2

Hi Daitienshi,

Consolidated i18n dictionaries are cached in the system. Therefore, addition of an entry may not reflect immediately. Does the dictionaries loaded at runtime have the keys TEST-001, TEST-002 and TEST-003 ? 

Also, in case the keys are missing, one could update the cache by restarting the bundle - org.apache.sling.i18n.

Avatar

Level 2

Hi Ankur,

The dictionaries do have the keys TEST-001, TEST-002, TEST-003 during runtime, as I can retrieve those values via JSP.  I can even modify the values and see those changes come in via JSP after a page refresh

Avatar

Level 2

Hi Daitienshi,

I tried the following steps

  1. Add keys in translator.html
  2. I18n.get("TEST-001"); returns "TEST-001" in both js and jsp
  3. Restart bundle org.apache.sling.i18n.
  4. I18n.get("TEST-001"); returns expected string in both js and jsp

Please let us know in case I am missing something. Also, please try restarting the bundle.

Avatar

Level 2

Hi Ankur,

I've added the keys in the translator.html.

In my JS, I use Granite.I18n.get("TEST-001"); using just I18n gives me an error of I18n not being defined?

I've restarted both the org.apache.sling.i18n and com.day.cq.cq-i18n bundles.

Refreshing the page with that code on their still only returns back the "TEST-001" value rather than the translated version.

Of note, my translations keys are in a separate dictionary for my app (/apps/myApp/i18n) rather than the default /libs/wcm/core/i18n.  Do I need to do something up to look at my dictionary?

Thanks!

Avatar

Level 2

Hi Daitienshi,

I am unable to reproduce the issue at my end.

All the translations in js will be same as those in jsp and therefore this does not look like a dictionary location issue. Also, Granite.I18n.get("TEST-001"); was used to test the same in js.

Avatar

Level 2

Hi Ankur,

I've noticed that there is an error in the browser console related to the granite.js:

Uncaught TypeError: Cannot read property 'externalize' of undefined(...) getToken    @ granite.js:176

The granite.js it's referring to is the /etc/clientlibs/granite/jquery/granite.js.  

However, that doesn't seem to stop me from successfully calling the Granite.I18n.getDictionary() and getting an object back.

Otherwise, my calls are very simple:

Granite.I18n.setLocale("FR"); Granite.I18n.get("TEST-001");

Maybe the error that I'm seeing is indeed causing this to fail?  Would you know what might be causing that line in the granite.js to be erroring?

Thanks!

Avatar

Level 2

Hi,

As per your comment, Granite.HTTP is undefigned. Please debug casues for the same.

Avatar

Level 2

It seems that the generated /etc/clientlibs/granite/jquery/granite.js includes code from granite.http.externalize.js, which contains this line of code that is erroring out.

I'm not sure where that granity.http.externalize.js comes from as it doesn't seem to included in the default bundle when installing AEM from scratch.

Is there a way to remove that file and force the granite.js to be generated without it?

Thanks!

Avatar

Former Community Member

Note we solved this using https://docs.adobe.com/docs/en/aem/6-2/develop/the-basics/clientlibs.html and adding a dependency to our client lib.

"categories (string) multiple" or "dependencies String[] granite.utils"

This defines the Granite.I18n.get API. Similar to a Java import.

Hope this helps others trying to solve this issue.

-Joel

Avatar

Employee

Hi,

Do you see any errors from your browser?

The Javascript implementation will need to retrieve the dictionary as JSON via an Ajax request. You should see a request to something like /libs/cq/i18n/dict.fr.json.

Can you check this url returns the expected information?

Avatar

Level 2
Hi Joseph, How would I request the dictionary via AJAX? I can call Granite.I18n.getDictionary() and get an object back but I have no clue what this object is (have tried a bunch of the functions it has defined) but still can't get anything out of it.

Avatar

Level 1

Hope this might help someone looking for solution.

 

This has worked for me:

var pageLang = new java.util.Locale(currentPage.getLanguage(false).getLanguage());
var resourceBundle = request.getResourceBundle(pageLang);
var i18n = new com.day.cq.i18n.I18n(resourceBundle);

 

i18n.get("String that needs to be translated")