# Creating a Custom Magnolia CMS Templating Function
# Introduction
Magnolia CMS templating functions (opens new window) allow you to provide Java functionality to FreeMarker templates. This guide will teach you how to create a custom templating function.
See magnolia-cms-templating-function-demo (opens new window) for a fully functional Maven module based on this guide.
# Prerequisites
This guide assumes the following:
- You have experience with a Java IDE (this guide references IntelliJ (opens new window))
- You've worked with the FreeMarker template engine (opens new window)
- You've worked with Magnolia pages (opens new window), components (opens new window), and templating functions (opens new window)
- You've created and installed a Magnolia Maven module (opens new window)
- You're familiar with Magnolia dependency injection (opens new window)
- You've written Magnolia version handler tasks (opens new window)
# Step 1—Creating the Module
Follow the Magnolia instructions (opens new window) to create a Magnolia Maven module with the Magnolia Maven archetype. Your module parameters should look something like:
groupId: com.ryanbrookepayne.magnolia
artifactId: magnolia-templating-functions
version: 1.0-SNAPSHOT
package: com.ryanbrookepayne.magnolia
magnolia-bundle-version: 6.1
module-class-name: MagnoliaTemplatingFunctionsModule
module-name: magnolia-templating-functions
# Step 2—Creating the Templating Functions Class
Open your newly created module with your IDEA and create a templating.functions
package in the main
directory.
Create a HelloWorldTemplatingFunctions
class in the templating.functions
package.
package com.ryanbrookepayne.magnolia.templating.functions;
public class HelloWorldTemplatingFunctions {
}
# Step 3—Creating the Functions
In the HelloWorldTemplatingFunctions
class, create a FUNCTION_NAME
field. Once installed, this name (hellofn
) will be globally available in all FreeMarker template scripts. While not functional, Magnolia follows the {function_name}fn
convention.
package com.ryanbrookepayne.magnolia.templating.functions;
public class HelloWorldTemplatingFunctions {
public static final String FUNCTION_NAME = "hellofn";
}
Next, add two simple Java methods:
package com.ryanbrookepayne.magnolia.templating.functions;
public class HelloWorldTemplatingFunctions {
public static final String FUNCTION_NAME = "hellofn";
public String sayHello() {
return "Hello world!";
}
public String sayHello(int headingLevel) {
return String.format("<h%1$s>Hello world!</h%1$s>", headingLevel);
}
}
Once the templating function is installed, these methods will be available in FreeMarker template scripts. For example:
${hellofn.sayHello()}
# Step 4—Installing the Functions
In Magnolia, templating functions are known as context attributes (opens new window) and are instantiated via dependency injection-using Google Guice (opens new window). Because of this, they must be configured as both components and renderers (opens new window).
# Adding the Component
Add the reference to the HelloWorldTemplatingFunctions
class to the magnolia-templating-functions module descriptor (opens new window).
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module SYSTEM "module.dtd">
<module>
...
<components>
<id>main</id>
<component>
<type>com.ryanbrookepayne.magnolia.templating.functions.HelloWorldTemplatingFunctions</type>
<implementation>com.ryanbrookepayne.magnolia.templating.functions.HelloWorldTemplatingFunctions</implementation>
<scope>singleton</scope>
</component>
</components>
...
</module>
# Installing the Renderer
First, add the magnolia-rendering
dependency to the main pom.xml file:
<dependencies>
...
<dependency>
<groupId>info.magnolia</groupId>
<artifactId>magnolia-rendering</artifactId>
</dependency>
...
</dependencies>
Next, add the required renderer tasks to the MagnoliaTemplatingFunctionModuleVersionHandler
class:
package com.ryanbrookepayne.magnolia.setup;
import ...
public class MagnoliaTemplatingFunctionsModuleVersionHandler extends DefaultModuleVersionHandler {
@Override
protected List<Task> getStartupTasks(InstallContext installContext) {
List<Task> tasks = new ArrayList<>();
tasks.add(
new InstallRendererContextAttributeTask(
"rendering",
"freemarker",
HelloWorldTemplatingFunctions.FUNCTION_NAME,
HelloWorldTemplatingFunctions.class.getName()));
tasks.add(
new InstallRendererContextAttributeTask(
"site",
"site",
HelloWorldTemplatingFunctions.FUNCTION_NAME,
HelloWorldTemplatingFunctions.class.getName()));
return tasks;
}
}
❗️ IMPORTANT: The official documentation example (opens new window) uses the getExtraInstallTasks
method to install the renderer context attributes. However, this method DOES NOT install the attributes. Use the getStartupTasks
method instead.
# Step 5—Using the Functions
In the dummy-component.ftl
template script, implement the templating functions:
${hellofn.sayHello()}
${hellofn.sayHello(2)}
Follow the Magnolia instructions (opens new window) to install your module then start up Magnolia. Create a page and use the "dummy-component". Your page should look like:
Feedback
Thanks to the following folks for providing feedback on this guide: