You are on page 1of 17

Freemarker

General Templating language


Many built-in functions for String, number,
boolean handling
Support for Expressions, Conditionals, Loops
and Macros
Doesn't allow direct code execution (aka java
snippets in JSP)
Enforces explicit null handling

Freemarker- why in Magnolia

template overloading While the default template is delivered in that


module's jar a customer can overload the default template by copying the file
into the webapp templates folder. Since the template contains no logic all the
logic of the paragraph is reused.
in repository templates Freemarker templates can be stored where ever
you want and therefore in the repository too. This allows just in time
template editing, activation of templates (css changes, ...). In addition this
templates can be versioned together with the content.
code separation The separation of business logic and rendering templates
is enforced and guaranteed
customization All delivered paragraphs can be customized by either
subclassing the paragraph bean, by reconfiguring the paragraph or by
overloading the template.
compiled The templates are independent of the container and don't need to
be expl. compiled by javac/jspc yet are still made into java objects at runtime

Freemarker- why in Magnolia

independent of servlet API JSP's are very much dependent on servlet API
while Magnolia template rendering is not. This is because Magnolia uses a
neutral context. By using Freemarker the rendering is independent of the
servlet container and can be executed isolated. This facilitates testing allows
nice things as diffs or request independent reaching of content.

templates are in the module's jar Currently all jsps must be extracted from
the module jar and copied to the webapp folder. This can be an obstacle as
the deployed webapp should normally not be changed on runtime (war
deployment). It is also cumbersome during the development process in
which one must copy the templates from the module resources to the
webapp (and back again).
security no critical code is stored in the file system and could be changed
expression language the expression language is very similar to the one of
freemarker and most of the templates will look very similar

Freemarker The code

Variables use Ant/Maven like notation ${myVar}


Directives are denoted by <# or [# (the latter is
better when writing FM expressions for html
pages since it doesn't confuses validation and
html editors)
Default values defined as ${myVar!unknown}

Freemarker contd.

Built-ins

start_with, end_with

${my head?end_with(day)} ==> false

index_of

${abcabc?index_of(bc)} ==> 1

${abcabc?index_of(bc,2)} ==> 4

js_string

escapes string literals and variations of /><script> in strings


intended as values for generated javascript prevention of XSS
vulnerabilities

And many more, see

http://freemarker.sourceforge.net/docs/ref_builtins_string.html

Freemarker contd.

Built-ins

Substrings ${some string?substring(2,3)}

Capitalization cap_first, uncap_first, capitalize

${word one?cap_first} ==> Word one


${some rEAl MesS?capitalize} ==> Some Real Mess

chop_linebreak removes only linebreak at the end


of string (if any)

Date, time, datetime (conversions are done


according as specified in date_format, ...)

${"10/25/1995"?date("MM/dd/yyyy")} ==> Oct 25, 1995

Freemarker contd.

Conditionals

If, else, elseif, switch/case/default/break


[#if x == 1]
... do something
[#elseif myVar?has_content]
... something else
[#else]
... yet something else
[#/if]

Freemarker contd.

Loops
[#assign seq = ("mon", "tue", "wed", "thu")]
[#list seq as x]
${x_index + 1}. ${x?cap_first}[#if x_has_next],[/#if]
[/#list]
1. Mon,
2. Tue,
3. Wed,
4. Thu

Freemarker contd.

Include
[#include /another/cool/template/for/inclution.ftl]

Can provide encoding for subtemplates if necessary

Path can be relative of absolute

Always use slash in path, never backslash (even on


Windows!)

Acquisition support

If current template is in path /foo/bar, then using


[#include "*/footer.ftl"] results in inclusion of
/foo/bar/footer.ftl, /foo/footer.ftl, /footer.ftl

Freemarker contd.

#compress

Useful for removing extra whitespaces from html

#escape, #noescape
[#escape x as x?html]
First name: ${firstName}
Last name: ${lastName}
Maiden name: ${maidenName}
[/#escape]

First name: ${firstName?html}


Last name: ${lastName?html}
Maiden name: ${maidenName?html}

Freemarker in Magnolia (4.0+)

Default variables

templateDef points to template definition node

def current paragraph definition node

ctx magnolia context

page or actpage current page content. Similar to


<cms:setNode/>

aggregationState aggregationState

i18n resource bundle messages

Freemarker in Magnolia (4.0+)

Default variables

model bean created by FM renderer from


modelClass value defined in paragraph or template

mgnl various utility methods see javadoc for more


http://dev.magnolia-cms.com/ref/4.1/apidocs/index.html?
info/magnolia/module/templating/MagnoliaTemplatingUtilities.html

actionResult result of associated


action.execute() method

content current node (either page or paragraph,


depending on the template). Similar to
<cms:setNode/> in JSP

Freemarker in Magnolia (4.0+)

Freemarker in Magnolia (4.0+)

Template class

simple java bean

extends info.magnolia.cms.beans.config.Template

Template model

extends
info.magnolia.cms.beans.config.RenderingModelImpl

model is a place for all necessary code execution


(what you would normally include as snippets in
JSP)

place to obtain additional resources/info to be


rendered by the template

Freemarker in Magnolia (4.0+)

Includes support for JSP tag libraries for reuse of


tags from previously created templates
[#assign cms=JspTaglibs["cms-taglib"]]
[@cms.contentNodeIterator contentNodeCollectionName="main"]
[@cms.includeTemplate /]
[/@cms.contentNodeIterator]
[@cms.newBar contentNodeCollectionName="main" newLabel="New
Content" paragraph="${templateDef.mainArea.paragraphsAsStringList}" /]

Freemarker in Magnolia (4.0+)

Freemarker in Magnolia (4.0+)

Few examples:
<a href="javascript:alert('$
{i18n['link.document.resolveError']?js_string}')">$
{i18n['link.document.resolveError']}</a>
[#assign teaserLink=model.teaserLink!""]
[#if !hideTeaserImage]
[#assign imageLink=model.imageLink!""]
[/#if]
[#if imageLink?has_content]
[#assign imageAlt=title]
[#else]
[#assign imageAlt="${i18n['image.resolveError']}"]
[/#if]

You might also like