FreeMarker学习笔记(模板部分)

Data Model
FreeMarker的Data Model与JSF的Component Tree概念很类似,就是一个Tree的数据结构;
在模板中的变量访问形式是:${var},而在Velocity中是$var.
几个概念:
hashes:一个节点如果有多个子节点,那么通过 访问,这个节点就是hashes
scalars:叶子节点就是scalars【标量?】
sequences:一个节点如果是容器的话,其child就是一个sequence,与hashes不同的是,是通过数组来访问的,没有主键, for example: root.animals[0].name
Template:
interpolations:${var}
FTL Tag: 类似HTML的标签,不过以#开头,一部分特定的FTL标签还会以@开头;
Comment:评注用<#-- comments --> 而不是
几个FTl TAG(Directives):有两种directives,预定义的指令与用户定义指令,如果是用户定义的指令,用@开头。<@mydirective ...>...
<#if ...>...
<#list vars as var> ${var}
<#include "../somefile.html">
Methods:
FreeMarker中也可以定义方法,可以在页面中直接调用,比如${avg(3,5)},在后台有一个类实现TemplateMethodModel,该类需要有一个exec(List)方法来实现自定义方法的逻辑。当然,这个avg方法也需要通过dataModel.put("avg",AvgMethod)来显式的声明的。
Micro and Transforms: 宏和转换都可以看作是用户自定义的FTL。Transforms定义和Methods类似,需要在后台有一个匹配的实现类,该类实现了TemplateTransformModel接口,该接口中有一个方法getWriter(),返回一个用于转换变形的Writer,一般用内部类来实现。
Micro:
定义宏的方法很简单<#micro micro_name ..> ${param1} 使用宏时用<@micro_name />
#Nested:是被宏包围定义的文本内容,比如<@mymicro>this is a nested content ,宏定义时用<#micro mymicro>#nested
定义变量:
通过#assign指令来定义或改变变量的值,需要注意变量的作用范围,有local, loop等
Namespaces:
在通过<#include "xxx.ftl" as ns>之后,可以用ns.items.item来访问原来定义在xxx.ftl中的变量,这个ns就是一个命名空间。

FreeMarker模板文件并不比HTML页面复杂多少,FreeMarker模板文件主要由如下4个部分组成: 1,文本:直接输出的部分 2,注释:格式部分,不会输出 3,插值:即${...}或#{...}格式的部分,将使用数据模型中的部分替代输出 4,FTL指令:FreeMarker指定,和HTML标记类似,名字前加#予以区分,不会输出 下面是一个FreeMarker模板的例子,包含了以上所说的4个部分 Welcome! Welcome ${user} ! We have these animals: ${being.name} for ${being.price} Euros 1, FTL指令规则 在FreeMarker中,使用FTL标签来使用指令,FreeMarker有3种FTL标签,这和HTML标签是完全类似的. 1,开始标签: 2,结束标签: 3,空标签: 实际上,使用标签时前面的符号#也可能变成@,如果该指令是一个用户指令而不是系统内建指令时,应将#符号改成@符号. 用户指令用@ 使用FTL标签时, 应该有正确的嵌套,而不是交叉使用,这和XML标签的用法完全一样.如果全用不存在的指令,FreeMarker不会使用模板输出,而是产生一个错误消息.FreeMarker会忽略FTL标签中的空白字符.值得注意的是 和指令之间不允许有空白字符. 2, 插值规则 FreeMarker的插值有如下两种类型:1,通用插值${expr};2,数字格式化插值:#{expr}或#{expr;format} 2.1 通用插值 对于通用插值,又可以分为以下4种情况: 1,插值结果为字符串值:直接输出表达式结果 2,插值结果为数字值:根据默认格式(由#setting指令设置)将表达式结果转换成文本输出.可以使用内建的字符串函数格式化单个插值,如下面的例子: ${answer} ${answer?string} ${answer?string.number} ${answer?string.currency} ${answer?string.percent} ${answer} 输出结果是: $42.00 $42.00 42 $42.00 4,200% 3,插值结果为日期值:根据默认格式(由#setting指令设置)将表达式结果转换成文本输出.可以使用内建的字符串函数格式化单个插值,如下面的例子: ${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')'")} 输出结果是: 2008-04-08 08:08:08 Pacific Daylight Time Tue, Apr 8, '03 Tuesday, April 08, 2003, 08:08:08 PM (PDT) 4,插值结果为布尔值:根据默认格式(由#setting指令设置)将表达式结果转换成文本输出.可以使用内建的字符串函数格式化单个插值,如下面的例子: ${foo?string("yes", "no")} 输出结果是: yes 2.2 数字格式化插值 数字格式化插值可采用#{expr;format}形式来格式化数字,其中format可以是: mX:小数部分最小X位 MX:小数部分最大X位 如下面的例子: #{x; M2} #{y; M2} #{x; m1} #{y; m1} #{x; m1M2} #{x; m1M2} 3, 表达式 表达式是FreeMarker模板的核心功能,表达式放置在插值语法${}之中时,表明需要输出表达式的值;表达式语法也可与FreeMarker 标签结合,用于控制输出.实际上FreeMarker的表达式功能非常强大,它不仅支持直接指定值,输出变量值,也支持字符串格式化输出和集合访问等功能. 3.1 直接指定值 使用直接指定值语法让FreeMarker直接输出插值中的值,而不是输出变量值.直接指定值可以是字符串,数值,布尔值,集合和MAP对象. 1,字符串 直接指定字符串值使用单引号或双引号限定,如果字符串值中包含特殊字符需要转义,看下面的例子: ${"我的文件保存在C:\\盘"} ${'我名字是\"annlee\"'} 输出结果是: 我的文件保存在C:\盘 我名字是"annlee" FreeMarker支持如下转义字符: \";双引号(u0022) \';单引号(u0027) \\;反斜杠(u005C) \n;换行(u000A) \r;回车(u000D) \t;Tab(u0009) \b;退格键(u0008) \f;Form feed(u000C) \l; \a;& \{;{ \xCode;直接通过4位的16进制数来指定Unicode码,输出该unicode码对应的字符. 如果某段文本中包含大量的特殊符号,FreeMarker提供了另一种特殊格式:可以在指定字符串内容的引号前增加r标记,在r标记后的文件将会直接输出.看如下代码: ${r"${foo}"} ${r"C:\foo\bar"} 输出结果是: ${foo} C:\foo\bar 2,数值 表达式中的数值直接输出,不需要引号.小数点使用"."分隔,不能使用分组","符号.FreeMarker目前还不支持科学计数法,所以"1E3"是错误的.在FreeMarker表达式中使用数值需要注意以下几点: 1,数值不能省略小数点前面的0,所以".5"是错误的写法 2,数值8 , +8 , 8.00都是相同的 3,布尔值 直接使用true和false,不使用引号. 4,集合 集合以方括号包括,各集合元素之间以英文逗号","分隔,看如下的例子: ${x} 输出结果是: 星期一 星期二 星期三 星期四 星期五 星期六 星期天 除此之外,集合元素也可以是表达式,例子如下: [2 + 2, [1, 2, 3, 4], "whatnot"] 还可以使用数字范围定义数字集合,如2..5等同于[2, 3, 4, 5],但是更有效率.注意,使用数字范围来定义集合时无需使用方括号,数字范围也支持反递增的数字范围,如5..2 5,Map对象 Map对象使用花括号包括,Map中的key-value对之间以英文冒号":"分隔,多组key-value对之间以英文逗号","分隔.下面是一个例子: {"语文":78, "数学":80} Map对象的key和value都是表达式,但是key必须是字符串 3.2 输出变量值 FreeMarker的表达式输出变量时,这些变量可以是顶层变量,也可以是Map对象中的变量,还可以是集合中的变量,并可以使用点(.)语法来访问Java对象的属性.下面分别讨论这些情况 1,顶层变量 所谓顶层变量就是直接放在数据模型中的值,例如有如下数据模型: Map root = new HashMap(); //创建数据模型 root.put("name","annlee"); //name是一个顶层变量 对于顶层变量,直接使用${variableName}来输出变量值,变量名只能是字母,数字,下划线,$,@和#的组合,且不能以数字开头号.为了输出上面的name的值,可以使用如下语法: ${name} 2,输出集合元素 如果需要输出集合元素,则可以根据集合元素的索引来输出集合元素,集合元素的索引以方括号指定.假设有索引: ["星期一","星期二","星期三","星期四","星期五","星期六","星期天"].该索引名为week,如果需要输出星期三,则可以使用如下语法: ${week[2]} //输出第三个集合元素 此外,FreeMarker还支持返回集合的子集合,如果需要返回集合的子集合,则可以使用如下语法: week[3..5] //返回week集合的子集合,子集合中的元素是week集合中的第4-6个元素 3,输出Map元素 这里的Map对象可以是直接HashMap的实例,甚至包括JavaBean实例,对于JavaBean实例而言,我们一样可以把其当成属性为key,属性值为value的Map实例.为了输出Map元素的值,可以使用点语法或方括号语法.假如有下面的数据模型: Map root = new HashMap(); Book book = new Book(); Author author = new Author(); author.setName("annlee"); author.setAddress("gz"); book.setName("struts2"); book.setAuthor(author); root.put("info","struts"); root.put("book", book); 书有作者, 为了访问数据模型中名为struts2的书的作者的名字,可以使用如下语法: book.author.name //全部使用点语法 book["author"].name book.author["name"] //混合使用点语法和方括号语法 book["author"]["name"] //全部使用方括号语法 使用点语法时,变量名字有顶层变量一样的限制,但方括号语法没有该限制,因为名字可以是任意表达式的结果. Map?keys这个map当中所有的key的列表 Map?values这个map当中所有的value的列表 3.3, 字符串操作 FreeMarker的表达式对字符串操作非常灵活,可以将字符串常量和变量连接起来,也可以返回字符串的子串等. 字符串连接有两种语法: 1,使用${..}或#{..}在字符串常量部分插入表达式的值,从而完成字符串连接. 2,直接使用连接运算符+来连接字符串 例如有如下数据模型: Map root = new HashMap(); root.put("user","annlee"); 下面将user变量和常量连接起来: ${"hello, ${user}!"} //使用第一种语法来连接 ${"hello, " + user + "!"} //使用+号来连接 上面的输出字符串都是hello,annlee!,可以看出这两种语法的效果完全一样. 值得注意的是,${..}只能用于文本部分,不能用于表达式,下面的代码是错误的: Wow! Wow! 应该写成:Wow! 截取子串可以根据字符串的索引来进行,截取子串时如果只指定了一个索引值,则用于取得字符串中指定索引所对应的字符;如果指定两个索引值,则返回两个索引中间的字符串子串.假如有如下数据模型: Map root = new HashMap(); root.put("book","struts2,freemarker"); 可以通过如下语法来截取子串: ${book[0]}${book[4]} //结果是su ${book[1..4]} //结果是tru
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值