@item-enonic-types/lib-freemarker
v3.0.0
Published
Type definitions for lib-freemarker
Readme
FreeMarker for Enonic XP
This library lets you use Apache FreeMarker-templates with Enonic XP.
Installation
To install this library you need to add a new dependency to your app's build.gradle file.
Gradle
repositories {
maven { url "https://repo.itemtest.no/releases" }
maven { url "https://repo.itemtest.no/snapshots" }
}
dependencies {
include "no.item:lib-xp-freemarker:3.0.0-SNAPSHOT"
}TypeScript
To update the version of enonic-types in package.json using npm, run the following command:
npm i -D @item-enonic-types/lib-freemarkerYou can add the following changes to your tsconfig.json to get TypeScript-support.
{
"compilerOptions": {
+ "baseUrl": "./",
+ "paths": {
+ "/lib/xp/*": ["./node_modules/@enonic-types/lib-*"],
+ "/lib/*": [ "./node_modules/@item-enonic-types/lib-*" ,"./src/main/resources/lib/*"],
+ }
}
}Add types for IntelliJ
If you are using IDEs from IntelliJ, you can get the correct type for the portal object by adding a file
src/main/resources/freemarker_implicit.ftl with this content:
[#ftl]
[#-- @implicitly included --]
[#-- @ftlvariable name="portal" type="no.item.freemarker.FreemarkerPortalObject" --]Configuration file
You can configure the FreeMarker settings by adding an XP_HOME/config/freemarker.properties file.
To preserve backwards compatibility in an existing project you can set the incompatible_improvements version like this:
incompatible_improvements=2.3.25Developers should use the HTML Debug Exception Handler in their local development environments.
template_exception_handler=html_debug[!CAUTION] Do not use the
html_debugexception handler in production! It should only be used for development as it shows technical information about your system.
Usage
Render from template files
You can use resolve to get the ResourceKey of a template file in your application. Then you can pass in a data model
to render that template.
import { render } from "/lib/freemarker";
import { getContent } from "/lib/xp/portal";
import type { Response } from "@enonic-types/core";
type FreeMarkerParams = {
title: string;
text: string | undefined;
}
const view = resolve("article.ftl");
export function get(): Response {
const content = getContent()!;
const model: FreeMarkerParams = {
title: content.data.title,
text: content.data.text,
};
return {
body: render<FreeMarkerParams>(view, model),
};
};Render from inline strings
Alternatively you can use a string as the template.
import { render } from "/lib/freemarker";
import { getContent } from "/lib/xp/portal";
import type { Response } from "@enonic-types/core";
type FreeMarkerParams = {
title: string;
text: string | undefined;
year: string;
}
// The FreeMarker template as a string. Notice how the $ needs to be escaped.
const view = `
[#import "/site/utils/footer.ftl" as Footer]
<h1>\${title}</h1>
[#if text?has_content]
<p>\${text}</p>
[/#if]
[@Footer.render year=year /]
`;
export function get(): Response {
const content = getContent()!;
const virtualTemplateName = "my-inline-template.ftl";
const model: FreeMarkerParams = {
title: content.data.title,
text: content.data.text,
year: "2025"
};
return {
body: render<FreeMarkerParams>(view, model, virtualTemplateName),
};
};The portal object
The following utility functions are made available in the portal object:
portal.localize()portal.processHtml()
The portal-functions can be used within interpolations (${}). Example:
[#-- @ftlvariable name="nextPageUrl" type="String" --]
<a href="${nextPageUrl}">
${portal.localize("article.nextPage")}
</a>[!WARNING] Always use the
?no_escbuilt-in withportal.processHtml(). It prevents auto-escaping the markup if an output format is set.
The portal.component directive
When rendering components from regions in pages and layouts you can use the portal.component directive.
[#-- @ftlvariable name="mainRegion" type="com.enonic.xp.region.Region" --]
<div class="my-layout">
[#list mainRegion.components as component]
[@portal.component path=component.path /]
[/#list]
</div>If you are creating a view to preview fragments,
you can use the portal.component directive like this:
[@portal.component path="fragment" /]Localization
This library will use the first locale it finds, checking in the following order:
| Order | Source of locale | Use case |
|------:|---------------------------------------------------------------------------------------------|-----------------------|
| 1 | The language field of the current content | Normal content |
| 2 | The language field of the current site | E.g. the error page |
| 3 | The end users "Accept-Language" that matches a supported language in the i18n directory | E.g. an admin tool |
| 4 | Default to "en-US" | E.g. the main.js file |
So you can use the special variables ${.locale} and ${.lang}
to access the "language tag" resolved based on the list above.
You also don't need to pass in a locale for portal.localize() unless you want a different locale then automatically
selected locale.
<!doctype html>
<html lang="${.lang}">
<body>
<h1>The language tag is: ${.locale}</h1>
<p>${portal.localize("article.text")}</p>
</body>
</html>If you need another locale to be used (han that of the current content), you can set it with the
#setting directive.
[#-- Changes the `locale` to Norwegian for the remainder of the template. --]
[#-- This will affect the `portal.localize()` and date formatting. --]
[#setting locale="no"]
[#-- Setting the `time_zone` to get the correct time when formatting dates --]
[#setting time_zone="Europe/Oslo"]Deploying
Building
To build the project, run the following command
enonic project buildYou will find the jar-file at ./build/libs/lib-xp-freemarker-[version].jar
Deploying locally
Deploy locally for testing purposes:
./gradlew publishToMavenLocalDeploy to Maven
./gradlew publish -P com.enonic.xp.app.production=truePublish types to npm
npm publish
# npm publish --tag betaAcknowledgments
This library was inspired by the lib-freemarker library by TINE IKT.
