Can I get entire i18n labels of specific dictionary

安稳与你 提交于 2019-12-08 05:22:30

问题


I am facing an issue with i18n labels.

My application reads few i18n labels at js frontend using Granite.I18n.get('') function. The entire dictionary gets downloaded as ‘/libs/cq/i18n/dict.{+locale}.json’ as dictated in ‘/etc/clientlibs/foundation/shared/source/init.js’.

Now the en dictionary returns only the custom labels and is small size. But other languages like fr,the dictionary file is aggregation of all /libs dictionary and is very huge. I noticed this in few other sites also.

tennantco.com

en dictionary - 118 KB

fr dictionary - 1.4 MB

Timewarnercable.com

en dictionary - 1.1 KB

fr dictionary - 1.2 MB

Thermofisher

en dictionary - 3 KB

fr dictionary - 695 KB

Our pain point with this is, cost of caching this heavy file at CDN increases and trying to find a way to reduce CDN cost.

I understand en labels are the key itself. But the ExportServlet is able to filter out the render custom dictionary only for en. Our dictionaries are similar to otb dictionaries under /libs. Then how come ExportServlet treat otb labels under en export?

Is this bug common in all CMS products or specific to Adobe? Also need a solution or workaround to get custom dictionary only for other languages.


回答1:


The English dictionary is small because English entries are the keys and not the translation. French (and other languages) are big because they contain the key in English and further translation. Also, a lot of keys are only available in translated languages only because the key is used as default translation.

So for French, if you use Granite.I18n.get('Hello world!'), it will return the French translation if it finds it otherwise it will simply return 'Hello World', which doesn't require a translation if the language context is English.

Due to the nature of JS being evaluated on client side, the product is designed to download the full dictionary including the OOTB translation of the product itself as the i18n implementation is not context aware and cannot filter out unwanted translation.

While convenient, this is a limitation and side effect of using Granite.I18n.get('') unfortunately.

Possible Workarounds

  • Granite.I18n.* can be avoided by using server side i18n libs and rendering only the required translations on server and serving as partial HTML. This may not work for SPA.
  • If you are using SPA frameworks like Angular(x) then they support i18n factory initialisation which can be hooked into custom servlet response that downloads a filtered i18n. This can potentially be a lot of work and the size can still be a problem if too many terms are translated and dictionary grows large.
  • Compress, minimise and cache the dictionaries. You can do it with Apache modules or output filters. This will reduce the size and load on traffic but again it's not guaranteed that size will be small for the whole dictionary as the translations grow.

In general, the pages must only render what is required. Using JS to do late translation will force a dictionary download and Granite.i18n does not cater for optimised downloading experience.




回答2:


We faced the similar requirement to fetch I18n values at client side using Granite.i18n Library This is what I did.

  1. Created a custom servlet which returns JSON response similar to
    ResourceBundleExportServlet.
  2. Loaded the bundle using basename and locale parameter - ResourceBundle resourceBundle = req.getResourceBundle(basename,
    pageLocale);
  3. Added sling:basename="basename_constant"' in language specific i18n xml file which resides in /apps/project-name/i18n folder. In my case, I am setting the value of locale itself ex: "zh_cn".

4.In clientlibs javascript file setting Granite.I18n.setUrlPrefix("/bin/custom/i18n/dict."); to fetch from
custom servlet URL. This doesn't requires modification of OOTB I18n.js




回答3:


I ended up writing a custom implementation as I didnt get much help from Adobe tickets as well on this issue.

  • OTB dictionary json is rendered by ResourceBundleExportServlet
  • I created a custom sling servlet that ll prepare and return json similar to ResourceBundleExportServlet
  • Modified /etc/clientlibs/granite/utils/source/I18n.js to call the custom servlet rather than otb servlet.
  • Custom servlet is coded to return only specific data dictionary and not all dictionaries.

This solved my problem. Though am not convinced as proper solution. There needs to an otb way of rendering this clean.



来源:https://stackoverflow.com/questions/45330214/can-i-get-entire-i18n-labels-of-specific-dictionary

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!