Using Freemarker in your theme templates
Freemarker is a template language very similar to Velocity. Starting from Liferay 6.0 Liferay supports also Freemarker templates in themes and Web Content templates. In this post I will show how you can use Freemarker in your themes.
Getting started
To get started you’ll need Liferay Portal 6.0 GA3 as well as corresponding Plugins SDK. Once you have setup your Portal and Plugins SDK we can start by creating a new theme plugin in PLUGINS_SDK_ROOT/themes folder.
To create the theme issue following command:
./create.[sh|bat] my-freemarker "My Freemarker"
Then go to my-freemarker-theme directory and open build.xml in your favorite editor.
In build.xml add theme.type property with value ftl above theme.parent property like this:
<property name="theme.type" value="ftl"></property> <property name="theme.parent" value="_styled"></property>
Then you need to create docroot/WEB-INF/liferay-look-and-feel.xml with following contents:
<?xml version="1.0"?> <!DOCTYPE look-and-feel PUBLIC "-//Liferay//DTD Look and Feel 6.0.0//EN" "http://www.liferay.com/dtd/liferay-look-and-feel_6_0_0.dtd"> <look-and-feel> <compatibility> <version>6.0.0+</version> </compatibility> <theme id="my-freemarker-theme" name="My Freemarker"> <template-extension>ftl</template-extension> </theme> </look-and-feel>
Now you run:
ant deploy
Congratulations you’ve just made your first Freemarker based theme. Now you can override base theme files in docroot/_diffs folder just as you would normally except template files now have extension .ftl instead of .vm.
Freemarker syntax
Freemarker syntax is slightly different from Velocity and it is much more strict. With Freemarker you won’t be able to get a way with trying to use undefined variables and you should also note that null value means it’s undefined. To test if value exists you can use double question mark after the variable name like this:
<#if someVariableName??> Variable exists </#if>
For full syntax reference check out Freemarker website.
Pre-defined theme variables
Most of the variables present for Velocity templates are also available for Freemarker templates. Only Velocity specific tools were removed you can accomplish everything and more with Freemarker build-ins. Here’s some examples how to format a java.util.Date type variable with Freemarker build-ins:
${lastUpdated?string("yyyy-MM-dd HH:mm:ss zzzz")} ${lastUpdated?string("EEE, MMM d, ''yy")} ${lastUpdated?string("EEEE, MMMM dd, yyyy, hh:mm:ss a '('zzz')'")}
You can find all the variables available for Freemarker templates from com.liferay.portal.freemarker.FreeMarkerVariables class and docroot/html/themes/_unstyled/init.ftl
Macro libraries
Most of the macros available to Velocity templates are also available for Freemarker templates. The only difference is the syntax how they are used. We provide a macro library with namespace liferay so that it won’t get mixed with your own macros. You can take a look at portal-impl/src/FTL_liferay.ftl to see full list of macros and use it as an example to build your own macros. Here are some commonly used macros:
<@liferay.css file_name=“some.css” /> <@liferay.js file_name=“some.js” /> <@liferay.language key=“my-key” /> <@liferay.breadcrumb /> <@liferay.docbar />
Tag libraries
Yes, you read it correctly. You can use taglibs in your Freemarker templates. This is something unique to Freemarker and it is limited to only templates in themes. To import a portal taglib to your template just add following line to your template:
<#assign aui=PortalJspTagLibs["/WEB-INF/tld/liferay-aui.tld"]>
Now you can use any tag within that taglib just if it was a macro library. Here’s an example how to add a Alloy UI input field:
<@aui.input name=“aStringLiteral” label=“Test” />
Have fun trying this out and if you find any glitches do report them to our issue tracker.