Java模板引擎Freemarker
参考自:http://freemarker.foofun.cn/
http://www.imooc.com/learn/801
FreeMarker 是一款 模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页,电子邮件,配置文件,源代码等)的通用工具。
模板编写的语言为FreeMarker Template Language (FTL)。它是简单的,专用的语言, 不是 像PHP那样成熟的编程语言。
模板(FTL编程)是由如下部分混合而成的:
- 文本:文本会照着原样来输出。
- 插值:这部分的输出会被计算的值来替换。插值由 ${ and } 所分隔(或者 #{ and },这种风格已经不建议再使用了;点击查看更多)。
- FTL 标签:FTL标签和HTML标签很相似,但是它们却是给FreeMarker的指示, 而且不会打印在输出内容中。
- 注释:注释和HTML的注释也很相似,但它们是由 <#– 和 –>来分隔的。注释会被FreeMarker直接忽略, 更不会在输出内容中显示。
基本操作
- 基本类型
<div class="demo-dev">
<ul>
<!-- 变量赋值 -->
<#assign a = 100/>
<!-- 取值 -->
a = <font color="red">${a}</font>
<!-- 运算-->
a + 100 = <font color="red">${a + 100}</font>
</ul>
</div>
- 封装类型
<!-- 取值 -->
name:<font color="red">${user.name}</font>
<!-- 防止当user对象,name属性为空或不存在时报错-->
name:<font color="red">${user.name!}</font>
<!-- 防止user不存在时报错 -->
#"游客":为空时设置默认值
name:<font color="red">${(user.name)!"游客"}</font>
-
集合
- List,Set:
<#list myList as item> <font color="red">${item!}</font><br/> </#list>
- Map
<#list myMap?keys as key> <font color="red">${key}:${myMap[key]}</font><br/> </#list>
流程控制
-
if-else
<#assign var = 99/> <#if var == 99> <font color="red">var为99</font> <#elseif var > 99> <font color="red">var大于99</font> <#else> <font color="red">var小于99</font> <#if>
判断是否存在
<#if myList??>或<#if myList?exists> # some code </#if>
多条件(||,&&,!)
-
switch
<!-- 也支持字符串 "java"--> <#assign var = 11> <#switch var> <#case 10> <#case 11> 10 or 11<br/> <#break> <#case 100> 100<br/> <#default> other </#switch>
内建函数
即freemaker内部创建好了的函数,通常格式为var?函数名()
,可链式,即继续添加?函数名()
,以下部分举例,具体可查看http://freemarker.foofun.cn/ref_builtins.html
-
String内建函数举例:
<#assign a = "hello"/> <#assign b = "world"/> <li>连接</li> <font color="red">${a + b}</font><br/> <li>截取</li> <font color="red">${(a + b)?substring(5,8)}</font><br/> <li>长度</li> <font color="red">${(a + b)?length}</font><br/> <li>大写</li> <font color="red">${(a + b)?upper_case}</font><br/> <li>小写</li> <font color="red">${(a + b)?lower_case}</font><br/> <li>index of</li> <font color="red">${(a + b)?index_of('w')}</font><br/> <li>last_index_of</li> <font color="red">${(a + b)?last_index_of('o')}</font><br/> <li>replace</li> <font color="red">${(a + b)?replace('o','xx')}</font><br/>
-
List内建函数
<#assign myList=[2,3,4,5,7,6,8,1]/> <#list myList?sort as item> ${item_index} : ${item}<br/> </#list>
-
自定义函数(以实现sort排序为例)
view层:
<#list sort_int(myList) as item> ${item} </#list>
controller层:
ModelAndView mv = new ModelAndView("/index"); mv.addObject("sort_int",new SortMethod()); return mv;
SortMethod类,实现TemplateMethodModelEx类:
public class SortMethod implements TemplateMethodModelEx{ @Override public Object exec(List arguments) throws TemplateModelException{ //获取第一个参数,必须转换为freemaker的数据类型 SimpleSequence arg0 = (SimpleSequence)arguments.get(0); List<BigDecimal> list = arg0.toList(); Collections.sort(list,new Comparator<BigDecimal>(){ @Override public int compare(BigDecimal o1,Big Decimal o2){ return o1.intValue() - o2.intValue();//升序 } }); return list; } }
宏和循环变量
-
宏(macro):
宏是有一个变量名的模板片段。可以在模板中使用宏作为自定义指令, 这样就能进行重复性的工作。
定义一个宏:
<#macro greet> <font size="+2">Hello Joe!</font> </#macro>
macro 指令自身不输出任何内容, 它只是用来创建宏变量,所以就会有一个名为 greet 的变量。在
<#macro greet>
和</#macro>
之间的内容 (称为 宏定义体) 将会在使用该变量作为指令时执行。调用宏:
//或 <@greet/> <@greet></@greet>
输出:
<font size="+2">Hello Joe!</font>
参数:前面宏的内容是固定的,要想实现可变输出,就需要使用参数,同时,可以有多个参数,并能设默认值
//两个参数,color默认值为black <#macro greet person color="black"> <font size="+2" color="${color}">Hello ${person}!</font> </#macro>
使用宏:
<@greet person="Fred"/> <!-- 覆盖默认值 --> <@greet person="Fred" color="red"/>
嵌套内容
在定义宏时,在宏定义体中添加<#nested>
<#macro border>
<table border=4 cellspacing=0 cellpadding=4><tr><td>
<#nested>
</tr></td></table>
</#macro>
调用宏时:
<@border>The bordered text</@border>
将会输出:
<table border=4 cellspacing=0 cellpadding=4><tr><td>
The bordered text
</td></tr></table>
nested 指令也可以多次被调用,例如:
<#macro do_thrice>
<#nested>
<#nested>
<#nested>
</#macro>
<@do_thrice>
Anything.
</@do_thrice>
将会输出:
Anything.
Anything.
Anything.
如果不使用 nested 指令, 那么嵌套的内容就不会被执行,如果不小心将 greet 指令写成了这样:
<@greet person="Joe">
Anything.
</@greet>
FreeMarker 不会把它视为错误,只是输出:
<font size="+2">Hello Joe!</font>
嵌套的内容被忽略了,因为 greet 宏没有使用 nested 指令。