« Atrás

Using Freemarker in your theme templates

Company Blogs 24 de agosto de 2010 Por Mika Koivisto Staff

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.

Respuestas anidadas Autor Fecha
Cool feature! Thank you, Mika. Jonas Yuan 24 de agosto de 2010 13:50
You have long spoken half of Freemarker over... Sampsa Sohlman 25 de agosto de 2010 11:08
Oh its super Murat ÇOLAK 26 de agosto de 2010 1:41
Hi I'm not being able to find 'liferay-aui.tld'... Amruta Borkar 2 de enero de 2011 22:25
Has support for velocity hooks been removed ? ... Ian White 19 de octubre de 2011 15:02
[...]... Anónimo 2 de abril de 2012 9:13
Hi Mika, I just implemented a theme using... Juan Ramon Paniagua 27 de febrero de 2013 5:32
[...] So there you have it! How you easily can... Anónimo 8 de abril de 2013 7:20
I have a big (for me) issue with including a... Jan Rodan 5 de febrero de 2014 6:06
I have a big (for me) issue with including a... Jan Rodan 5 de febrero de 2014 6:06
<footer id="footer" role="contentinfo"> <div... ekta j 25 de noviembre de 2016 3:05

Cool feature! Thank you, Mika.
Publicado el día 24/08/10 13:50.
You have long spoken half of Freemarker over the Velocity.. now we have it emoticon

Thanks, Mika
Publicado el día 25/08/10 11:08.
Publicado el día 26/08/10 1:41.
Hi I'm not being able to find 'liferay-aui.tld' . Please tell me where can I find it.
Publicado el día 2/01/11 22:25.
Has support for velocity hooks been removed ?

I notice that when using the portal trunk, my bean, which is declared in an applicationContext.xml, is now not being found by the BeanLocator. It was working prior to my svn update.

Is there another way to achieve velocity hook functionality now ?

Thanks

Ian
Publicado el día 19/10/11 15:02 en respuesta a Amruta Borkar.
[...] http://www.liferay.com/web/mika.koivisto/blog/-/blogs/using-freemarker-in-your-t­heme-templates Flag Please sign in to flag this as inappropriate. Mark as an Answer [...] Read More
Publicado el día 2/04/12 9:13.
Hi Mika,

I just implemented a theme using Freemarker as the template engine.
The theme didn't included the staging-portlet-bar and I saw that the implementation of the <@liferay.dockbar/> macro is different than the Velocity implementation.
I solved the issue in my theme by including:
<#if show_staging>${theme.runtime("170")}</#if>
after the call to the macro. I think it would be nice to have that included in the macro to avoid people running into this kind of issues.
Publicado el día 27/02/13 5:32.
[...] So there you have it! How you easily can use Freemarker instead of JSP in your portlet and how to use you own custom template loader for reading Freemarker templates from your source of choice. Now... [...] Read More
Publicado el día 8/04/13 7:20.
I have a big (for me) issue with including a taglib:

<#assign ui=PortalJspTagLibs["/WEB-INF/tld/liferay-ui.tld"]>
<#assign classes= stringUtil.split("com.liferay.portal.model.Group,com.liferay.portal.model.Organi­zation") />
<@ui["my-sites"] classNames="${classes}" cssClass="dropdown-menu my-sites-menu" />

The problem is the classNames value. I do not know how to pass the correct type in there.
Has anybody an idea?
Thanks!
Publicado el día 5/02/14 6:06.
I have a big (for me) issue with including a taglib:

<#assign ui=PortalJspTagLibs["/WEB-INF/tld/liferay-ui.tld"]>
<#assign classes= stringUtil.split("com.liferay.portal.model.Group,com.liferay.portal.model.Organi­zation") />
<@ui["my-sites"] classNames="${classes}" cssClass="dropdown-menu my-sites-menu" />

The problem is the classNames value. I do not know how to pass the correct type in there.
Has anybody an idea?
Thanks!
Publicado el día 5/02/14 6:06.
<footer id="footer" role="contentinfo">
<div class="footer-inner">
##set ($footer-navigation = "FOOTER_NAVIGATION")
##set($footer-navigation=$journalContentUtil.getConten­t($group_id, $footer-navigation,null,"$locale",$theme_display))
##$footer-navigation
­ $!journalContentUtil.getContent($getterUtil.getLong("$!group_id"), $theme.getSetting("FOOTER_NAVIGATION"), null, "$!locale", $theme_display)

#if (!$is_signed_in)
<span class="signin-link">
<a data-redirect="$portalUtil.isLoginRedirectRequired($request)" href="$sign_in_url" id="sign-in" rel="nofollow">$sign_in_text</a>
</span>
#end
</div>
</footer>

Hello Everyone can you convert this code DXP ?
Publicado el día 25/11/16 3:05.