FreeMarker 设计指南 - 3
2007-12-03 13:28
381 查看
3、模板
(1)整体结构
l模板使用FTL(FreeMarker模板语言)编写,是下面各部分的一个组合:
Ø文本:直接输出
ØInterpolation:由${和},或#{和}来限定,计算值替代输出
ØFTL标记:FreeMarker指令,和HTML标记类似,名字前加#予以区分,不会输出
Ø注释:由<#--和-->限定,不会输出
l下面是以一个具体模板例子:
l[BR]是用于换行的特殊字符序列
l注意事项:
ØFTL区分大小写,所以list是正确的FTL指令,而List不是;${name}和${NAME}是不同的
ØInterpolation只能在文本中使用
ØFTL标记不能位于另一个FTL标记内部,例如:
Ø注释可以位于FTL标记和Interpolation内部,如下面的例子:
Ø多余的空白字符会在模板输出时移除
(2)指令
l在FreeMarker中,使用FTL标记引用指令
l有三种FTL标记,这和HTML标记是类似的:
Ø开始标记:<#directivenameparameters>
Ø结束标记:</#directivename>
Ø空内容指令标记:<#directivenameparameters/>
l有两种类型的指令:预定义指令和用户定义指令
l用户定义指令要使用@替换#,如<@mydirective>...</@mydirective>(会在后面讲述)
lFTL标记不能够交叉,而应该正确的嵌套,如下面的代码是错误的:
l如果使用不存在的指令,FreeMarker不会使用模板输出,而是产生一个错误消息
lFreeMarker会忽略FTL标记中的空白字符,如下面的例子:
l但是,<、</和指令之间不允许有空白字符
(3)表达式
l直接指定值
Ø字符串
n使用单引号或双引号限定
n如果包含特殊字符需要转义,如下面的例子:
输出结果是:
n下面是支持的转义序列:
n有一类特殊的字符串称为raw字符串,被认为是纯文本,其中的/和{等不具有特殊含义,该类字符串在引号前面加r,下面是一个例子:
输出的结果是:
Ø数字
n直接输入,不需要引号
n精度数字使用“.”分隔,不能使用分组符号
n目前版本不支持科学计数法,所以“1E3”是错误的
n不能省略小数点前面的0,所以“.5”是错误的
n数字8、+8、08和8.00都是相同的
Ø布尔值
ntrue和false,不使用引号
Ø序列
n由逗号分隔的子变量列表,由方括号限定,下面是一个例子:
输出的结果是:
n列表的项目是表达式,所以可以有下面的例子:
n可以使用数字范围定义数字序列,例如2..5等同于[2,3,4,5],但是更有效率,注意数字范围没有方括号
n可以定义反递增的数字范围,如5..2
Ø散列(hash)
n由逗号分隔的键/值列表,由大括号限定,键和值之间用冒号分隔,下面是一个例子:
n键和值都是表达式,但是键必须是字符串
l获取变量
Ø顶层变量:${variable},变量名只能是字母、数字、下划线、$、@和#的组合,且不能以数字开头
Ø从散列中获取数据
n可以使用点语法或方括号语法,假设有下面的数据模型:
下面都是等价的:
n使用点语法,变量名字有顶层变量一样的限制,但方括号语法没有该限制,因为名字是任意表达式的结果
Ø从序列获得数据:和散列的方括号语法语法一样,只是方括号中的表达式值必须是数字;注意:第一个项目的索引是0
Ø序列片断:使用[startIndex..endIndex]语法,从序列中获得序列片断(也是序列);startIndex和endIndex是结果为数字的表达式
Ø特殊变量:FreeMarker内定义变量,使用.variablename语法访问
l字符串操作
ØInterpolation(或连接操作)
n可以使用${..}(或#{..})在文本部分插入表达式的值,例如:
n可以使用+操作符获得同样的结果
n${..}只能用于文本部分,下面的代码是错误的:
应该写成:
Ø子串
n例子(假设user的值为“BigJoe”):
结果是(注意第一个字符的索引是0):
l序列操作
Ø连接操作:和字符串一样,使用+,下面是一个例子:
输出结果是:
l散列操作
Ø连接操作:和字符串一样,使用+,如果具有相同的key,右边的值替代左边的值,例如:
输出结果是:
l算术运算
Ø+、-、×、/、%,下面是一个例子:
输出结果是(假设x为5):
Ø操作符两边必须是数字,因此下面的代码是错误的:
Ø使用+操作符时,如果一边是数字,一边是字符串,就会自动将数字转换为字符串,例如:
输出结果是:
Ø使用内建的int(后面讲述)获得整数部分,例如:
输出结果是(假设x为5):
l比较操作符
Ø使用=(或==,完全相等)测试两个值是否相等,使用!=测试两个值是否不相等
Ø=和!=两边必须是相同类型的值,否则会产生错误,例如<#if1="1">会引起错误
ØFreemarker是精确比较,所以对"x"、"x"和"X"是不相等的
Ø对数字和日期可以使用<、<=、>和>=,但不能用于字符串
Ø由于Freemarker会将>解释成FTL标记的结束字符,所以对于>和>=可以使用括号来避免这种情况,例如<#if(x>y)>
Ø另一种替代的方法是,使用lt、lte、gt和gte来替代<、<=、>和>=
l逻辑操作符
Ø&&(and)、||(or)、!(not),只能用于布尔值,否则会产生错误
Ø例子:
l内建函数
Ø内建函数的用法类似访问散列的子变量,只是使用“?”替代“.”,下面列出常用的一些函数
Ø字符串使用的:
nhtml:对字符串进行HTML编码
ncap_first:使字符串第一个字母大写
nlower_case:将字符串转换成小写
nupper_case:将字符串转换成大写
ntrim:去掉字符串前后的空白字符
Ø序列使用的:
nsize:获得序列中元素的数目
Ø数字使用的:
nint:取得数字的整数部分(如-1.9?int的结果是-1)
Ø例子(假设test保存字符串"Tom&Jerry"):
输出结果是:
l操作符优先顺序
(4)Interpolation
lInterpolation有两种类型:
Ø通用Interpolation:${expr}
Ø数字Interpolation:#{expr}或#{expr;format}
l注意:Interpolation只能用于文本部分
l通用Interpolation
Ø插入字符串值:直接输出表达式结果
Ø插入数字值:根据缺省格式(由#setting指令设置)将表达式结果转换成文本输出;可以使用内建函数string格式化单个Interpolation,下面是一个例子:
输出结果是:
Ø插入日期值:根据缺省格式(由#setting指令设置)将表达式结果转换成文本输出;可以使用内建函数string格式化单个Interpolation,下面是一个使用格式模式的例子:
输出的结果类似下面的格式:
Ø插入布尔值:根据缺省格式(由#setting指令设置)将表达式结果转换成文本输出;可以使用内建函数string格式化单个Interpolation,下面是一个例子:
输出结果是:
l数字Interpolation的#{expr;format}形式可以用来格式化数字,format可以是:
ØmX:小数部分最小X位
ØMX:小数部分最大X位
Ø例子:
(1)整体结构
l模板使用FTL(FreeMarker模板语言)编写,是下面各部分的一个组合:
Ø文本:直接输出
ØInterpolation:由${和},或#{和}来限定,计算值替代输出
ØFTL标记:FreeMarker指令,和HTML标记类似,名字前加#予以区分,不会输出
Ø注释:由<#--和-->限定,不会输出
l下面是以一个具体模板例子:
<html>[BR]
<head>[BR]
<title>Welcome!</title>[BR]
</head>[BR]
<body>[BR]
<#--Greettheuserwithhis/hername-->[BR]
<h1>Welcome${user}!</h1>[BR]
<p>Wehavetheseanimals:[BR]
<ul>[BR]
<#listanimalsasbeing>[BR]
<li>${being.name}for${being.price}Euros[BR]
</#list>[BR]
</ul>[BR]
</body>[BR]
</html>
l[BR]是用于换行的特殊字符序列
l注意事项:
ØFTL区分大小写,所以list是正确的FTL指令,而List不是;${name}和${NAME}是不同的
ØInterpolation只能在文本中使用
ØFTL标记不能位于另一个FTL标记内部,例如:
<#if<#include'foo'>='bar'>...</if>
Ø注释可以位于FTL标记和Interpolation内部,如下面的例子:
<h1>Welcome${user<#--Thenameofuser-->}!</h1>[BR]
<p>Wehavetheseanimals:[BR]
<ul>[BR]
<#list<#--somecomment...-->animalsas<#--again...-->being>[BR]
...
Ø多余的空白字符会在模板输出时移除
(2)指令
l在FreeMarker中,使用FTL标记引用指令
l有三种FTL标记,这和HTML标记是类似的:
Ø开始标记:<#directivenameparameters>
Ø结束标记:</#directivename>
Ø空内容指令标记:<#directivenameparameters/>
l有两种类型的指令:预定义指令和用户定义指令
l用户定义指令要使用@替换#,如<@mydirective>...</@mydirective>(会在后面讲述)
lFTL标记不能够交叉,而应该正确的嵌套,如下面的代码是错误的:
<ul>
<#listanimalsasbeing>
<li>${being.name}for${being.price}Euros
<#ifuse="BigJoe">
(exceptforyou)
</#list>
</#if><#--WRONG!-->
</ul>
l如果使用不存在的指令,FreeMarker不会使用模板输出,而是产生一个错误消息
lFreeMarker会忽略FTL标记中的空白字符,如下面的例子:
<#list[BR]
animalsas[BR]
being[BR]
>[BR]
${being.name}for${being.price}Euros[BR]
</#list>
l但是,<、</和指令之间不允许有空白字符
(3)表达式
l直接指定值
Ø字符串
n使用单引号或双引号限定
n如果包含特殊字符需要转义,如下面的例子:
${"It's/"quoted/"and
thisisabackslash://"}
${'It/'s"quoted"and
thisisabackslash://'}
输出结果是:
It's"quoted"and
thisisabackslash:/
It's"quoted"and
thisisabackslash:/
n下面是支持的转义序列:
转义序列 | 含义 |
/" | 双引号(u0022) |
/' | 单引号(u0027) |
// | 反斜杠(u005C) |
/n | 换行(u000A) |
/r | Return(u000D) |
/t | Tab(u0009) |
/b | Backspace(u0008) |
/f | Formfeed(u000C) |
/l | < |
/g | > |
/a | & |
/{ | { |
/xCode | 4位16进制Unicode代码 |
${r"${foo}"}
${r"C:/foo/bar"}
输出的结果是:
${foo}
C:/foo/bar
Ø数字
n直接输入,不需要引号
n精度数字使用“.”分隔,不能使用分组符号
n目前版本不支持科学计数法,所以“1E3”是错误的
n不能省略小数点前面的0,所以“.5”是错误的
n数字8、+8、08和8.00都是相同的
Ø布尔值
ntrue和false,不使用引号
Ø序列
n由逗号分隔的子变量列表,由方括号限定,下面是一个例子:
<#list["winter","spring","summer","autumn"]asx>
${x}
</#list>
输出的结果是:
winter
spring
summer
autumn
n列表的项目是表达式,所以可以有下面的例子:
[2+2,[1,2,3,4],"whatnot"]
n可以使用数字范围定义数字序列,例如2..5等同于[2,3,4,5],但是更有效率,注意数字范围没有方括号
n可以定义反递增的数字范围,如5..2
Ø散列(hash)
n由逗号分隔的键/值列表,由大括号限定,键和值之间用冒号分隔,下面是一个例子:
{"name":"greenmouse","price":150}
n键和值都是表达式,但是键必须是字符串
l获取变量
Ø顶层变量:${variable},变量名只能是字母、数字、下划线、$、@和#的组合,且不能以数字开头
Ø从散列中获取数据
n可以使用点语法或方括号语法,假设有下面的数据模型:
(root)
|
+-book
||
|+-title="Breedinggreenmouses"
||
|+-author
||
|+-name="JuliaSmith"
||
|+-info="Biologist,1923-1985,Canada"
|
+-test="title"
下面都是等价的:
book.author.name
book["author"].name
book.author.["name"]
book["author"]["name"]
n使用点语法,变量名字有顶层变量一样的限制,但方括号语法没有该限制,因为名字是任意表达式的结果
Ø从序列获得数据:和散列的方括号语法语法一样,只是方括号中的表达式值必须是数字;注意:第一个项目的索引是0
Ø序列片断:使用[startIndex..endIndex]语法,从序列中获得序列片断(也是序列);startIndex和endIndex是结果为数字的表达式
Ø特殊变量:FreeMarker内定义变量,使用.variablename语法访问
l字符串操作
ØInterpolation(或连接操作)
n可以使用${..}(或#{..})在文本部分插入表达式的值,例如:
${"Hello${user}!"}
${"${user}${user}${user}${user}"}
n可以使用+操作符获得同样的结果
${"Hello"+user+"!"}
${user+user+user+user}
n${..}只能用于文本部分,下面的代码是错误的:
<#if${isBig}>Wow!</#if>
<#if"${isBig}">Wow!</#if>
应该写成:
<#ifisBig>Wow!</#if>
Ø子串
n例子(假设user的值为“BigJoe”):
${user[0]}${user[4]}
${user[1..4]}
结果是(注意第一个字符的索引是0):
BJ
igJ
l序列操作
Ø连接操作:和字符串一样,使用+,下面是一个例子:
<#list["Joe","Fred"]+["Julia","Kate"]asuser>
-${user}
</#list>
输出结果是:
-Joe
-Fred
-Julia
-Kate
l散列操作
Ø连接操作:和字符串一样,使用+,如果具有相同的key,右边的值替代左边的值,例如:
<#assignages={"Joe":23,"Fred":25}+{"Joe":30,"Julia":18}>
-Joeis${ages.Joe}
-Fredis${ages.Fred}
-Juliais${ages.Julia}
输出结果是:
-Joeis30
-Fredis25
-Juliais18
l算术运算
Ø+、-、×、/、%,下面是一个例子:
${x*x-100}
${x/2}
${12%10}
输出结果是(假设x为5):
-75
2.5
2
Ø操作符两边必须是数字,因此下面的代码是错误的:
${3*"5"}<#--WRONG!-->
Ø使用+操作符时,如果一边是数字,一边是字符串,就会自动将数字转换为字符串,例如:
${3+"5"}
输出结果是:
35
Ø使用内建的int(后面讲述)获得整数部分,例如:
${(x/2)?int}
${1.1?int}
${1.999?int}
${-1.1?int}
${-1.999?int}
输出结果是(假设x为5):
2
1
1
-1
-1
l比较操作符
Ø使用=(或==,完全相等)测试两个值是否相等,使用!=测试两个值是否不相等
Ø=和!=两边必须是相同类型的值,否则会产生错误,例如<#if1="1">会引起错误
ØFreemarker是精确比较,所以对"x"、"x"和"X"是不相等的
Ø对数字和日期可以使用<、<=、>和>=,但不能用于字符串
Ø由于Freemarker会将>解释成FTL标记的结束字符,所以对于>和>=可以使用括号来避免这种情况,例如<#if(x>y)>
Ø另一种替代的方法是,使用lt、lte、gt和gte来替代<、<=、>和>=
l逻辑操作符
Ø&&(and)、||(or)、!(not),只能用于布尔值,否则会产生错误
Ø例子:
<#ifx<12&&color="green">
Wehavelessthan12things,andtheyaregreen.
</#if>
<#if!hot><#--herehotmustbeaboolean-->
It'snothot.
</#if>
l内建函数
Ø内建函数的用法类似访问散列的子变量,只是使用“?”替代“.”,下面列出常用的一些函数
Ø字符串使用的:
nhtml:对字符串进行HTML编码
ncap_first:使字符串第一个字母大写
nlower_case:将字符串转换成小写
nupper_case:将字符串转换成大写
ntrim:去掉字符串前后的空白字符
Ø序列使用的:
nsize:获得序列中元素的数目
Ø数字使用的:
nint:取得数字的整数部分(如-1.9?int的结果是-1)
Ø例子(假设test保存字符串"Tom&Jerry"):
${test?html}
${test?upper_case?html}
输出结果是:
Tom&Jerry
TOM&JERRY
l操作符优先顺序
操作符组 | 操作符 |
后缀 | [subvarName][subStringRange].(methodParams) |
一元 | +expr、-expr、! |
内建 | ? |
乘法 | *、/、% |
加法 | +、- |
关系 | <、>、<=、>=(lt、lte、gt、gte) |
相等 | ==(=)、!= |
逻辑and | && |
逻辑or | || |
数字范围 | .. |
lInterpolation有两种类型:
Ø通用Interpolation:${expr}
Ø数字Interpolation:#{expr}或#{expr;format}
l注意:Interpolation只能用于文本部分
l通用Interpolation
Ø插入字符串值:直接输出表达式结果
Ø插入数字值:根据缺省格式(由#setting指令设置)将表达式结果转换成文本输出;可以使用内建函数string格式化单个Interpolation,下面是一个例子:
<#settingnumber_format="currency"/>
<#assignanswer=42/>
${answer}
${answer?string}<#--thesameas${answer}-->
${answer?string.number}
${answer?string.currency}
${answer?string.percent}
输出结果是:
$42.00
$42.00
42
$42.00
4,200%
Ø插入日期值:根据缺省格式(由#setting指令设置)将表达式结果转换成文本输出;可以使用内建函数string格式化单个Interpolation,下面是一个使用格式模式的例子:
${lastUpdated?string("yyyy-MM-ddHH:mm:sszzzz")}
${lastUpdated?string("EEE,MMMd,''yy")}
${lastUpdated?string("EEEE,MMMMdd,yyyy,hh:mm:ssa'('zzz')'")}
输出的结果类似下面的格式:
2003-04-0821:24:44PacificDaylightTime
Tue,Apr8,'03
Tuesday,April08,2003,09:24:44PM(PDT)
Ø插入布尔值:根据缺省格式(由#setting指令设置)将表达式结果转换成文本输出;可以使用内建函数string格式化单个Interpolation,下面是一个例子:
<#assignfoo=true/>
${foo?string("yes","no")}
输出结果是:
yes
l数字Interpolation的#{expr;format}形式可以用来格式化数字,format可以是:
ØmX:小数部分最小X位
ØMX:小数部分最大X位
Ø例子:
<#--IfthelanguageisUSEnglishtheoutputis:-->
<#assignx=2.582/>
<#assigny=4/>
#{x;M2}<#--2.58-->
#{y;M2}<#--4-->
#{x;m1}<#--2.6-->
#{y;m1}<#--4.0-->
#{x;m1M2}<#--2.58-->
#{y;m1M2}<#--4.0-->
相关文章推荐
- FreeMarker设计指南(完整整理)
- FreeMarker设计指南(1)
- FreeMarker设计指南(1)
- FreeMarker设计指南(一)
- FreeMarker设计指南(2)
- FreeMarker设计指南
- FreeMarker设计指南(1)
- FreeMarker设计指南(2)
- FreeMarker设计指南
- FreeMarker设计指南(2)
- FreeMarker 设计指南 - 4
- FreeMarker设计指南(二)
- FreeMarker设计指南(1)
- FreeMarker设计指南(完整整理)
- FreeMarker设计指南(1)
- FreeMarker设计指南(3)
- FreeMarker设计指南 2
- FreeMarker设计指南(完整整理)——转载自http://www.dlog.cn/wojiushicai/diary/11765
- FreeMarker设计指南(3)
- FreeMarker 设计指南 - 1