Pre render hooks [@since 6.2]
Pre render hooks are functions that let you run code before Sitevision starts rendering a page. Hooks are declared in the hooks.js
file that must be placed directly under the WebApp's /src
folder.
To get access to the hooks available, simply require('hooks')
in your hooks.js
file. See example below.
Available hooks
There are three types of pre render hooks available: beforeRender, getPageTitle and addHeadElement.
beforeRender
The beforeRender hook accepts a function with req
and res
as arguments. This hook is intended to run arbitrary code.
beforeRender((req, res) => {})
getPageTitle
The getPageTitle hook accepts a function with req
as argument. This hook should return a string that will be used as title of the current page.
getPageTitle(req => 'Page title')
A null or blank string will be ignored. Sitevision will always escape the returned string. If multiple WebApps on the same page use this hook, the last successfully invoked getPageTitle-hook will be used as <title>
of current page.
addHeadElement
The addHeadElement hook accepts a function with req
as argument. This hook should return a string (a valid <head>
element) that will be added to the <head>
section of the current page.
addHeadElement(req => ...)
A null or blank returned string will be ignored. Sitevision will not escape the returned string so remember to escape all dynamically inserted values.
Request object (req
)
The request object (req
) is almost identical to the request object in a regular WebApp callback. However, there are two differences:
Additions
- A context object is available that makes it possible to fetch data in a hook and later consume it during rendering of the WebApp. See the example below of how it might be used.
Limitations
- route parameters will not be resolved. If you need to resolve route parameters in a hook, use the req.path property to resolve your captured value.
Response object (res
)
The response object (res
) is limited within the hooks context. The servlet response is not committed in this phase which makes it possible to set cookies and redirect. The following methods are available:
set(name, value)
- Set HTTP headers. Note that Content-Type cannot be set.
cookie(cookie)
- Set cookies
clearCookie(name)
- Clears a cookie
redirect(url)
- Sends a temporary (302) redirect to a given url
redirect(url, statusCode) [@since 2023.03.1]
- Redirect to a given url with a given status code
- Supported status codes:
- 301 (permanent)
- 302 (temporary)
- 303 [@since 2023.08.1]
- 307 [@since 2023.08.1]
- 308 [@since 2023.08.1]
- Defaults to 302 if no status code is provided
Example
Below is an example of what a hooks.js
might look like
// hooks.js
(function() {
'use strict';
const { beforeRender, addHeadElement, getPageTitle } = require('hooks');
const { getEventData } = require('/module/server/eventsApi');
const { escape } = require('underscore');
beforeRender((req) => {
const data = getEventData(req.params.eventId);
req.context.eventData = data; // req.context is propagated to the rendering phase (index.js)
});
getPageTitle((req) => req.context.eventData.title);
addHeadElement((req) => {
const description = escape(req.context.eventData.description);
return '<meta property="og:description" content="' + description + '">';
});
addHeadElement((req) => {
const image = escape(req.context.eventData.image);
return '<meta property="og:image" content="' + image + '">';
});
}());
The req.context
object is available during rendering of the WebApp with the data set in the beforeRender
-hook.
// index.js
router.get('/', (req, res) => {
logger.info(req.context.eventData); // eventData set in beforeRender hook
});
Requireables
Sitevision's Public API and WebApp specific requireables are available when evaluating hooks.
// hooks.js context, WebApp specifics
const
_ = require('underscore'); // [example](https://underscorejs.org/)
appData = require('appData'), // [example](/docs/webapps/webapps-1/configuration/appdata),
appInfo = require('appInfo'), // [example](/docs/webapps/webapps-1/require/appinfo),
appResource = require('appResource'), // [example](/docs/webapps/webapps-1/resource#h-AppResource)
globalAppData = require('globalAppData'), // [example](/docs/webapps/webapps-1/configuration/appdata)
hooks = require('hooks'), // [example](/docs/webapps/webapps-1/pre-render-hooks)
i18n = require('i18n'), // [example](/docs/webapps/webapps-1/i18n)
storage = require('storage'), // [example](/docs/data-storage)
oauth2 = require('oauth2'), // since 7.0 [example](/docs/webapps/webapps-1/require/oauth2)
privileged = require('privileged'), // since 7.0 [example](/docs/webapps/webapps-1/require/privileged)
serverModule = require('/module/server/moduleName'); // [example](/docs/webapps/webapps-1/module)
The Sitevision Public API is always accessible server-side. All interfaces, classes and enums that are anotated with the @Requireable annotation is available via the require function.
Note that Public API requireables always has a leading capital letter (requireable name matches the name of the Public API interface/class/enum).
// Server context (e.g. index.js, server module etc.)
const
requester = require('Requester'),
properties = require('Properties'),
propertyUtil = require('PropertyUtil'),
resourceLocatorUtil = require('ResourceLocatorUtil'),
portletContextUtil = require('PortletContextUtil'),
permissionUtil = require('PermissionUtil'),
publishingUtil = require('PublishingUtil'),
versionUtil = require('VersionUtil'),
metadataUtil = require('MetadataUtil'),
metadataDefinitionUtil = require('MetadataDefinitionUtil'),
outputUtil = require('OutputUtil'),
userIdentityUtil = require('UserIdentityUtil'),
mimeTypeUtil = require('MimeTypeUtil'),
nodeIteratorUtil = require('NodeIteratorUtil'),
nodeTreeUtil = require('NodeTreeUtil'),
nodeComparatorUtil = require('NodeComparatorUtil'),
nodeFilterUtil = require('NodeFilterUtil'),
nodeTypeUtil = require('NodeTypeUtil'),
localInboundRestApi = require('RestApi'),
...