JSPs are native to Java EE and therefore have access to all the contextual
objects inherit to the platform, like the request and session. Through these
objects, developers can obtain Liferay DXP-specific context information by
accessing container objects like themeDisplay
or serviceContext
. This,
however, is not the case for FreeMarker templates. To access this information in
FreeMarker templates, you must inject it yourself into the template’s context.
Liferay DXP gives you a head start by injecting several common objects into the
template’s context and exposing them as
FreeMarker macros.
To inject other objects into the FreeMarker template’s context, you must create
a Context Contributor.
You can create a Context Contributor to use non-JSP templating languages for themes, widget templates, and any other templates used in Liferay DXP. For example, suppose you want your theme to change color based on the user’s organization. You could create a Context Contributor to inject the user’s organization into your theme’s context, and then determine the theme’s color based on that information.
Follow the steps below to create a context contributor:
-
Create an OSGi module using your favorite third party tool, or use Blade CLI.
-
Create a component class that implements the
TemplateContextContributor
service, and set thetype
property to the type of context you’re injecting into. Set it toTYPE_THEME
to inject context-specific variables for your theme, or set it toTYPE_GLOBAL
to inject it into every context execution in Liferay DXP, like themes, widget templates, DDM templates, etc, as defined in TemplateContextContributor. To follow naming conventions, begin the class name with the entity you want to inject context-specific variables for, followed by TemplateContextContributor (e.g.,ProductMenuTemplateContextContributor
):@Component( immediate = true, property = {"type=" + TemplateContextContributor.TYPE_THEME}, service = TemplateContextContributor.class )
-
Implement the TemplateContextContributor interface in your
*TemplateContextContributor
class, and overwrite theprepare(Map<String,Object>, HttpServletRequest)
method to inject new or modified variables into thecontextObjects
map. This is your template’s context that was described earlier.
The ProductMenuTemplateContextContributor
’s class is shown as an example
below. It overwrites the prepare(...)
method to inject a modified
bodyCssClass
variable and a new liferay_product_menu_state
variable into the
theme context for the Product Menu. Specifically, the cssClass
variable
provides styling for the Product Menu and the productMenuState
variable
determines whether the visible Product Menu should be open or closed:
@Override
public void prepare(
Map<String, Object> contextObjects, HttpServletRequest request) {
if (!isShowProductMenu(request)) {
return;
}
String cssClass = GetterUtil.getString(
contextObjects.get("bodyCssClass"));
String productMenuState = SessionClicks.get(
request,
ProductNavigationProductMenuWebKeys.
PRODUCT_NAVIGATION_PRODUCT_MENU_STATE,
"closed");
contextObjects.put(
"bodyCssClass", cssClass + StringPool.SPACE + productMenuState);
contextObjects.put("liferay_product_menu_state", productMenuState);
}
The ProductMenuTemplateContextContributor
provides an easy way to inject
variables into Liferay DXP’s theme directly related to the Product Menu. You can
do the same with your custom context contributor. With the power to inject
additional variables into any context in Liferay DXP, you’re free to fully harness
the power of your chosen templating language.