This document describes different APIs that can be used with DXP to inject resources (.js
, .css
, ...) to an HTML page, thus letting the user extend currently existing artifacts without any need to overwrite them (like it was previously done with hooks in older Liferay versions).
DynamicInclude
is the lowest-level API that lets programmers inject arbitrary content in any rendered page through access to its HttpServletResponse
.
DynamicInclude
s attach to a unique key
which identifies where the content is inserted. An example of such key can be /html/common/themes/top_head.jsp#post
which makes the content be inserted in this JSP file.
You can find an example of a DynamicInclude
attaching to that key in DXP's source code.
In particular, the register method is responsible for attaching the object to the key.
There are lots of DynamicInclude
keys inside DXP. You can find them by looking for liferay-util:dynamic-include
inside the source code.
However, there are six core keys that are widely used to insert custom resources for all pages rendered by DXP. They are, in orden of appearance in the rendered HTML:
/html/common/themes/top_head.jsp#pre
: injects content right at the top of thehead
, just after thetitle
andmeta
tags./html/common/themes/top_js.jspf#resources
: injects content right at the top of thebody
, above/html/common/themes/top_head.jsp#post
./html/common/themes/top_head.jsp#post
: injects content right at the top of thebody
, above the alert messages (if any)./html/common/themes/body_top.jsp#post
: injects content right at the top of thebody
, under the alert messages (if any)./html/common/themes/bottom.jsp#pre
: injects content at the top of the body, before all portlet resources (.css
and.js
) are injected./html/common/themes/bottom.jsp#post
: injects content at the top of the body, after all portlet resources (.css
and.js
) are injected.
There's more information about this in DXP's documentation.
TagDynamicInclude
is the counterpart of DynamicInclude
. It implements a tag that developers may put in their JSP files to provide an extension point to that JSP file.
For example, you can inject resources in /html/common/themes/top_head.jsp#pre
because the developer of the JSP file containing it put a <liferay-util:dynamic-include key="/html/common/themes/top_head.jsp#pre" />
inside.
You can see <liferay-util:dynamic-include>
's TLD here.
TopHeadResources
is a frontend infrastructure service built on top of DynamicInclude
.
It is used to inject JavaScript resources in the <head>
tag of the rendered HTML so that is is available to the page.
It distinguishes between guest and authenticated resources (the latter including the former). This allows serving a limited subset of JavaScript files for guest users that, usually, don't need the full set of JavaScript files to use the portal.
As multiple TopHeadResources
can be deployed, they are prioritized according to their service.ranking
.
You can define TopHeadResources
using Java code like in AUITopHeadResources, but you can also use an easier declarative syntax.
The declarative syntax is used in bnd.bnd
files and makes use of three different headers:
Liferay-JS-Resources-Top-Head
: this specifies a comma delimited list of JavaScript resources to include always. The path of the files is relative tosrc/main/resource/META-INF/resources
as they are fetched through the bundle's servlet context.Liferay-JS-Resources-Top-Head-Authenticated
: this specifies a comma delimited list of JavaScript resources to include only when the user has been authenticated. The path of the files is relative tosrc/main/resources/META-INF/resources
as they are fetched through the bundle's servlet context.Liferay-Top-Head-Weight
: the value of this property is used asservice.ranking
to prioritize the associatedTopHeadResources
.
Whenever a bundle containing one of the first two headers is deployed to DXP, TopHeadExtender scans it and creates a TopHeadResources
on the fly.
The <html-top>
, <html-bottom>
and <body-bottom>
tags can be used to inject arbitrary HTML code to the rendered page at specific positions:
<html-top>
is injected atthemes/top_head.jsp
<html-bottom>
is injected atthemes/bottom.jsp
<body-bottom>
is injected atthemes/body_bottom.jsp
See section Core DynamicInclude
Keys for more information on these JSP files.
These tags make use of the OutputData
class which is an object placed in the ServletRequest
to store all code that must be output at the specified page positions.
Of course, in addition to the tags, the OutputData
object can be accessed programatically too, from any point of the code, to inject HTML code.
The ScriptData
is similar to OutputData
but specialized for JavaScript content.
It is stored inside the HttpServletRequest
, under the key WebKeys.AUI_SCRIPT_DATA
but there is no helper method to access it, so it has to be retrieved and stored manually.
The contents of the ScriptData
object are flushed in themes/bottom.jsp
, right before the contents injected by the <html-bottom>
tag.
At the time of writing, there are several infrastructure DynamicInclude
s used for different purposes.
Here's a list of projects defining them for quick reference:
Project | Functionality |
---|---|
frontend-compatibility-ie |
injects IE compatiblity layer. |
frontend-css-variables-web |
injects a <style> block containing the definitions for CSS variables. |
frontend-editor-ckeditor-web |
injects CKEditor files. |
frontend-js-alert-support-web |
|
frontend-js-collapse-support-web |
|
frontend-js-dropdown-support-web |
|
frontend-js-jquery-web |
injects jQuery files when enabled in the System Settings. |
frontend-js-loader-modules-extender |
injects AMD Loader configuration. |
frontend-js-lodash-web |
injects Lodash files when enabled in the System Settings. |
frontend-js-spa-web |
injects SPA support when enabled (see Senna.js too). |
frontend-js-svg4everybody-web |
injects SVG for Everybody support. |
frontend-js-tabs-support-web |
|
frontend-js-tooltip-support-web |
|
frontend-js-top-head-extender |
injects defined TopHeadResources . |
frontend-theme-contributor-extender |
injects resources provided by Theme Contributors. |
frontend-theme-font-awesome-web |
injects Font Awesome resources. |
remote-app-support-web |
injects JavaScript files implementing the Remote App callback API. |
However, because this is subject to continuous change, we recommend searching for implementations of the DynamicInclude
in the IDE to see the most up-to-date list.