Working with Maps in FreeMarker Templates
FreeMarker supports variables of type hash, which are
unordered mappings of strings to other models, and provide
the built-in ?keys
and ?values
to expose the key and value sets
as sequences. In order to support maps with key types other
than strings, the CAE FreeMarker view engine does not map Java objects of type
java.util.Map
to FreeMarker hashes. Instead,
java.util.Map
methods will be available on such models. In order to access the
entry, key, or value sets, call the respective methods on the model object. Any such set is a
FreeMarker sequence and thus compatible with the
#list
directive.
<#list map.entrySet() as entry> ${entry.key} is mapped to ${entry.value} </#list>
Example 4.8. Iterating over java.util.Map entries in FreeMarker templates
Using JSP Tag Libraries in FreeMarker Templates
FreeMarker templates can access functionality provided by a JSP tag library, assuming that the
tag library is deployed in the web application as specified in JavaServer Pages 2.2 and up. Import
the tags exposed by a JSP tag library into a named hash by using its URI as a key into the
implicit JspTaglibs
map. The imported tags will be available as custom directives
in the named hash.
<#assign fmt=JspTaglibs["http://java.sun.com/jsp/jstl/fmt"]> <@fmt.formatNumber value=self.someValue/>
JspTaglibs
only exposes tags, not static methods exposed by a JSP tag library as
functions.
Accessing Static Methods in Freemarker Templates
To give a FreeMarker template access to public static methods of a Java class, you have to implement a "facade" Java singleton that provides non-static methods that delegate to the static methods.
public final class FreemarkerFacaceExample { public static final FreemarkerFacaceExample INSTANCE = new FreemarkerFacaceExample(); private FreemarkerFacaceExample() { } /** * Provides non-static access to static method. */ public String nonStaticDefaultString(String text) { return StringUtils.defaultString(text); } }
Then, add this singleton as a shared variable to the CAE's FreeMarker configuration, and access the methods using the singleton in any CAE FreeMarker template.
The following listing shows an example Spring configuration to add a custom shared FreeMarker
variable, assuming the facade singleton class is called com.company.cae.MyFreemarkerFacade
and the variable should be exposed as myFreemarkerFacade
.
<import resource="classpath:/com/coremedia/cae/view-freemarker-services.xml"/> <customize:append id="myFreemarkerSharedVariablesCustomizer" bean="freemarkerSharedVariables"> <map> <entry key="myFreemarkerFacade"> <bean class="com.company.cae.MyFreemarkerFacade"> <!-- inject services etc. here! --> </bean> </entry> </map> </customize:append>
Auto-Import of Freemarker Functions and Macros
In order to expose functions, macros, or common configuration to all templates,
you need to add the corresponding Freemarker file to the freemarkerConfigurer
bean's property
autoImports
. The following listing shows an example Spring configuration that exposes
all functions of custom-functions.ftl
with the name cufu
.
<import resource="classpath:/com/coremedia/cae/view-freemarker-services.xml"/> <customize:append id="myFreemarkerAutoImportsCustomizer" bean="freemarkerConfigurer" property="autoImports"> <map> <entry key="cufu" value="/lib/custom/freemarker/custom-functions.ftl"/> </map> </customize:append>
All functions are now available to your Freemarker templates. However, the IDE will most likely not
recognize these functions and the name defined in your Spring configuration. Adding a
freemarker_implict.ftl
as shown in Example 4.9, “Code for Idea auto-completion” to
src/main/resources/META-INF/resources/
within your Maven module's directory will add
auto-completion to the IntelliJ IDEA development environment.
[#ftl] [#-- @implicitly included --] [#import "/lib/custom/freemarker/custom-functions.ftl" as cufu]
Example 4.9. Code for Idea auto-completion