What do you do if the language keys you want to modify are in one of Liferay’s applications or another module whose source code you don’t control? Since module language keys are in the respective module, the process for overriding a module’s language keys is different from the process of overriding Liferay’s language keys.
Here is the process:
- Find the module and its metadata and language keys
- Write your custom language key values
- Prioritize your module’s resource bundle
Find the module and its metadata and language keys
In Gogo shell, list the bundles and grep for keyword(s) that match the portlet’s display name. Language keys are in the portlet’s web module (bundle). When you find the bundle, note its ID number.
To find the Blogs portlet, for example, your Gogo commands and output might look like this:
g! lb | grep Blogs
152|Active | 1|Liferay Blogs Service (1.0.2)
184|Active | 1|Liferay Blogs Editor Config (2.0.1)
202|Active | 1|Liferay Blogs Layout Prototype (2.0.2)
288|Active | 1|Liferay Blogs Recent Bloggers Web (1.0.2)
297|Active | 1|Liferay Blogs Item Selector Web (1.0.2)
374|Active | 1|Liferay Blogs Item Selector API (2.0.1)
448|Active | 1|Liferay Blogs API (3.0.1)
465|Active | 1|Liferay Blogs Web (1.0.6)
true
List the bundle’s headers by passing its ID to the headers
command.
g! headers 465
Liferay Blogs Web (465)
-----------------------
Manifest-Version = 1.0
Bnd-LastModified = 1459866186018
Bundle-ManifestVersion = 2
Bundle-Name = Liferay Blogs Web
Bundle-SymbolicName = com.liferay.blogs.web
Bundle-Version: 1.0.6
...
Web-ContextPath = /blogs-web
g!
Note the Bundle-SymbolicName
, Bundle-Version
, and Web-ContextPath
. The
Web-ContextPath
value, following the /
, is the servlet context name.
Important: Record the servlet context name, bundle symbolic name and version, as you’ll use them to create the resource bundle loader later in the process.
For example, here are those values for Liferay Blogs Web module:
- Bundle symbolic name:
com.liferay.blogs.web
- Bundle version:
4.0.16
- Servlet context name:
blogs-web
Next find the module’s JAR file so you can examine its language keys. Liferay follows this module JAR file naming convention:
[bundle symbolic name]-[version].jar
For example, the Blogs Web version 4.0.16 module is in
com.liferay.blogs.web-4.0.16.jar
.
Here’s where to find the module JAR:
- Liferay’s Nexus repository
[Liferay Home]/osgi/modules
- Embedded in an application’s or application suite’s LPKG file in
[Liferay Home]/osgi/marketplace
.
The language property files are in the module’s src/main/resources/content
folder. Identify the language keys you want to override in the
Language[_xx].properties
files.
Checkpoint: Make sure you have the required information for overriding the module’s language keys:
- Language keys
- Bundle symbolic name
- Servlet context name
Next you’ll write new values for the language keys.
Write custom language key values
Create a new module to hold a resource bundle loader and your custom language keys.
In your module’s src/main/resources/content
folder, create
language properties files
for each locale whose keys you want to override. In each language properties
file, specify your language key overrides.
Next you’ll prioritize your module’s language keys as a resource bundle for the target module.
Prioritize Your Module’s Resource Bundle
Now that your language keys are in place, use OSGi manifest headers to specify
the language keys are for the target module. To compliment the target module’s
resource bundle, you’ll aggregate your resource bundle with the target module’s
resource bundle. You’ll list your module first to prioritize its resource bundle
over the target module resource bundle. Here’s an example of module
com.liferay.docs.l10n.myapp.lang
prioritizing its resource bundle over target
module com.liferay.blogs.web
’s resource bundle:
Provide-Capability:\
liferay.resource.bundle;resource.bundle.base.name="content.Language",\
liferay.resource.bundle;resource.bundle.aggregate:String="(bundle.symbolic.name=com.liferay.docs.l10n.myapp.lang),(bundle.symbolic.name=com.liferay.blogs.web)";bundle.symbolic.name=com.liferay.blogs.web;resource.bundle.base.name="content.Language";service.ranking:Long="2";\
servlet.context.name=blogs-web
The example Provide-Capability
header has two parts:
-
liferay.resource.bundle;resource.bundle.base.name="content.Language"
declares that the module provides a resource bundle with the base namecontent.language
. -
The
liferay.resource.bundle;resource.bundle.aggregate:String=...
directive specifies the list of bundles with resource bundles to aggregate, the target bundle, the target bundle’s resource bundle name, and this service’s ranking:"(bundle.symbolic.name=com.liferay.docs.l10n.myapp.lang),(bundle.symbolic.name=com.liferay.blogs.web)"
: The service aggregates resource bundles from bundlescom.liferay.docs.l10n.myapp.lang
andcom.liferay.blogs.web
. Aggregate as many bundles as desired. Listed bundles are prioritized in descending order.bundle.symbolic.name=com.liferay.blogs.web;resource.bundle.base.name="content.Language"
: Override thecom.liferay.blogs.web
bundle’s resource bundle namedcontent.Language
.service.ranking:Long="2"
: The resource bundle’s service ranking is2
. The OSGi framework applies this service if it outranks all other resource bundle services that targetcom.liferay.blogs.web
’scontent.Language
resource bundle.servlet.context.name=blogs-web
: The target resource bundle is in servlet contextblogs-web
.
Deploy your module to see the language keys you’ve overridden.
Now you can modify the language keys of modules in Liferay’s OSGi runtime. Remember, language keys you want to override might actually be in Liferay’s core. You can override Liferay’s language keys too.