Say I have 3 modules in a Liferay project, A
, B
and language
. Module A
is a normal module with portlet in it. Module B
, however, is a portletless module, it is nothing more than a plain Java utility module. language
module is something like what is described in the “Localizing Your Application” article in Liferay’s Help Center.
Now, I have one Language.properties
file in each of these modules. Language.properties
file in the language
module contains properties that are to be shared between modules A
and B
and Language.properties
file in modules A
and B
contains properties specific for each module.
Now, this Help Center’s article has defined what to do to enable reading from those files in a module. However, this article says that it is required to configure a portlet in the module where Language.properties
file is located.
That step may work for the module A
in my case, but for module B
I can not do this since module B
is portletless.
Inside the module B
I tried reading the Language.properties
file with the following code:
com.liferay.portal.kernel.language.LanguageUtil.get("locale", "key");
However, this does not work. It does not find the keys which I put in the B
‘s Language.properties
file. However, interestingly enough, what it finds are keys from the language
‘s Language.properties
file.
So, surprisingly invoking get
method of the LanguageUtil
class inside the B
module works, just it reads unwanted Language.properties
file.
My question here is, how can I configure Language Utilities to read the Language.properties
file from the portletless b
module instead of the language
common language module?
Advertisement
Answer
There are several layers to unfold here:
Liferay has pulled together almost all of its localization keys into a single module. From a product perspective, this is great, as it allows central handling of overrides, avoids duplicates, and even enables a UI to change those common keys.
For custom extensions, centralization is not such a great thing, and you’d rather come with your own translations in your custom modules (or explicitly use the default ones).
Enter OSGi: With using LanguageUtil
, my understanding is that you’re using the “current bundle” perspective, and LanguageUtil will only check Liferay’s own central translation repository. What you can (and likely should) do is to utilize ResourceBundleUtil in such a way:
ResourceBundle bundle = ResourceBundleUtil.getBundle(locale, this.getClass().getClassLoader()); String result = ResourceBundleUtil.getString(bundle, key, parameter);
Instead of this.getClass().getClassLoader()
, you can of course provide any other class’ loader, but it should give you a hint. This provides the bundle in which the translation is located.
Encapsulate this in a method that defaults back to any other localization that you’d like (could be another bundle, or Liferay’s global one), and you’ll find your translation.
Of course, you can also deploy a plugin that adds to Liferay’s own translations, but personally, I prefer not to go that route. There’s always potential to run into conflicts with other modules that try to translate the same key differently, or for Liferay to introduce the same key at some point in time (and it doesn’t play well with an individual portlet’s translation)