Type definitions for lib-freemarker
npm install @item-enonic-types/lib-freemarkerThis library lets you use Apache FreeMarker-templates with Enonic XP.
!Build badge



To install this library you need to add a new dependency to your app's build.gradle file.
``groovy
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"
}
`
To update the version of enonic-types in package.json using npm, run the following command:
`bash`
npm i -D @item-enonic-types/lib-freemarker
You can add the following changes to your tsconfig.json to get TypeScript-support.
`diff`
{
"compilerOptions": {
+ "baseUrl": "./",
+ "paths": {
+ "/lib/xp/": ["./node_modules/@enonic-types/lib-"],
+ "/lib/": [ "./node_modules/@item-enonic-types/lib-" ,"./src/main/resources/lib/*"],
+ }
}
}
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`
[#ftl]
[#-- @implicitly included --]
[#-- @ftlvariable name="portal" type="no.item.freemarker.FreemarkerPortalObject" --]
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:
`properties`
incompatible_improvements=2.3.25
Developers should use the HTML Debug Exception Handler
in their local development environments.
`properties`
template_exception_handler=html_debug
> [!CAUTION]
> Do not use the html_debug exception handler in production!
> It should only be used for development as it shows technical information about your system.
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.
`TypeScript
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
};
};
`
Alternatively you can use a string as the template.
`typescript
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]
[#if text?has_content]
\${text}
[@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
};
};
`
The following utility functions are made available in the
portal object:
- portal.localize()portal.processHtml()
-
The portal-functions can be used within interpolations (${}). Example:
`ftl
[#-- @ftlvariable name="nextPageUrl" type="String" --]
${portal.localize("article.nextPage")}
`
> [!WARNING]
> Always use the ?no_esc built-in
> with portal.processHtml(). It prevents auto-escaping the markup if an output format is set.
When rendering components from regions in _pages_ and _layouts_ you can use the portal.component directive.
`ftl
[#-- @ftlvariable name="mainRegion" type="com.enonic.xp.region.Region" --]
If you are creating a view to preview fragments,
you can use the
portal.component directive like this:`ftl
[@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.`ftl
The language tag is: ${.locale}
${portal.localize("article.text")}
`If you need another
locale to be used (han that of the current content), you can set it with the
#setting directive.`ftl
[#-- 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
$3
To build the project, run the following command
`bash
enonic project build
`You will find the jar-file at _./build/libs/lib-xp-freemarker-[version].jar_
$3
Deploy locally for testing purposes:
`bash
./gradlew publishToMavenLocal
`$3
`bash
./gradlew publish -P com.enonic.xp.app.production=true
`Publish types to npm
`bash
npm publish
npm publish --tag beta
``This library was inspired by the lib-freemarker library by TINE IKT.