Skip to content

Latest commit

 

History

History
112 lines (70 loc) · 14.2 KB

resource_injection.md

File metadata and controls

112 lines (70 loc) · 14.2 KB

DXP Support for Injection of Dynamic Resources

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 in portal-kernel

DynamicInclude is the lowest-level API that lets programmers inject arbitrary content in any rendered page through access to its HttpServletResponse.

DynamicIncludes 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.

Core DynamicInclude Keys

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:

  1. /html/common/themes/top_head.jsp#pre: injects content right at the top of the head, just after the title and meta tags.
  2. /html/common/themes/top_js.jspf#resources: injects content right at the top of the body, above /html/common/themes/top_head.jsp#post.
  3. /html/common/themes/top_head.jsp#post: injects content right at the top of the body, above the alert messages (if any).
  4. /html/common/themes/body_top.jsp#post: injects content right at the top of the body, under the alert messages (if any).
  5. /html/common/themes/bottom.jsp#pre: injects content at the top of the body, before all portlet resources (.css and .js) are injected.
  6. /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

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

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.

How to define TopHeadResources

You can define TopHeadResources using Java code like in AUITopHeadResources, but you can also use an easier declarative syntax.

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 to src/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 to src/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 as service.ranking to prioritize the associated TopHeadResources.

Whenever a bundle containing one of the first two headers is deployed to DXP, TopHeadExtender scans it and creates a TopHeadResources on the fly.

liferay-util:html-top, liferay-util:html-bottom, and liferay-util:body-bottom tags

The <html-top>, <html-bottom> and <body-bottom> tags can be used to inject arbitrary HTML code to the rendered page at specific positions:

See section Core DynamicInclude Keys for more information on these JSP files.

OutputData

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.

ScriptData

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.

List of Frontend Infrastructure DynamicIncludes

At the time of writing, there are several infrastructure DynamicIncludes 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.