Templating engine
separation between view logic and rendered view
merge data (dynamic) into template (static), to create final document
dynamic data are usually pased via model
in Collection
iterations, conditions, macros, includes, locale
Apache Velocity http://velocity.apache.org/
+
general purpose, industry standard, powerful, support in IDEs
+
support from Spring
-
ugly syntax, too complex
FreeMarker http://www.freemarker.org/index.html
+
general purpose, support in IDEs, easy to use
+
support from Spring
StringTemplate http://www.stringtemplate.org/
+
general purpose, lightweight, fast, easy to use
-
single-person project, no support in IDEs
MVEL2, Thymeleaf, SiteMesh, TeaServlet, Jamon, WebMacro
Replaces JSP in MVC, even more separate view.
Support for JSP taglibs, support for namespaces.
Predefined and user macros, with params support.
Internationalization. (Disable by ?c
)
Expresssions with strings, arithmetic, boolean arithmetic, arrays, user defined.
Output transformation (eg. escaping HTML)
${user}
${user!"Anonymous"} - default value
${cargo.weight!(item.weight * itemCount + 10)}
<#if user??> ${user} is defined </#if>
${user.weight / 2 + 100}
<#include "/layout//footer.ftl">
// search for footer_en_US.ftl, footer_en.ftl, footer.ftl
<#if someBoolean>It was right</#if>
<#if user == "Strajk">Welcome back, admin!</#if>
<#if offer.icecream.price == 0>Free ice-cream!</#if>
<#list animals as being>${being.name} ${being.type}</#list>
<#macro greet person="Anonymous" where>
<h1>Hello ${person}, welcome to ${where}!</h1>
</#macro>
<@greet person="Fred"/>
<#macro wrapper>
<div class="wrapper">
<#nested>
</div>
</#macro>
<@border>Gift to be wrapped</@border>
freemarker-2.3.19.jar
org.springframework.web.servlet.view.freemarker
<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<property name="templateLoaderPath" value="/WEB-INF/views/"/>
</bean>
<bean id="freeMarkerViewResolver"
class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
<property name="cache" value="true"/>
<property name="prefix" value=""/> <!-- Set in freemarkerConfig -->
<property name="suffix" value=".ftl"/>
<property name="exposeSpringMacroHelpers" value="true"/>
</bean>
<#include "/layout/head.ftl">
<#include "/layout/navigation.ftl">
… content ...
<#include "/layout/debug.ftl">
<#include "/layout/footer.ftl">
<#include "/layout/foot.ftl">
/views/account
/views/account/_side.ftl
/views/account/card.ftl
/views/account/cards.ftl
/views/account/default.ftl
/views/account/forbidden.ftl
/views/account/groups.ftl
/views/account/upload.ftl
/views/browse
/views/browse/card.ftl
/views/browse/default.ftl
/views/browse/manage.ftl
/views/homepage
/views/homepage/default.ftl
/views/homepage/misplaced.ftl
/views/layout
/views/layout/debug.ftl
/views/layout/foot.ftl
/views/layout/footer.ftl
/views/layout/head.ftl
/views/layout/navigation.ftl