首页 > 开发 > 综合 > 正文

FreeMarker设计指南(3)

2024-07-21 02:14:09
字体:
来源:转载
供稿:网友
freemarker设计指南(3)
3、模板



(1)整体结构



l         模板使用ftl(freemarker模板语言)编写,是下面各部分的一个组合:



ø         文本:直接输出



ø         interpolation:由${和},或#{和}来限定,计算值替代输出



ø         ftl标记:freemarker指令,和html标记类似,名字前加#予以区分,不会输出



ø         注释:由<#--和-->限定,不会输出



l         下面是以一个具体模板例子:



<html>[br]



<head>[br]



  <title>welcome!</title>[br]



</head>[br]



<body>[br]



  <#-- greet the user with his/her name -->[br]



  <h1>welcome ${user}!</h1>[br]



  <p>we have these animals:[br]



  <ul>[br]



  <#list animals as being>[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 <#-- the name of user -->}!</h1>[br]



<p>we have these animals:[br]



<ul>[br]



<#list <#-- some comment... --> animals as <#-- again... --> being>[br]



... 



ø         多余的空白字符会在模板输出时移除



(2)指令



l         在freemarker中,使用ftl标记引用指令



l         有三种ftl标记,这和html标记是类似的:



ø         开始标记:<#directivename parameters>



ø         结束标记:</#directivename>



ø         空内容指令标记:<#directivename parameters/>



l         有两种类型的指令:预定义指令和用户定义指令



l         用户定义指令要使用@替换#,如<@mydirective>...</@mydirective>(会在后面讲述)



l         ftl标记不能够交叉,而应该正确的嵌套,如下面的代码是错误的:



<ul>



<#list animals as being>



  <li>${being.name} for ${being.price} euros



  <#if use = "big joe">



     (except for you)



</#list>



</#if> <#-- wrong! -->



</ul> 



l         如果使用不存在的指令,freemarker不会使用模板输出,而是产生一个错误消息



l         freemarker会忽略ftl标记中的空白字符,如下面的例子:



<#list[br]



  animals       as[br]



     being[br]



>[br]



${being.name} for ${being.price} euros[br]



</#list    > 



l         但是,<、</和指令之间不允许有空白字符



(3)表达式



l         直接指定值



ø         字符串



n         使用单引号或双引号限定



n         如果包含特殊字符需要转义,如下面的例子:



${"it's /"quoted/" and



this is a backslash: //"}



 



${'it/'s "quoted" and



this is a backslash: //'} 



输出结果是:



it's "quoted" and



this is a backslash: /



 



it's "quoted" and



this is a backslash: / 



n         下面是支持的转义序列:



转义序列



含义



/"



双引号(u0022)



/'



单引号(u0027)



//



反斜杠(u005c)



/n



换行(u000a)



/r



return (u000d)



/t



tab (u0009)



/b



backspace (u0008)



/f



form feed (u000c)



/l



<



/g



>



/a



&



/{



{



/xcode



4位16进制unicode代码



n         有一类特殊的字符串称为raw字符串,被认为是纯文本,其中的/和{等不具有特殊含义,该类字符串在引号前面加r,下面是一个例子:



${r"${foo}"}



${r"c:/foo/bar"} 



输出的结果是:



${foo}



c:/foo/bar 



ø         数字



n         直接输入,不需要引号



n         精度数字使用“.”分隔,不能使用分组符号



n         目前版本不支持科学计数法,所以“1e3”是错误的



n         不能省略小数点前面的0,所以“.5”是错误的



n         数字8、+8、08和8.00都是相同的



ø         布尔值



n         true和false,不使用引号



ø         序列



n         由逗号分隔的子变量列表,由方括号限定,下面是一个例子:



<#list ["winter", "spring", "summer", "autumn"] as x>



${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":"green mouse", "price":150}



n         键和值都是表达式,但是键必须是字符串



l         获取变量



ø         顶层变量: ${variable},变量名只能是字母、数字、下划线、$、@和#的组合,且不能以数字开头



ø         从散列中获取数据



n         可以使用点语法或方括号语法,假设有下面的数据模型:



(root)



|



+- book



|   |



|   +- title = "breeding green mouses"



|   |



|   +- author



|       |



|       +- name = "julia smith"



|       |



|       +- 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>



应该写成:



<#if isbig>wow!</#if>



ø         子串



n         例子(假设user的值为“big joe”):



${user[0]}${user[4]}



${user[1..4]}



结果是(注意第一个字符的索引是0):



bj



ig j 



l         序列操作



ø         连接操作:和字符串一样,使用+,下面是一个例子:



<#list ["joe", "fred"] + ["julia", "kate"] as user>



- ${user}



</#list>



输出结果是:



- joe



- fred



- julia



- kate



l         散列操作



ø         连接操作:和字符串一样,使用+,如果具有相同的key,右边的值替代左边的值,例如:



<#assign ages = {"joe":23, "fred":25} + {"joe":30, "julia":18}>



- joe is ${ages.joe}



- fred is ${ages.fred}



- julia is ${ages.julia} 



输出结果是:



- joe is 30



- fred is 25



- julia is 18 



l         算术运算



ø         +、-、×、/、%,下面是一个例子:



${x * x - 100}



${x / 2}



${12 % 10}



输出结果是(假设x为5):



-75



2.5







ø         操作符两边必须是数字,因此下面的代码是错误的:



${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         比较操作符



ø         使用=(或==,完全相等)测试两个值是否相等,使用!= 测试两个值是否不相等



ø         =和!=两边必须是相同类型的值,否则会产生错误,例如<#if 1 = "1">会引起错误



ø         freemarker是精确比较,所以对"x"、"x  "和"x"是不相等的



ø         对数字和日期可以使用<、<=、>和>=,但不能用于字符串



ø         由于freemarker会将>解释成ftl标记的结束字符,所以对于>和>=可以使用括号来避免这种情况,例如<#if (x > y)>



ø         另一种替代的方法是,使用lt、lte、gt和gte来替代<、<=、>和>=



l         逻辑操作符



ø         &&(and)、||(or)、!(not),只能用于布尔值,否则会产生错误



ø         例子:



<#if x < 12 && color = "green">



  we have less than 12 things, and they are green.



</#if>



<#if !hot> <#-- here hot must be a boolean -->



  it's not hot.



</#if> 



l         内建函数



ø         内建函数的用法类似访问散列的子变量,只是使用“?”替代“.”,下面列出常用的一些函数



ø         字符串使用的:



n         html:对字符串进行html编码



n         cap_first:使字符串第一个字母大写



n         lower_case:将字符串转换成小写



n         upper_case:将字符串转换成大写



n         trim:去掉字符串前后的空白字符



ø         序列使用的:



n         size:获得序列中元素的数目



ø         数字使用的:



n         int:取得数字的整数部分(如-1.9?int的结果是-1)



ø         例子(假设test保存字符串"tom & jerry"):



${test?html}



${test?upper_case?html}



输出结果是:



tom &amp; jerry



tom &amp; jerry 



l         操作符优先顺序



操作符组



操作符



后缀



[subvarname] [substringrange] . (methodparams)



一元



+expr、-expr、!



内建



?



乘法



*、 / 、%



加法



+、-



关系



<、>、<=、>=(lt、lte、gt、gte)



相等



==(=)、!=



逻辑and



&&



逻辑or



||



数字范围



..



(4)interpolation



l         interpolation有两种类型:



ø         通用interpolation:${expr}



ø         数字interpolation:#{expr}或#{expr; format}



l         注意:interpolation只能用于文本部分



l         通用interpolation



ø         插入字符串值:直接输出表达式结果



ø         插入数字值:根据缺省格式(由#setting指令设置)将表达式结果转换成文本输出;可以使用内建函数string格式化单个interpolation,下面是一个例子:



<#setting number_format="currency"/>



<#assign answer=42/>



${answer}



${answer?string}  <#-- the same as ${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-dd hh:mm:ss zzzz")}



${lastupdated?string("eee, mmm d, ''yy")}



${lastupdated?string("eeee, mmmm dd, yyyy, hh:mm:ss a '('zzz')'")} 



输出的结果类似下面的格式:



2003-04-08 21:24:44 pacific daylight time



tue, apr 8, '03



tuesday, april 08, 2003, 09:24:44 pm (pdt)



ø         插入布尔值:根据缺省格式(由#setting指令设置)将表达式结果转换成文本输出;可以使用内建函数string格式化单个interpolation,下面是一个例子:



<#assign foo=true/>



${foo?string("yes", "no")}



输出结果是:



yes



l         数字interpolation的#{expr; format}形式可以用来格式化数字,format可以是:



ø         mx:小数部分最小x位



ø         mx:小数部分最大x位



ø         例子:



           <#-- if the language is us english the output is: -->



<#assign x=2.582/>



<#assign y=4/>



#{x; m2}   <#-- 2.58 -->



#{y; m2}   <#-- 4    -->



#{x; m1}   <#-- 2.6 -->



#{y; m1}   <#-- 4.0 -->



#{x; m1m2} <#-- 2.58 -->



#{y; m1m2} <#-- 4.0  --> 


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表