ftl编辑器(freemarker)的使用和说明
- 格式:doc
- 大小:44.00 KB
- 文档页数:5
freemarker的使⽤⼀:freemarker是什么?freemarker是⼀个模板引擎,基于定义的模板和数据⽣成对应的⽂本(HTML,xml,java等),是⼀个⽣成⽂本的⼯具。
⼆:freemarker的使⽤⽅法(1)在⼯程中引⼊freemarker相关的依赖<dependency><groupId>org.freemarker</groupId><artifactId>freemarker</artifactId><version>2.3.23</version></dependency>View Code(2)使⽤的步骤第⼀步:创建⼀个Configuration对象,直接new⼀个即可,构造参数是freemarker的版本号第⼆步:设置模板⽂件所在的路径,需要给出在磁盘上储存的全路径第三步:设置⽣成的⽂件的编码格式,⼀般为utf-8格式第四步:加载模板,创建模板对象第五步:创建模板使⽤的数据集,可以使pojo也可以是map类型的第六步:创建Write流对象,将⽂件⽂件输出,需要指定⽣成的⽂件的名称第七步:调⽤模板的process⽅法,⽣成相应的⽂本第⼋步:关闭流@Testpublic void genFile() throws Exception {// 第⼀步:创建⼀个Configuration对象,直接new⼀个对象。
构造⽅法的参数就是freemarker对于的版本号。
Configuration configuration = new Configuration(Configuration.getVersion());// 第⼆步:设置模板⽂件所在的路径。
configuration.setDirectoryForTemplateLoading(new File("D:/workspace/item-web/src/main/webapp/WEB-INF/ftl"));// 第三步:设置模板⽂件使⽤的字符集。
ftl用法FTL(FreeMarker Template Language)是一种模板引擎语言,用于生成文档、页面或其他输出格式。
本文将介绍FTL的基本用法,包括语法结构、变量和表达式、条件和循环、引入模板等内容。
在开发Web应用程序时,我们通常需要生成高度动态、个性化的内容,而FTL可以帮助我们轻松地构建模板,并将数据插入其中以生成所需的输出。
FTL的语法简洁,易于理解和使用,并支持强大的模板功能,是开发人员常用的工具之一。
## FTL语法结构FTL模板由标签和表达式组成。
标签通常以尖括号`< >`包围,而表达式则用大括号`{ }`包围。
通过灵活运用这些标签和表达式,可以实现各种功能和业务逻辑。
### 变量和表达式在FTL中,我们可以定义和使用变量,以及进行各种算术和逻辑运算。
例如,我们可以使用`<#assign>`标签为变量赋值,然后通过`${变量名}`引用它们。
同时,FTL还支持常见的算术运算符和逻辑运算符,如`+`、`-`、`*`、`/`、`>`、`<`、`>=`、`<=`等。
这样,我们可以在模板中进行各种计算并生成运算结果。
### 条件和循环条件和循环是开发Web应用程序时不可或缺的一部分,FTL提供了丰富的条件判断和循环语句,方便我们处理不同的情况和操作。
常见的条件判断语句包括`<#if>`、`<#else>`、`<#elseif>`和`<#switch>`等。
而循环语句则包括`<#list>`、`<#foreach>`等。
举例来说,假设我们有一个存储了用户信息的列表,我们可以使用`<#list>`标签对列表进行遍历,并在模板中展示每个用户的信息。
此外,我们还可以利用`<#if>`标签对用户的属性进行判断,实现个性化的展示效果。
### 引入模板当我们需要在一个模板中引入另一个模板时,可以使用`<#include>`标签。
FreeMarker设计指南(3)时间:2011-04-12 14:30FreeMarker设计指南(3) 3、模板(1)整体结构 l 模板使用FTL(FreeMarker模板语言)编写,是下面各部分的一个组合:文本:直接输出 IntERPolation:由${和},或#{和}来限定,计算值替代输出 FTL标记:FreeMarker指令,和HTML标记类似,名字前加#予以区分,不会输出注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>${} for ${} 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>${} for ${} 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]${} for ${} Euros[BR]</#list >l 但是,<、</和指令之间不允许有空白字符(3)表达式l 直接指定值字符串n 使用单引号或双引号限定n 如果包含特殊字符需要转义,如下面的例子:${"It's \"quoted\" andthis is a backslash: \\"}${'It\'s "quoted" andthis is a backslash: \\'}输出结果是:It's "quoted" andthis is a backslash: \It's "quoted" andthis is a backslash: \n 下面是支持的转义序列:转义序列含义\"双引号(u0022)\'单引号(u0027)\\反斜杠(u005C)\n换行(u000A)\rReturn (u000D)\tTab (u0009)\bBackspace (u0008)\fForm feed (u000C)\l<\g>\a&\{{\xCode4位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和都是相同的布尔值n true和false,不使用引号序列n 由逗号分隔的子变量列表,由方括号限定,下面是一个例子:<#list ["winter", "spring", "summer", "autumn"] as x>${x}</#list>输出的结果是:winterspringsummerautumnn 列表的项目是表达式,所以可以有下面的例子:[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 键和值都是表达式,但是键必须是字符串获取变量顶层变量:${variable},变量名只能是字母、数字、下划线、$、@和#的组合,且不能以数字开头从散列中获取数据n 可以使用点语法或方括号语法,假设有下面的数据模型:(root)|- book| || - title = "Breeding green mouses"| || - author| || - name = "Julia Smith"| || - info = "BioloGISt, 1923-1985, Canada"- test = "title"下面都是等价的:book["author"].name.["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):BJig Jl 序列操作连接操作:和字符串一样,使用,下面是一个例子:<#list ["Joe", "Fred"] ["Julia", "Kate"] as user>- ${user}</#list>输出结果是:- Joe- Fred- Julia- Katel 散列操作连接操作:和字符串一样,使用,如果具有相同的key,右边的值替代左边的值,例如:<#assign ages = {"Joe":23, "Fred":25} {"Joe":30, "Julia":18}>- Joe is ${}- Fred is ${}- Julia is ${}输出结果是:- Joe is 30- Fred is 25- Julia is 18l 算术运算+、-、×、/、%,下面是一个例子:${x * x - 100}${x / 2}${12 % 10}输出结果是(假设x为5):-752操作符两边必须是数字,因此下面的代码是错误的:${3 * "5"} <#-- WRONG! -->使用操作符时,如果一边是数字,一边是字符串,就会自动将数字转换为字符串,例如:${3 "5"}输出结果是:35使用内建的int(后面讲述)获得整数部分,例如:${(x/2)int}${int}${int}${int}${int}输出结果是(假设x为5):211-1-1l 比较操作符使用=(或==,完全相等)测试两个值是否相等,使用!= 测试两个值是否不相等=和!=两边必须是相同类型的值,否则会产生错误,例如<#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 内建函数内建函数的用法类似访问散列的子变量,只是使用“”替代“.”,下面列出常用的一些函数字符串使用的:html:对字符串进行HTML编码cap_first:使字符串第一个字母大写lower_case:将字符串转换成小写upper_case:将字符串转换成大写trim:去掉字符串前后的空白字符序列使用的:size:获得序列中元素的数目数字使用的:int:取得数字的整数部分(如int的结果是-1)例子(假设test保存字符串"Tom & Jerry"):${testhtml}${testupper_casehtml}输出结果是:Tom & JerryTOM & JERRYl 操作符优先顺序操作符组操作符后缀[subvarName] [subStringRange] . (methodParams)一元expr、-expr、!内建?乘法*、/ 、%加法、-关系<、>、<=、>=(lt、lte、gt、gte)相等==(=)、!=逻辑and&&逻辑or||数字范围..(4)Interpolationl Interpolation有两种类型:通用Interpolation:${expr}数字Interpolation:#{expr}或#{expr; format}l 注意:Interpolation只能用于文本部分l 通用Interpolation插入字符串值:直接输出表达式结果插入数字值:根据缺省格式(由#setting指令设置)将表达式结果转换成文本输出;可以使用内建函数string格式化单个Interpolation,下面是一个例子:<#setting number_format="currency"/><#assign answer=42/>${answer}${answerstring} <#-- the same as ${answer} -->${answer}${answer}${answer}输出结果是:$$42$4,200%插入日期值:根据缺省格式(由#setting指令设置)将表达式结果转换成文本输出;可以使用内建函数string格式化单个Interpolation,下面是一个使用格式模式的例子:${lastUpdatedstring("yyyy-MM-dd HH:mm:ss zzzz")}${lastUpdatedstring("EEE, MMM d, ''yy")}${lastUpdatedstring("EEEE, MMMM dd, yyyy, hh:mm:ss a '('zzz')'")}输出的结果类似下面的格式:2003-04-08 21:24:44 Pacific Daylight TimeTue, Apr 8, '03Tuesday, April 08, 2003, 09:24:44 PM (PDT)插入布尔值:根据缺省格式(由#setting指令设置)将表达式结果转换成文本输出;可以使用内建函数string格式化单个Interpolation,下面是一个例子:<#assign foo=true/>${foostring("yes", "no")}输出结果是:yesl 数字Interpolation的#{expr; format}形式可以用来格式化数字,format可以是:mX:小数部分最小X位MX:小数部分最大X位例子:<#-- If the language is US English the output is: --><#assign x=><#assign y=4/>#{x; M2} <#-- -->#{y; M2} <#-- 4 -->#{x; m1} <#-- -->#{y; m1} <#-- -->#{x; m1M2} <#-- -->#{y; m1M2} <#-- -->(2)在模板中定义变量在模板中定义的变量有三种类型:plain变量:可以在模板的任何地方访问,包括使用include指令插入的模板,使用assign指令创建和替换局部变量:在宏定义体中有效,使用local指令创建和替换循环变量:只能存在于指令的嵌套内容,由指令(如list)自动创建宏的参数是局部变量,而不是循环变量;局部变量隐藏(而不是覆盖)同名的plain变量;循环变量隐藏同名的局部变量和plain变量,下面是一个例子:<#assign x = "plain">1. ${x} <#-- we see the plain var. here --><@test/>6. ${x} <#-- the value of plain var. was not changed --><#list ["loop"] as x>7. ${x} <#-- now the loop var. hides the plain var. --><#assign x = "plain2"> <#-- replace the plain var, hiding does not mater here -->8. ${x} <#-- it still hides the plain var. --></#list>9. ${x} <#-- the new value of plain var. --><#macro test>2. ${x} <#-- we still see the plain var. here --><#local x = "local">3. ${x} <#-- now the local var. hides it --><#list ["loop"] as x>4. ${x} <#-- now the loop var. hides the local var. --></#list>5. ${x} <#-- now we see the local var. again --></#macro>输出结果:1. plain2. plain3. local4. loop5. local6. plain7. loop8. loop9. plain2内部循环变量隐藏同名的外部循环变量,如:<#list ["loop 1"] as x>${x}<#list ["loop 2"] as x>${x}<#list ["loop 3"] as x>${x}</#list>${x}</#list>${x}</#list>输出结果:loop 1loop 2loop 3loop 2loop 1模板中的变量会隐藏(而不是覆盖)数据模型中同名变量,如果需要访问数据模型中的同名变量,使用特殊变量global,下面的例子假设数据模型中的user的值是Big Joe:<#assign user = "Joe Hider">${user} <#-- prints: Joe Hider -->${.} <#-- prints: Big Joe -->(3)名字空间通常情况,只使用一个名字空间,称为主名字空间为了创建可重用的宏、变换器或其它变量的集合(通常称库),必须使用多名字空间,其目的是防止同名冲突创建库下面是一个创建库的例子(假设保存在lib/中):<#macro copyright date><p>Copyright (C) ${date} Julia Smith. All rights reserved.<br>Email: ${mail}</p></#macro><#import "/lib/" as date="1999-2002"/>${}${mail}输出结果:<p>Copyright (C) 1999-2002 Julia Smith. All rights reserved.<#import "/lib/" as my>${}${}输出结果:<#macro copyright date><p>Copyright (C) ${date} ${user}. All rights reserved.</p></#macro><#assign mail = "">假设数据模型中的user变量的值是Fred,则下面的代码:<#import "/lib/" as date="1999-2002"/>${}输出结果:<p>Copyright (C) 1999-2002 Fred. All rights reserved.</p>补充(静态方法的调用):方法1:##定义配置文件/调用代码${("Hello")}<br>${("狼的原野")}方法2:${("@@method")}补充:常用语法EG.一个对象BOOK1.输出${}空值判断:${if_exists },${default(‘xxx’)}<#list employees as e>${e_index}. ${}输出:1. Readonly2. Robbinfreemarker中Map的使用<#list testMapkeys as testKey>< option value=”${testKey}“ >${testMap[testKey]}</option></#list>一、宏使用1.用户定义指令-使用@符合来调用2.有两种不同的类型:Macro(宏)和transform(传递器),Macro是在模板中使用macro指令定义,而transform是在模板外由程序定义(基本上都是基于Java的),这里通过Macro来介绍自定义指令。
一、准备工作1.1 下载文件可以从htt p://freema rker.source forg/站点下载最新的(最新版本是0.9.14)。
free marke r.jar包(目前最新版本是2.3.18)与eclip se插件1.2 安装ecli pse插件将下载来的e clips e插件解压缩到本地磁盘,更改huds on.freema rker_ide_0.9.14文件夹中的free marke r-2.3.6.jar文件更改成最新版本的fre emark er-2.3.18.jar,并且将MET A-INF/MANIFE ST.MF文件中的Bundl e-ClassP ath属性值修改为f reema rker-2.3.18.jar。
最后将hud son.freema rker_ide_0.9.14放到ec lipse的plug ins目录中,完成ecli pse 插件的安装。
1.3 freema rker文档下载从http://freema rker.source forg/官方网站中下载帮助文档(也有中文的手册)二、freema rker的使用2.1 简介2.1.1 FTL tag标签由于free marke r tag标签是属于fre emark er的指令,它们仅仅是f reema rker处理过程中的信息,而不会输出到页面上,所以它们与h tml标签有一些区别。
这些标签都是以#号开头,如<#import"/public/work_p ublic.ftl" as public>。
但用户自定义的标签是以@符号开头,如在free marke r中使用s truts标签:<@s.if test="result s!=null&&result s.size()!=0">注意FTL标签不可以在其他FTL标签和插值中使用(注释可以在F TL标签和插值中使用,因为它在解析时,整个注释都将抛弃,不会影响具体代码),如下面这样就是一个错误的写法:<#if <#includ e 'foo'>='bar'>...</#if>2.1.2 注释freema rker的文档注释与html相似,但它是以<#--和-->来分割的。
ftl 中的注释
FTL(FreeMarker Template Language)是一种用于生成动态内容的模板语言。
在FTL中,注释是一种特殊的标记,用于在模板中添加说明或暂时禁用某些代码。
FTL中的注释使用“<#--”和“-->”标记,注释内容位于这两个标记之间。
注释在模板编译时会被忽略,不会影响模板的输出结果。
使用注释可以帮助开发者在模板中添加一些必要的说明或临时禁用某些代码,以便于调试和维护。
例如,可以在注释中添加一些调试信息、版本号或版权声明等。
在FTL中,注释也可以嵌套在其他标签或表达式中,以实现更复杂的注释效果。
例如:
ftl复制代码:
<#-- 如果变量${variable}的值为true -->
<#if variable>
<!-- 这里是变量${variable}为true时的输出-->
</#if>
在这个例子中,注释“如果变量${variable}的值为true”仅在变量“variable”的值为true时才会被注释掉,而注释内的其他代码则在任何情况下都不会被输出。
总的来说,FTL中的注释是一种方便的工具,可以帮助
开发者更好地维护和调试模板代码。
freemarker(ftl)模板开发常⽤⽅法(迭代,数值格式化等)1.if-else常⽤<#if signStatus??> //如果signStatus值存在 <#if signStatus=='2'>是<#else>否</#if> <#else> 否</#if>if-elseif-else1 <#if condition>2 ...3 <#elseif condition2>4 ...5 <#elseif condition3>6 ...7 ...8 <#else>9 ...10 </#if>2.时间格式化时间戳转⽇期 ${time?number_to_datetime} ${time?number*1000} 时间戳乘1000⽇期格式化 ${dateTime?string('yyyy-MM-dd hh:mm:ss')} 格式化为 2020-11-12 15:05:29 ${dateTime?string('yyyy-MM-dd ')} 格式化为 2020-11-123.数值格式化数值如果有⼩数保留两位⼩数,否则补0两位,例如128.81, 688则为 688.00${((totalInvoice.amount)!0)?string('###,##0.00')}特别需要注意的是 ?前⾯的数值需要括号()⽐如:${additionsTotalAmt!0?string('###,##0.00')}⽆效果,⽽正确的是 ${(additionsTotalAmt!0)?string('###,##0.00')}另外,1 ${num?string('0.00')}2如果⼩数点后不⾜两位,⽤ 0 代替34 ${num?string('#.##')}5如果⼩数点后多余两位,就只保留两位,否则输出实际值6输出为:1239765.4678 ${num?string(',###.00')}9输出为:1,239,765.4610整数部分每三位⽤ , 分割,并且保证⼩数点后保留两位,不⾜⽤ 0 代替1112 ${num?string(',###.##')}13输出为:1,239,765.4614整数部分每三位⽤ , 分割,并且⼩数点后多余两位就只保留两位,不⾜两位就取实际位数,可以不不包含⼩数点1516 ${num?string('000.00')}17输出为:012.7018整数部分如果不⾜三位(000),前⾯⽤0补齐,否则取实际的整数位1920 ${num?string('###.00')}21等价于22 ${num?string('#.00')}23输出为:12.70参考https:///qq_32534855/article/details/676317881 ${price?string.currency}23对price进⾏格式化,显⽰为货币格式。
FreeMarker的模板文件并不比HTML页面复杂多少,FreeMarker模板文件主要由如下4个部分组成:1,文本:直接输出的部分2,注释:<#-- ... -->格式部分,不会输出3,插值:即${...}或#{...}格式的部分,将使用数据模型中的部分替代输出4,FTL指令:FreeMarker指定,和HTML标记类似,名字前加#予以区分,不会输出下面是一个FreeMarker模板的例子,包含了以上所说的4个部分<html><br><head><br><title>Welcome!</title><br></head><br><body><br><#-- 注释部分 --><br><#-- 下面使用插值 --><h1>Welcome ${user} !</h1><br><p>We have these animals:<br><u1><br><#-- 使用FTL指令 --><#list animals as being><br><li>${} for ${being.price} Euros<br><#list><br><u1><br></body><br></html>1, FTL指令规则在FreeMarker中,使用FTL标签来使用指令,FreeMarker有3种FTL标签,这和HTML标签是完全类似的.1,开始标签:<#directivename parameter>2,结束标签:</#directivename>3,空标签:<#directivename parameter/>实际上,使用标签时前面的符号#也可能变成@,如果该指令是一个用户指令而不是系统内建指令时,应将#符号改成@符号.使用FTL标签时, 应该有正确的嵌套,而不是交叉使用,这和XML标签的用法完全一样.如果全用不存在的指令,FreeMarker不会使用模板输出,而是产生一个错误消息.FreeMarker会忽略FTL标签中的空白字符.值得注意的是< , /> 和指令之间不允许有空白字符.2, 插值规则FreeMarker的插值有如下两种类型:1,通用插值${expr};2,数字格式化插值:#{expr}或#{expr;format}2.1 通用插值对于通用插值,又可以分为以下4种情况:1,插值结果为字符串值:直接输出表达式结果2,插值结果为数字值:根据默认格式(由#setting指令设置)将表达式结果转换成文本输出.可以使用内建的字符串函数格式化单个插值,如下面的例子:<#settion number_format="currency"/><#assign answer=42/>${answer}${answer?string} <#-- the same as ${answer} -->${answer?string.number}${answer?string.currency}${answer?string.percent}${answer}输出结果是:$42.00$42.0042$42.004,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 TimeTue, Apr 8, '03Tuesday, April 08, 2003, 08:08:08 PM (PDT)4,插值结果为布尔值:根据默认格式(由#setting指令设置)将表达式结果转换成文本输出.可以使用内建的字符串函数格式化单个插值,如下面的例子:<#assign foo=true/>${foo?string("yes", "no")}输出结果是:yes2.2 数字格式化插值数字格式化插值可采用#{expr;format}形式来格式化数字,其中format可以是: mX:小数部分最小X位MX:小数部分最大X位如下面的例子:<#assign x=2.582/><#assign y=4/>#{x; M2} <#-- 输出2.58 -->#{y; M2} <#-- 输出4 -->#{x; m2} <#-- 输出2.6 -->#{y; m2} <#-- 输出4.0 -->#{x; m1M2} <#-- 输出2.58 -->#{x; m1M2} <#-- 输出4.0 -->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;<\g;>\a;&\{;{\xCode;直接通过4位的16进制数来指定Unicode码,输出该unicode码对应的字符.如果某段文本中包含大量的特殊符号,FreeMarker提供了另一种特殊格式:可以在指定字符串内容的引号前增加r标记,在r标记后的文件将会直接输出.看如下代码:${r"${foo}"}${r"C:\foo\bar"}输出结果是:${foo}C:\foo\bar2,数值表达式中的数值直接输出,不需要引号.小数点使用"."分隔,不能使用分组","符号.FreeMarker目前还不支持科学计数法,所以"1E3"是错误的.在FreeMarker表达式中使用数值需要注意以下几点:1,数值不能省略小数点前面的0,所以".5"是错误的写法2,数值8 , +8 , 8.00都是相同的3,布尔值直接使用true和false,不使用引号.4,集合集合以方括号包括,各集合元素之间以英文逗号","分隔,看如下的例子:<#list ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"] as x>${x}</#list>输出结果是:星期一星期二星期三星期四星期五星期六星期天除此之外,集合元素也可以是表达式,例子如下:[2 + 2, [1, 2, 3, 4], "whatnot"]还可以使用数字范围定义数字集合,如2..5等同于[2, 3, 4, 5],但是更有效率.注意,使用数字范围来定义集合时无需使用方括号,数字范围也支持反递增的数字范围,如5..25,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"].namebook.author["name"] //混合使用点语法和方括号语法book["author"]["name"] //全部使用方括号语法使用点语法时,变量名字有顶层变量一样的限制,但方括号语法没有该限制,因为名字可以是任意表达式的结果.3.3, 字符串操作FreeMarker的表达式对字符串操作非常灵活,可以将字符串常量和变量连接起来,也可以返回字符串的子串等.字符串连接有两种语法:1,使用${..}或#{..}在字符串常量部分插入表达式的值,从而完成字符串连接. 2,直接使用连接运算符+来连接字符串例如有如下数据模型:Map root = new HashMap(); root.put("user","annlee");下面将user变量和常量连接起来:${"hello, ${user}!"} //使用第一种语法来连接${"hello, " + user + "!"} //使用+号来连接上面的输出字符串都是hello,annlee!,可以看出这两种语法的效果完全一样.值得注意的是,${..}只能用于文本部分,不能用于表达式,下面的代码是错误的: <#if ${isBig}>Wow!</#if><#if "${isBig}">Wow!</#if>应该写成:<#if isBig>Wow!</#if>截取子串可以根据字符串的索引来进行,截取子串时如果只指定了一个索引值,则用于取得字符串中指定索引所对应的字符;如果指定两个索引值,则返回两个索引中间的字符串子串.假如有如下数据模型:Map root = new HashMap(); root.put("book","struts2,freemarker");可以通过如下语法来截取子串:${book[0]}${book[4]} //结果是su${book[1..4]} //结果是tru3.4 集合连接运算符这里所说的集合运算符是将两个集合连接成一个新的集合,连接集合的运算符是+,看如下的例子:<#list ["星期一","星期二","星期三"] + ["星期四","星期五","星期六","星期天"] as x>${x}</#list>输出结果是:星期一星期二星期三星期四星期五星期六星期天3.5 Map连接运算符Map对象的连接运算符也是将两个Map对象连接成一个新的Map对象,Map对象的连接运算符是+,如果两个Map对象具有相同的key,则右边的值替代左边的值.看如下的例子:<#assign scores = {"语文":86,"数学":78} + {"数学":87,"Java":93}>语文成绩是${scores.语文}数学成绩是${scores.数学}Java成绩是${scores.Java}输出结果是:语文成绩是86数学成绩是87Java成绩是933.6 算术运算符FreeMarker表达式中完全支持算术运算,FreeMarker支持的算术运算符包括:+, - , * , / , % 看如下的代码:<#assign x=5>${ x * x - 100 }${ x /2 }${ 12 %10 }输出结果是:-75 2.5 2在表达式中使用算术运算符时要注意以下几点:1,运算符两边的运算数字必须是数字2,使用+运算符时,如果一边是数字,一边是字符串,就会自动将数字转换为字符串再连接,如:${3 + "5"},结果是:35使用内建的int函数可对数值取整,如:<#assign x=5>${ (x/2)?int }${ 1.1?int }${ 1.999?int }${ -1.1?int }${ -1.999?int }结果是:2 1 1 -1 -13.7 比较运算符表达式中支持的比较运算符有如下几个:1,=或者==:判断两个值是否相等.2,!=:判断两个值是否不等.3,>或者gt:判断左边值是否大于右边值4,>=或者gte:判断左边值是否大于等于右边值5,<或者lt:判断左边值是否小于右边值6,<=或者lte:判断左边值是否小于等于右边值注意:=和!=可以用于字符串,数值和日期来比较是否相等,但=和!=两边必须是相同类型的值,否则会产生错误,而且FreeMarker是精确比较,"x","x ","X"是不等的.其它的运行符可以作用于数字和日期,但不能作用于字符串,大部分的时候,使用gt等字母运算符代替>会有更好的效果,因为 FreeMarker会把>解释成FTL 标签的结束字符,当然,也可以使用括号来避免这种情况,如:<#if (x>y)>3.8 逻辑运算符逻辑运算符有如下几个:逻辑与:&&逻辑或:||逻辑非:!逻辑运算符只能作用于布尔值,否则将产生错误3.9 内建函数FreeMarker还提供了一些内建函数来转换输出,可以在任何变量后紧跟?,?后紧跟内建函数,就可以通过内建函数来轮换输出变量.下面是常用的内建的字符串函数:html:对字符串进行HTML编码cap_first:使字符串第一个字母大写lower_case:将字符串转换成小写upper_case:将字符串转换成大写trim:去掉字符串前后的空白字符下面是集合的常用内建函数size:获取序列中元素的个数下面是数字值的常用内建函数int:取得数字的整数部分,结果带符号例如:<#assign test="Tom & Jerry">${test?html}${test?upper_case?html}结果是:Tom & Jerry TOM & JERRY3.10 空值处理运算符FreeMarker对空值的处理非常严格,FreeMarker的变量必须有值,没有被赋值的变量就会抛出异常,因为FreeMarker未赋值的变量强制出错可以杜绝很多潜在的错误,如缺失潜在的变量命名,或者其他变量错误.这里所说的空值,实际上也包括那些并不存在的变量,对于一个Java 的 null值而言,我们认为这个变量是存在的,只是它的值为null,但对于FreeMarker模板而言,它无法理解null 值,null值和不存在的变量完全相同.为了处理缺失变量,FreeMarker提供了两个运算符:!:指定缺失变量的默认值??:判断某个变量是否存在其中,!运算符的用法有如下两种:variable!或variable!defaultValue,第一种用法不给缺失的变量指定默认值,表明默认值是空字符串,长度为0的集合,或者长度为0的Map对象.使用!指定默认值时,并不要求默认值的类型和变量类型相同.使用??运算符非常简单,它总是返回一个布尔值,用法为:variable??,如果该变量存在,返回true,否则返回false3.11 运算符的优先级FreeMarker中的运算符优先级如下(由高到低排列):1,一元运算符:!2,内建函数:?3,乘除法:*, / , %4,加减法:- , +5,比较:> , < , >= , <= (lt , lte , gt , gte)6,相等:== , = , !=7,逻辑与:&&8,逻辑或:||9,数字范围:..实际上,我们在开发过程中应该使用括号来严格区分,这样的可读性好,出错少4 FreeMarker的常用指令FreeMarker的FTL指令也是模板的重要组成部分,这些指令可实现对数据模型所包含数据的抚今迭代,分支控制.除此之外,还有一些重要的功能,也是通过FTL 指令来实现的.4.1 if指令这是一个典型的分支控制指令,该指令的作用完全类似于Java语言中的if,if 指令的语法格式如下:<#if condition>...<#elseif condition>...<#elseif condition>...<#else> ...</#if>例子如下:<#assign age=23><#if (age>60)>老年人<#elseif (age>40)>中年人<#elseif (age>20)>青年人<#else> 少年人</#if>输出结果是:青年人上面的代码中的逻辑表达式用括号括起来主要是因为里面有>符号,由于FreeMarker会将>符号当成标签的结束字符,可能导致程序出错,为了避免这种情况,我们应该在凡是出现这些符号的地方都使用括号.4.2 switch , case , default , break指令这些指令显然是分支指令,作用类似于Java的switch语句,switch指令的语法结构如下:<#switch value><#case refValue>...<#break><#case refValue>...<#break><#default>...</#switch>4.3 list, break指令list指令是一个迭代输出指令,用于迭代输出数据模型中的集合,list指令的语法格式如下:<#list sequence as item>...</#list>上面的语法格式中,sequence就是一个集合对象,也可以是一个表达式,但该表达式将返回一个集合对象,而item是一个任意的名字,就是被迭代输出的集合元素.此外,迭代集合对象时,还包含两个特殊的循环变量:item_index:当前变量的索引值item_has_next:是否存在下一个对象也可以使用<#break>指令跳出迭代例子如下:<#list ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"] as x>${x_index + 1}.${x}<#if x_has_next>,</if><#if x="星期四"><#break></#if></#list>4.4 include指令include指令的作用类似于JSP的包含指令,用于包含指定页.include指令的语法格式如下:<#include filename [options]>在上面的语法格式中,两个参数的解释如下:filename:该参数指定被包含的模板文件options:该参数可以省略,指定包含时的选项,包含encoding和parse两个选项,其中encoding指定包含页面时所用的解码集,而parse指定被包含文件是否作为FTL文件来解析,如果省略了parse选项值,则该选项默认是true.4.5 import指令该指令用于导入FreeMarker模板中的所有变量,并将该变量放置在指定的Map 对象中,import指令的语法格式如下:<#import "/lib/common.ftl" as com>上面的代码将导入/lib/common.ftl模板文件中的所有变量,交将这些变量放置在一个名为com的Map对象中.4.6 noparse指令noparse指令指定FreeMarker不处理该指定里包含的内容,该指令的语法格式如下:<#noparse>...</#noparse>看如下的例子:<#noparse><#list books as book><tr><td>${}<td>作者:${book.author}</#list></#noparse>输出如下:<#list books as book><tr><td>${}<td>作者:${book.author}</#list>4.7 escape , noescape指令escape指令导致body区的插值都会被自动加上escape表达式,但不会影响字符串内的插值,只会影响到body内出现的插值,使用escape指令的语法格式如下: <#escape identifier as expression>...<#noescape>...</#noescape></#escape>看如下的代码:<#escape x as x?html>First name:${firstName}Last name:${lastName}Maiden name:${maidenName}</#escape>上面的代码等同于:First name:${firstName?html}Last name:${lastName?html}Maiden name:${maidenName?html}escape指令在解析模板时起作用而不是在运行时起作用,除此之外,escape指令也嵌套使用,子escape继承父escape的规则,如下例子:<#escape x as x?html>Customer Name:${customerName}Items to ship;<#escape x as itemCodeToNameMap[x]>${itemCode1}${itemCode2}${itemCode3}${itemCode4}</#escape></#escape>上面的代码类似于:Customer Name:${customerName?html}Items to ship;${itemCodeToNameMap[itemCode1]?html}${itemCodeToNameMap[itemCode2]?html}${itemCodeToNameMap[itemCode3]?html}${itemCodeToNameMap[itemCode4]?html}对于放在escape指令中所有的插值而言,这此插值将被自动加上escape表达式,如果需要指定escape指令中某些插值无需添加escape表达式,则应该使用noescape指令,放在noescape指令中的插值将不会添加escape表达式.4.8 assign指令assign指令在前面已经使用了多次,它用于为该模板页面创建或替换一个顶层变量,assign指令的用法有多种,包含创建或替换一个顶层变量, 或者创建或替换多个变量等,它的最简单的语法如下:<#assign name=value [in namespacehash]>,这个用法用于指定一个名为name的变量,该变量的值为value,此外,FreeMarker允许在使用 assign指令里增加in子句,in子句用于将创建的name变量放入namespacehash命名空间中.assign指令还有如下用法:<#assign name1=value1 name2=value2 ...nameN=valueN [in namespacehash]>,这个语法可以同时创建或替换多个顶层变量,此外,还有一种复杂的用法,如果需要创建或替换的变量值是一个复杂的表达式,则可以使用如下语法格式:<#assign name [in namespacehash]>capture this</#assign>,在这个语法中,是指将assign指令的内容赋值给name变量.如下例子:<#assign x><#list ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"] as n>${n}</#list></#assign>${x}上面的代码将产生如下输出:星期一星期二星期三星期四星期五星期六星期天虽然assign指定了这种复杂变量值的用法,但是我们也不要滥用这种用法,如下例子:<#assign x>Hello ${user}!</#assign>,以上代码改为如下写法更合适:<#assign x="Hello ${user}!">4.9 setting指令该指令用于设置FreeMarker的运行环境,该指令的语法格式如下:<#setting name=value>,在这个格式中,name的取值范围包含如下几个:locale:该选项指定该模板所用的国家/语言选项number_format:指定格式化输出数字的格式boolean_format:指定两个布尔值的语法格式,默认值是true,falsedate_format,time_format,datetime_format:指定格式化输出日期的格式time_zone:设置格式化输出日期时所使用的时区4.10 macro , nested , return指令macro可以用于实现自定义指令,通过使用自定义指令,可以将一段模板片段定义成一个用户指令,使用macro指令的语法格式如下:<#macro name param1 param2 ... paramN>...<#nested loopvar1, loopvar2, ..., loopvarN>...<#return>...</#macro>在上面的格式片段中,包含了如下几个部分:name:name属性指定的是该自定义指令的名字,使用自定义指令时可以传入多个参数paramX:该属性就是指定使用自定义指令时报参数,使用该自定义指令时,必须为这些参数传入值nested指令:nested标签输出使用自定义指令时的中间部分nested指令中的循环变量:这此循环变量将由macro定义部分指定,传给使用标签的模板return指令:该指令可用于随时结束该自定义指令.看如下的例子:<#macro book> //定义一个自定义指令j2ee</#macro><@book /> //使用刚才定义的指令上面的代码输出结果为:j2ee在上面的代码中,可能很难看出自定义标签的用处,因为我们定义的book指令所包含的内容非常简单,实际上,自定义标签可包含非常多的内容,从而可以实现更好的代码复用.此外,还可以在定义自定义指令时,为自定义指令指定参数,看如下代码:<#macro book booklist> //定义一个自定义指令booklist是参数<#list booklist as book>${book}</#list></#macro><@book booklist=["spring","j2ee"] /> //使用刚刚定义的指令上面的代码为book指令传入了一个参数值,上面的代码的输出结果为:spring j2ee不仅如此,还可以在自定义指令时使用nested指令来输出自定义指令的中间部分,看如下例子:<#macro page title><html><head><title>FreeMarker示例页面 - ${title?html}</title></head><body><h1>${title?html}</h1><#nested> //用于引入用户自定义指令的标签体</body></html></#macro>上面的代码将一个HTML页面模板定义成一个page指令,则可以在其他页面中如此page指令:<#import "/common.ftl" as com> //假设上面的模板页面名为common.ftl,导入页面<@com.page title="book list"><u1><li>spring</li><li>j2ee</li></ul></@com.page>从上面的例子可以看出,使用macro和nested指令可以非常容易地实现页面装饰效果,此外,还可以在使用nested指令时,指定一个或多个循环变量,看如下代码: <#macro book><#nested 1> //使用book指令时指定了一个循环变量值<#nested 2></#macro><@book ;x> ${x} .图书</@book>当使用nested指令传入变量值时,在使用该自定义指令时,就需要使用一个占位符(如book指令后的;x).上面的代码输出文本如下:1 .图书2 .图书在nested指令中使用循环变量时,可以使用多个循环变量,看如下代码:<#macro repeat count><#list 1..count as x> //使用nested指令时指定了三个循环变量<#nested x, x/2, x==count></#list></#macro><@repeat count=4 ; c halfc last>${c}. ${halfc}<#if last> Last! </#if></@repeat>上面的输出结果为:1. 0.52. 13. 1.54. 2 Last;return指令用于结束macro指令,一旦在macro指令中执行了return指令,则FreeMarker不会继续处理macro指令里的内容,看如下代码:<#macro book>spring<#return>j2ee</#macro><@book />上面的代码输出:spring,而j2ee位于return指令之后,不会输出.if, else, elseifswitch, case, default, breaklist, breakincludeImportcompressescape, noescapeassignglobalsettingmacro, nested, returnt, lt, rt3一些常用方法或注意事项表达式转换类数字循环对浮点取整数给变量默认值判断对象是不是null常用格式化日期添加全局共享变量数据模型直接调用java对象的方法字符串处理(内置方法)在模板里对sequences和hashes初始化注释标志sequences内置方法hashes内置方法4 freemarker在web开发中注意事项web中常用的几个对象view中值的搜索顺序在模板里ftl里使用标签如何初始化共享变量与webwork整合配置5高级方法自定义方法自定义 Transforms1概念最常用的3个概念sequence 序列,对应java里的list、数组等非键值对的集合hash 键值对的集合namespace 对一个ftl文件的引用,利用这个名字可以访问到该ftl文件的资源2指令if, else, elseif语法<#if condition>...<#elseif condition2>...<#elseif condition3>......<#else>...</#if>用例<#if x = 1>x is 1</#if><#if x = 1>x is 1<#else>x is not 1</#if>switch, case, default, break语法<#switch value><#case refValue1>...<#break><#case refValue2>...<#break>...<#case refValueN>...<#break><#default>...</#switch>用例字符串<#switch being.size><#case "small">This will be processed if it is small <#break><#case "medium">This will be processed if it is medium <#break><#case "large">This will be processed if it is large <#break><#default>This will be processed if it is neither </#switch>数字<#switch x><#case x = 1>1<#case x = 2>2<#default>d</#switch>如果x=1 输出 1 2, x=2输出 2, x=3 输出dlist, break语法<#list sequence as item>...<#if item = "spring"><#break></#if>...</#list>关键字item_index:是list当前值的下标item_has_next:判断list是否还有值用例<#assign seq = ["winter", "spring", "summer", "autumn"]><#list seq as x>${x_index + 1}. ${x}<#if x_has_next>,</#if></#list>输出1. winter,2. spring,3. summer,4. autumninclude语法<#include filename>or<#include filename options>options包含两个属性encoding=”GBK” 编码格式parse=true 是否作为ftl语法解析,默认是true,false就是以文本方式引入.注意在ftl文件里布尔值都是直接赋值的如parse=true,而不是parse=”true” 用例/common/copyright.ftl包含内容Copyright 2001-2002 ${me}<br>All rights reserved.模板文件<#assign me = "Juila Smith"><h1>Some test</h1><p>Yeah.<hr><#include "/common/copyright.ftl" encoding=”GBK”>输出结果<h1>Some test</h1><p>Yeah.<hr>Copyright 2001-2002 Juila SmithAll rights reserved.Import语法<#import path as hash>类似于java里的import,它导入文件,然后就可以在当前文件里使用被导入文件里的宏组件。
freemarker(FTL)常见语法⼤全FreeMarker的插值有如下两种类型:1,通⽤插值${expr};2,数字格式化插值:#{expr}或#{expr;format} ${?if_exists } //⽤于判断如果存在,就输出这个值${?default(‘xxx’)}//默认值xxx${!"xxx"}//默认值xxx${book.date?string('yyyy-MM-dd')} //⽇期格式${book?string.number} 20 //三种不同的数字格式${book?string.currency}--<#-- $20.00 -->${book?string.percent}—<#-- 20% --><#assign foo=ture /> //声明变量,插⼊布尔值进⾏显⽰${foo?string("yes","no")} <#-- yes --><等⼤⼩⽐较符号使⽤需要注意:(xml的原因),可以⽤于⽐较数字和⽇期使⽤lt、lte、gt和gte来替代<、<=、>和>= 也可以使⽤括号<#if (x>y)>内置函数: 调⽤区别于属性的访问,使⽤?代替.常见的⼀些内置函数对于字符串html-对字符串进⾏HTML编码cap_first-使字符串第⼀个字母⼤写lower_case-将字符串转换成⼩写trim-去掉字符串前后的空⽩字符对于Sequences(序列)size-获得序列中元素的数⽬对于数字int-取得数字的整数部分(如-1.9?int的结果是-1)对于集合,可以使⽤数组的⽅式,使⽤下标索引进⾏访问逻辑判断:if................<#if condition>...<#elseif condition2>...<#elseif condition3>......<#else>...Boolean类型的空值判断空值判断可以写成<#if ?? > //注意${}为变量的渲染显⽰,⽽<>为定义等操作符的定义switch............<#switch value><#case refValue1>...<#break><#case refValue2>...<#break>...<#case refValueN>...<#break><#default>...</#switch>快速定义int区间的集合<#assign l=0..100/> //注意不需要[]3:循环读取集合: 注意/的使⽤<#list student as stu>${stu}<br/></#list>与jstl循环类似,也可以访问循环的状态item_index:当前变量的索引值item_has_next:是否存在下⼀个对象其中item名称为as后的变量名,如stu集合长度判断<#if student?size != 0></#if> 判断=的时候,注意只要⼀个=符号,⽽不是==宏/模板初步了解: 使⽤更像⼀个闭包closure,可以定义后,在脚本中任意地⽅引⽤,并原地起作⽤<#macro greet><font size="+2">Hello Joe!</font></#macro>使⽤的⽅式为:<@greet></@greet> //同xml可以简写成<@greet/>宏的参数定义,类似js,在宏名后带参数进⾏传递定义<#macro greet person color>${person}</#macro>调⽤带参数时,注意使⽤类似XML的属性格式进⾏传递,不需要关⼼顺序问题<@greet person="Fred" color="black"/>参数默认值定义,如果没有,就必须要求传递完整的参数列表<#macro greet person color="black"><font size="+2" color="${color}">Hello ${person}!</font></#macro>使⽤xml的嵌套内容进⾏传递宏调⽤,关键标签 <#nested><#macro border><table border=4 cellspacing=0 cellpadding=4><tr><td><#nested></tr></td></table></#macro>调⽤时:<@border>The bordered text</@border><#nested> 标签可以在宏中多次调⽤,也可以将多个宏组合进⾏嵌套for循环的精简版:<#list 1..count as x></#list>宏的循环变量,配合嵌套标签进⾏参数传递,<#macro repeat count><#list 1..count as x><#nested x, x/2, x==count> //这⾥的三个参数,将会传递到嵌套内容中</#list></#macro><@repeat count=4 ; c, halfc, last>${c}. ${halfc}<#if last> Last!</#if> //这⾥的内容由macro中的<#nested>进⾏参数的传递,传递的数量任意,当注意需要宏接受这些</@repeat>上述还需要注意;的使⽤参数的数量是可变的,并不要求全部都有,但是效果不同在模板中定义变量在模板中定义的变量有三种类型:plain变量:可以在模板的任何地⽅访问,包括使⽤include指令插⼊的模板,使⽤assign指令创建和替换。
FTL(FreeMarker Template Language)是一种用于动态生成文本输出的模板语言。
它通常用于Web开发中,在生成HTML页面时,通过模板引擎来动态生成页面内容。
而在使用FTL时,我们经常需要对文本进行替换操作,这就需要用到正则表达式。
1. 了解FTL replace指令在FTL中,replace指令用于替换文本中的指定内容,其基本语法如下:```<#replace pattern="要替换的内容" replacement="替换后的内容" src="源字符串">```其中,pattern为要替换的内容,可以是字符串或者正则表达式;replacement为替换后的内容;src为源字符串。
2. 使用FTL replace指令的示例下面是一个使用FTL replace指令的示例:```<#assign str = "Hello, World!"><#replace pattern="Hello" replacement="Hi" src=str />```经过上述替换操作后,str的值将变为"Hi, World!"。
3. 使用正则表达式进行替换在实际的开发中,我们通常会使用正则表达式来进行更加灵活的替换操作。
FTL的replace指令同样支持正则表达式的使用,我们可以通过正则表达式来匹配复杂的文本内容。
4. 替换指定格式的日期字符串假设我们需要将日期字符串从"yyyy-MM-dd"格式替换为"dd/MM/yyyy"格式,可以使用如下代码:```<#assign dateStr = "2022-01-01"><#replace pattern="(\d{4})-(\d{2})-(\d{2})"replacement="$3/$2/$1" src=dateStr />```通过上述代码,我们可以将dateStr的值从"2022-01-01"替换为"01/01/2022"。
freemarker使用流程Freemarker是一种模板引擎,它可以将数据和模板结合起来生成最终的输出。
它可以用于Java、.NET、PHP等多种编程语言中,本文将以Java为例介绍Freemarker的使用流程。
1. 下载Freemarker首先需要下载Freemarker的jar包,可以在官网上下载最新版本。
下载完成后将jar包添加到项目的classpath中。
2. 创建模板文件Freemarker使用.ftl作为模板文件的扩展名,创建一个.ftl文件并编写模板代码。
例如:```<html><head><title>${title}</title></head><body><h1>${heading}</h1><ul><#list items as item><li>${item}</li></#list></ul></body></html>```在这个例子中,`${}`是Freemarker的语法,表示要替换成实际的值。
`${title}`、`${heading}`和`${item}`都是变量名,在生成输出时会被替换成相应的值。
3. 创建数据模型数据模型是一个Java对象或Map,它包含了模板所需要的数据。
例如:```Map<String, Object> data = new HashMap<>();data.put("title", "My Website");data.put("heading", "Welcome to my website!");List<String> items = new ArrayList<>();items.add("Item 1");items.add("Item 2");items.add("Item 3");data.put("items", items);```在这个例子中,我们创建了一个Map对象,包含了模板需要的三个变量:`title`、`heading`和`items`。
Freemarker的基本语法及⼊门基础freemarker的基本语法及⼊门基础⼀、freemarker模板⽂件(*.ftl)的基本组成部分1. ⽂本:直接输出的内容部分2. 注释:不会输出的内容,格式为<#-- 注释内容 -->3. 取值(插值):代替输出数据模型的部分,格式为${数据模型}或#{数据模型}4. ftl指令:Freemarker指令,类似于HTML标记。
内建指令:开始标签:<#directivename parameter> 结束标签:</#directivename> 空标签:<#directivename parameter/>⾃定义指令:开始标签:<@directivename parameter> 结束标签:</@directivename> 空标签:<@directivename parameter/>⾄于什么是内建指令,什么是⾃定义指令我会在下⾯叙述到。
⼆、Freemarker语法及使⽤⽅法1. 取值(插值)指令及适⽤类型:(1) ${var}适⽤类型:java中常⽤的⼋⼤基本类型以及我们的String引⽤类型,但是,freemarker中boolean类型显⽰时true==yes false==no⽰例:在后台⽂件中定义变量String strVar = "世界你好";int intVar = 10;boolean booVar = true;在页⾯中获取变量:String获取:<font color="red"> ${strVar} </font><br>int获取:<font color="red"> ${intVar} </font><br>boolean获取:<font color="red"> ${booVar?string("yes","no")} </font>展⽰结果:String获取:世界你好int获取:10boolean获取:yes(2)${var!}适⽤类型:对 null 或者不存在的对象进⾏取值,可以设置默认值,例:${var!'我是默认值'} 即,有值时显⽰正常值,⽆值时⽰例:在后台⽂件中定义变量String strVar = "世界你好";String str = null;在页⾯中获取变量:String获取:<font color="red"> ${strVar!"我是空"} </font><br>str获取:<font color="red"> ${str!} </font><br>str获取:<font color="red"> ${str!"默认"} </font><br>展⽰结果:String获取:世界你好str获取:str获取:默认(3)${封装对象.属性}适⽤类型:对封装对象进⾏取值,例:${}⽰例:在后台⽂件中封装对象User[ name, age ]String name = "姓名";int age = 18;在页⾯中获取变量:name获取:<font color="red"> ${} </font><br>age获取:<font color="red"> ${User.age} </font><br>展⽰结果:name获取:姓名age获取:18(4)${date?String('yyyy-MM-dd')}适⽤类型:对⽇期格式进⾏取值,在这⾥我要强调的是,定义Date类型的变量时,java.util.Date⽆法输出⽇期,须使⽤java.sql.Date⽰例:在后台⽂件中定义变量java.sql.Date date = new Date().getTime();java.sql.Date time = new Date().getTime();java.sql.Date datetime = new Date().getTime();在页⾯中获取变量:date获取:<font color="red"> ${date?string('yyyy-MM-dd')} </font><br>time获取:<font color="red"> ${date?string('HH:mm:ss')} </font><br>datetime获取:<font color="red"> ${date?string('yyyy-MM-dd HH:mm:ss')} </font><br>展⽰结果:name获取:姓名age获取:18(5)${var?html}适⽤类型:转义HTML内容⽰例:在后台⽂件中封装变量Menu[ name, model ]Menu m = new Menu();m.setName(" freemarker ");m.setModel("<font color = 'red'>我只是个菜单</font>");在页⾯中获取变量:⾮转义获取:<font color="red"> ${m.model} </font><br>转义获取: ${m.model?html} </font><br>展⽰结果:⾮转义获取:我只是个菜单转义获取:<font color = 'red'>我只是个菜单</font>(6)<#assign num = 100 />适⽤类型:定义变量,⽀持计算和赋值⽰例:在页⾯中定义变量:<#assign num = 100 />num获取:<font color="red"> ${num)} </font><br>计算结果:<font color="red"> ${num * 10} </font><br>展⽰结果:num获取:100计算结果:1000(7)对List集合进⾏取值<#list list集合 as item>${item} --取值</#list>⽰例:List<String> strList = new ArrayList<String>();strList.add("第⼀个值");strList.add("第⼆个值");strList.add("第三个值");在页⾯中获取变量:<#list strList as item>${item!}<br/> --取值</#list>展⽰结果:第⼀个值第⼆个值第三个值(8)对Map集合进⾏取值<#list map?keys as key>${key}:${map[key]}</#list>⽰例:在后台⽂件中定义变量Map<String, Object> m = new HashMap<String, Object>(); m.put("name","姓名");m.put("age",18);m.put("sex","男");在页⾯中获取变量:<#list m?keys as key>${key}:${m[key]}</#list>展⽰结果:name:姓名age:18sex:男2. 条件判断指令:(1) if格式:<#if 条件>输出</#if>⽰例:在页⾯中定义变量并判断条件:<#assign age = 18 /><br><#if age == 18><font color="red"> age = 18</font></#if>展⽰结果:age = 18(2) if - else格式:<#if 条件>输出<#else>输出</#if>⽰例:在页⾯中定义变量并判断条件:<#assign age = 20 /><br><#if age == 18><font color="red"> age = 18</font><#else><font color="red"> age != 18</font></#if>展⽰结果:age != 18(3) if - elseif - else格式:<#if 条件1>输出<#elseif 条件2>输出<#else>输出</#if>在页⾯中定义变量并判断条件:<#assign age = 20 /><br><#if age > 18><font color="red">青年</font><#elseif age == 18><font color="red"> 成年</font><#else><font color="red"> 少年</font></#if>展⽰结果:成年(4) switch --常与case break default⼀起使⽤参数可为字符串格式:<#switch var><#case 条件1>输出<#break><#case 条件2>输出<#break><#default>输出</#switch>⽰例:在页⾯中定义变量并判断:<#switch var="星期⼀"><#case "星期⼀">油焖⼤虾<#break><#case "星期⼆">炸酱⾯<#break><#default>肯德基</#switch>展⽰结果:油焖⼤虾3. ⾃定义函数、⾃定义指令:(1) ⾃定义函数实现TemplateMthodModelEx(2) ⾃定义指令实现TemplateDirectiveModel⽰例:<@⾃定义指令名称⼊参(key-value格式) ; 出参(list格式)>运⾏条件</@⾃定义指令名称>PS:不同的返回值⽤逗号( , )间隔开4.常⽤内建函数、macro(宏指令)、function(函数指令):(1) 常⽤内建函数处理字符串:substring 截取字符串,包头不包尾(下标)cap_first 第⼀个字母⼤写end_with 以什么字母结尾contains 是否包含⽬标字符串date datetime time 转换成⽇期格式starts_with 以什么字母开头index_of 返回某个指定的字符串值在字符串中⾸次出现的位置(下标) last_index_of 获取指定字符出现的最后位置(下标)split 分隔trim 去两端空格处理数字:stringx?string("0.##") 变成⼩数点后⼏位round 四舍五⼊floor 去掉⼩数点ceiling 近1 变成整数first: 取List值第⼀个值last: 取List值最后⼀个值seq_contains: 是否包含指定字符seq_index_of: 指定字符所在位置size: 集合⼤⼩reverse: 集合倒序排列sort: 对集合进⾏排序sort_by: 根据某⼀个属性排序chunk: 分块处理其他:is_string: 是否为字符类型is_number: 是否为整数类型is_method: 是否为⽅法(): 判断整个变量has_content: 判断对象是否为空或不存在 eval:求值(2) macro(宏指令)调⽤:<@macro_name param />语法:<#macro 变量名参数><#nested/></#macro>(3) function(函数指令)调⽤:${function_name(param)}语法:<#function 变量名参数><#return></#function>。
ftl语法if_exists replace-概述说明以及解释1. 引言1.1 概述概述:在现代的软件开发中,模板引擎是一个非常重要的工具,它能够帮助开发人员快速构建动态网页。
其中,FreeMarker(简称ftl)是一种流行的模板引擎,在Java开发中被广泛使用。
本文将主要介绍ftl语法中的if_exists和replace两个关键词的使用方法。
if_exists用于判断变量是否存在,replace用于替换字符串中的部分内容。
通过深入了解这两个功能,开发人员可以更加灵活地处理模板中的数据,提高模板编写效率。
通过本文的学习,读者将能够熟练运用if_exists和replace这两个关键词,为自己的模板编写工作带来更多可能性。
同时,本文还将结合实际案例,帮助读者更好地理解和应用这两个功能。
1.2 文章结构文章结构包括三个部分,分别是引言、正文和结论。
在引言部分,我们将对文章主题进行概述,介绍文章的结构和目的,为读者提供一个整体的印象。
在正文部分,我们将分别介绍ftl语法、if_exists和replace的概念和用法,帮助读者更好地理解这些内容。
最后,在结论部分,我们将对整篇文章进行总结,提出应用建议,并展望未来可能的发展方向,为读者留下深刻印象并启发思考。
1.3 目的本文的目的在于介绍ftl语法中的if_exists和replace的用法,通过详细讲解这两个语法的功能和应用场景,帮助读者更好地理解和运用它们。
同时,我们将探讨这两个语法在实际开发中的作用,以及它们如何提高模板引擎的灵活性和效率。
通过本文的阐述,读者将能够更加熟练地使用ftl 语法,提升模板编写的质量和效率,为项目的开发和维护带来更多便利和便捷。
2. 正文2.1 什么是ftl语法FreeMarker Template Language(简称ftl)是一种基于模板的通用型模板引擎语言,用于生成输出文本。
它的语法类似于HTML,但具有更强大和灵活的功能。
freemaker模板引擎使⽤详解⽬录:⼀.freemaker介绍⼆.freemaker的使⽤正⽂:⼀.freemaker介绍1.1FreeMarker概述:FreeMarker是⼀款模板引擎,即⼀种基于模板和要改变的数据,并⽤来⽣成输出⽂本(HTML⽹页,电⼦邮件,配置⽂件,源代码等)的通⽤⼯具。
1.2获得FreeMarker下载FreeMarker jar包:中⽂⽹:使⽤Maven依赖jar包:<dependency><groupId>org.freemarker</groupId><artifactId>freemarker-gae</artifactId><version>2.3.25-incubating</version></dependency>⼆.FreeMarker的使⽤2.1、新建⼀个基于Maven的Web项⽬2.2、添加依赖这⾥没有使⽤MVC,只需依赖FreeMarker、Servlet与JSP核⼼包就可以了,修改后的pom.xml⽂件如下。
<project xmlns="/POM/4.0.0" xmlns:xsi="/2001/XMLSchema-instance"xsi:schemaLocation="/POM/4.0.0 /xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.zhangguo</groupId><artifactId>SpringMVC71</artifactId><version>0.0.1-SNAPSHOT</version><packaging>war</packaging><dependencies><!-- FreeMarker --><dependency><groupId>org.freemarker</groupId><artifactId>freemarker-gae</artifactId><version>2.3.25-incubating</version></dependency><!-- Servlet核⼼包 --><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.0.1</version><scope>provided</scope></dependency><!--JSP --><dependency><groupId>javax.servlet.jsp</groupId><artifactId>jsp-api</artifactId><version>2.1</version><scope>provided</scope></dependency></dependencies></project>依赖成功的结果:2.3、创建⽂章POJO类在src/main/java源代码⽬录下创建Article.java⽂件,该类代表⽂章,代码如下:package com.zhangguo.springmvc71.entities;/*** ⽂章**/public class Article {/** 编号*/private int id;/** 标题*/private String title;/** 内容*/private String content;public Article() {}public Article(int id, String title, String content) {super();this.id = id;this.title = title;this.content = content;}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}public String getContent() {return content;}public void setContent(String content) {this.content = content;}@Overridepublic String toString() {return "Article [id=" + id + ", title=" + title + ", content=" + content + "]";}}2.4、创建⽂章业务类在src/main/java源代码⽬录下创建ArticleService.java⽂件,该类代表⽂章业务,主要提供⽂章数据,定义了⼀个⽂章集合中,初始化时向集合中随意添加了5个⽂章对象,代码如下:package com.zhangguo.springmvc71.Services;import java.util.ArrayList;import java.util.List;import com.zhangguo.springmvc71.entities.Article;/*** ⽂章业务类(模拟)**/public class ArticleService {private static List<Article> articles;static {articles = new ArrayList<Article>();articles.add(new Article(20160701, "不明真相的美国⼈被UFO惊呆了其实是长征7号","据美国《洛杉矶时报》报道,当地时间周三晚(北京时间周四),在美国中西部的犹他州、内华达州、加利福利亚州,数千⼈被划过夜空的神秘⽕球吓到"));articles.add(new Article(20160702, "法国巴黎圣母院为教堂恐袭案遇害神⽗举⾏⼤弥撒", "⽽据美国战略司令部证实,其实这是中国长征七号⽕箭重新进⼊⼤⽓层,刚好经过加利福利亚附近。
ftl模板引擎语法FTL(FreeMarker Template Language)是一种模板引擎语言,用于生成动态内容。
下面是关于FTL模板引擎语法的详细介绍:1. 变量引用:在FTL中,可以使用`${}`语法来引用变量。
例如`${user}`表示引用名为user的变量。
2. 表达式:FTL支持各种表达式,包括算术、逻辑和比较表达式。
例如,可以使用`+`、`-`、``、`/`等运算符进行算术运算,使用`&&`、`||`等运算符进行逻辑运算,使用`>`、`<`、`==`等运算符进行比较运算。
3. 条件语句:FTL提供了`<#if>`、`<#elseif>`和`<#else>`标签来实现条件语句。
例如:<#if condition>。
<!-条件为真时执行的代码 -->。
<#elseif condition2>。
<!-条件2为真时执行的代码 -->。
<#else>。
<!-条件都不满足时执行的代码 -->。
</#if>。
4. 循环语句:FTL提供了`<#list>`标签用于循环遍历集合或数组。
例如: <#list collection as item>。
<!-循环体中的代码 -->。
</#list>。
其中,`collection`是要遍历的集合或数组,`item`是当前迭代的元素。
5. 宏定义:FTL支持宏定义,可以使用`<#macro>`标签定义宏,并使用`<@>`语法调用宏。
例如:<#macro myMacro arg1 arg2>。
<!-宏的代码 -->。
</#macro>。
<@myMacro arg1=value1 arg2=value2/>。
Freemarker是一个强大的模板引擎,常用于网页模板、配置文件等场景。
在Freemarker中,<#if> 是一个条件指令,用于在模板中实现条件判断。
以下是<#if>指令的基本用法:html复制代码<#if expression><!-- 这里是当表达式为真时的内容 --></#if>其中,expression 是一个条件表达式,当其值为真时,执行<#if>和</#if>之间的内容。
以下是一个示例:html复制代码<#if user != null><p>Hello, ${}!</p></#if>在上面的示例中,如果 user 不为 null,则输出一个包含问候语的段落。
如果 user 为 null,则不会输出任何内容。
除了简单的比较外,<#if>指令还支持更复杂的条件判断,例如逻辑运算符(AND、OR)和函数调用。
例如:html复制代码<#if (price > 100 && discount == true)><p>This product is on sale!</p></#if>在上面的示例中,如果产品的价格大于100且存在折扣,则输出一个销售提示。
需要注意的是,<#if>指令只能包含一个表达式,并且不支持嵌套。
如果需要嵌套判断,可以使用<#elseif>和<#else>指令。
例如:html复制代码<#if condition1><!-- 这里是当 condition1 为真时的内容 --></#if><#elseif condition2><!-- 这里是当 condition2 为真时的内容 --></#else><!-- 这里是当两个条件都不满足时的内容 --> </#if>。
1、快速入门(1)模板+数据模型=输出 模板+数据模型= FreeMarker 基于设计者和程序员是具有不同专业技能的不同个体的观念 他们是分工劳动的:设计者专注于表示——创建 HTML 文件、图片、Web 页面的其它 可视化方面;程序员创建系统,生成设计页面要显示的数据 经常会遇到的问题是:在 Web 页面(或其它类型的文档)中显示的信息在设计页面 时是无效的,是基于动态数据的 在这里,你可以在 HTML(或其它要输出的文本)中加入一些特定指令,FreeMarker 会在输出页面给最终用户时,用适当的数据替代这些代码 下面是一个例子:<html> <head> <title>Welcome!</title> </head> <body> <h1>Welcome${user}!</h1> <p>Our latest product: <a href="${latestProduct.url}">${}</a>! </body> </html>这个例子是在简单的 HTML 中加入了一些由${…} ${…}包围的特定代码,这些特定代码是 ${…} FreeMarker 的指令,而包含 FreeMarker 的指令的文件就称为模板(Template) 至于 user、latestProduct.url 和 来自于数据模型(data model) 数据模型由程序员编程来创建,向模板提供变化的信息,这些信息来自于数据库、 文件,甚至于在程序中直接生成 模板设计者不关心数据从那儿来,只知道使用已经建立的数据模型 下面是一个可能的数据模型:(root) | +- user = "Big Joe" | +- latestProduct | +- url = "products/greenmouse.html" |+- name = "green mouse"数据模型类似于计算机的文件系统,latestProduct 可以看作是目录,而 user、url 和 name 看作是文件,url 和 name 文件位于 latestProduct 目录中(这只是一个比喻, 实际并不存在) 当 FreeMarker 将上面的数据模型合并到模板中,就创建了下面的输出:<html> <head> <title>Welcome!</title> </head> <body> <h1>WelcomeBig Joe!</h1> <p>Our latest product: <a href="products/greenmouse.html">green mouse</a>! </body> </html>(2)数据模型 典型的数据模型是树型结构,可以任意复杂和深层次,如下面的例子:(root) | +- animals | | | | | | | | | | | | | | | +- elephant | | | +- price = 5000 | +- size = "large" | | | +- mouse | | | +- price = 50 | +- size = "small"| | | | | | || +- python | +- size = "medium" | +- price = 4999+- test = "It is a test" | +- whatnot | +- because = "don't know"类似于目录的变量称为 hashes hashes,包含保存下级变量的唯一的查询名字 类似于文件的变量称为 scalars scalars,保存单值 scalars 保存的值有两种类型:字符串(用引号括起,可以是单引号或双引号)和 数字(不要用引号将数字括起,这会作为字符串处理) 对 scalars 的访问从 root 开始,各部分用“.”分隔,如 animals.mouse.price . 另外一种变量是 sequences sequences,和 hashes 类似,只是不使用变量名字,而使用数字索 引,如下面的例子:(root) | +- animals | | | | | | | | | | | +- (1st) | | | | | | | +- (2nd) | +- name = "mouse" | +- size = "small" | +- price = 50| | | | | | | | | | | | | | || | | | | | || +- name = "elephant" | +- size = "large" | +- price = 5000+- (3rd) | +- name = "python" | +- size = "medium" | +- price = 4999+- whatnot | +- fruits | +- (1st) = "orange" | +- (2nd) = "banana"这种对 scalars 的访问使用索引,如 animals[0].name (3)模板 在 FreeMarker 模板中可以包括下面三种特定部分: ${…}:称为 interpolations,FreeMarker 会在输出时用实际值进行替代 FTL 标记(FreeMarker 模板语言标记) :类似于 HTML 标记,为了与 HTML 标记区 分,用#开始(有些以@开始,在后面叙述) 注释:包含在<#--和-->(而不是<!--和-->)之间 下面是一些使用指令的例子: if 指令<#if animals.python.price < animals.elephant.price> Pythons are cheaper than elephants today.<#else> Pythons are not cheaper than elephants today. </#if>list 指令<p>We have these animals: <table border=1> <tr><th>Name<th>Price <#list animals as being> <tr><td>${}<td>${being.price} Euros </#list> </table>输出为:<p>We have these animals: <table border=1> <tr><th>Name<th>Price <tr><td>mouse<td>50 Euros <tr><td>elephant<td>5000 Euros <tr><td>python<td>4999 Euros </table>include 指令<html> <head> <title>Test page</title> </head> <body> <h1>Test page</h1> <p>Blah blah... <#include "/copyright_footer.html"> </body> </html>一起使用指令<p>We have these animals: <table border=1> <tr><th>Name<th>Price <#list animals as being> <tr> <td> <#if being.size = "large"><b></#if> ${} <#if being.size = "large"></b></#if> <td>${being.price} Euros </#list> </table>2、数据模型(1)基础 在快速入门中介绍了在模板中使用的三种基本对象类型:scalars、hashes 和 sequences,其实还可以有其它更多的能力: scalars:存储单值 hashes:充当其它对象的容器,每个都关联一个唯一的查询名字 sequences:充当其它对象的容器,按次序访问 方法:通过传递的参数进行计算,以新对象返回结果 用户自定义 FTL 标记:宏和变换器 通常每个变量只具有上述的一种能力,但一个变量可以具有多个上述能力,如下面 的例子:(root) | +- mouse = "Yerri" | +- age = 12 | +- color = "brown">mouse 既是 scalars 又是 hashes,将上面的数据模型合并到下面的模板:${mouse} ${mouse.age} <#-- use mouse as scalar --> <#-- use mouse as hash -->${mouse.color} <#-- use mouse as hash -->输出结果是:Yerri 12 brown(2)Scalar 变量 Scalar 变量存储单值,可以是: 字符串:简单文本,在模板中使用引号(单引号或双引号)括起 数字:在模板中直接使用数字值 日期: 存储日期/时间相关的数据, 可以是日期、 时间或日期-时间 (Timestamp) ; 通常情况,日期值由程序员加到数据模型中,设计者只需要显示它们 布尔值:true 或 false,通常在<#if …>标记中使用 hashes、 (3)hashes、sequences 和集合 有些变量不包含任何可显示的内容,而是作为容器包含其它变量,者有两种类型: hashes:具有一个唯一的查询名字和它包含的每个变量相关联 sequences:使用数字和它包含的每个变量相关联,索引值从0开始 集合变量通常类似 sequences,除非无法访问它的大小和不能使用索引来获得它的 子变量;集合可以看作只能由<#list …>指令使用的受限 sequences (4)方法 方法变量通常是基于给出的参数计算值 下面的例子假设程序员已经将方法变量 avg 放到数据模型中, 用来计算数字平均值:The average of 3 and 5 is: ${avg(3, 5)} The average of 6 and 10 and 20 is: ${avg(6, 10, 20)} The average of the price of python and elephant is: ${avg(animals.python.price, animals.elephant.price)}(5)宏和变换器 宏和变换器变量是用户自定义指令(自定义 FTL 标记) ,会在后面讲述这些高级特性 (6)节点 节点变量表示为树型结构中的一个节点,通常在 XML 处理中使用,会在后面的专门 章节中讲述3 、模 板(1)整体结构 模板使用 FTL(FreeMarker 模板语言)编写,是下面各部分的一个组合: 文本:直接输出 Interpolation:由${和},或#{和}来限定,计算值替代输出 FTL 标记:FreeMarker 指令,和 HTML 标记类似,名字前加#予以区分,不会输 出 注释:由<#--和-->限定,不会输出 下面是以一个具体模板例子:<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>${} for ${being.price} Euros[BR] </#list>[BR] </ul>[BR] </body>[BR] </html>[BR]是用于换行的特殊字符序列 注意事项: 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)指令 在 FreeMarker 中,使用 FTL 标记引用指令 有三种 FTL 标记,这和 HTML 标记是类似的: 开始标记:<#directivename parameters> 结束标记:</#directivename> 空内容指令标记:<#directivename parameters/> 有两种类型的指令:预定义指令和用户定义指令 用户定义指令要使用@替换#,如<@mydirective>...</@mydirective>(会在后面讲述) FTL 标记不能够交叉,而应该正确的嵌套,如下面的代码是错误的:<ul> <#list animals as being> <li>${} for ${being.price} Euros <#if use = "Big Joe"> (except for you) </#list> </#if> <#-- WRONG! --> </ul>如果使用不存在的指令,FreeMarker 不会使用模板输出,而是产生一个错误消息 FreeMarker 会忽略 FTL 标记中的空白字符,如下面的例子:<#list[BR] animals being[BR] >[BR] ${} for ${being.price} Euros[BR] </#list > as[BR]但是,<、</和指令之间不允许有空白字符 (3)表达式 直接指定值 字符串 使用单引号或双引号限定 如果包含特殊字符需要转义,如下面的例子:${"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 /r /t /b /f /l /g /a /{ /xCode 含义 双引号(u0022) 单引号(u0027) 反斜杠(u005C) 换行(u000A) Return (u000D) Tab (u0009) Backspace (u0008) Form feed (u000C) < > & { 4位16进制 Unicode 代码有一类特殊的字符串称为 raw 字符串,被认为是纯文本,其中的/和{等不 具有特殊含义,该类字符串在引号前面加 r,下面是一个例子:${r"${foo}"} ${r"C:/foo/bar"}输出的结果是:${foo} C:/foo/bar数字 直接输入,不需要引号 精度数字使用“.”分隔,不能使用分组符号 . 目前版本不支持科学计数法,所以“1E3”是错误的 不能省略小数点前面的0,所以“.5”是错误的 数字8、+8、08和8.00都是相同的 布尔值 true 和 false,不使用引号 序列 由逗号分隔的子变量列表,由方括号限定,下面是一个例子:<#list["winter", "spring", "summer", "autumn"] as x>${x} </#list>输出的结果是:winter spring summer autumn列表的项目是表达式,所以可以有下面的例子:[2 + 2, [1, 2, 3, 4], "whatnot"]可以使用数字范围定义数字序列,例如2..5等同于[2, 3, 4, 5],但是更 有效率,注意数字范围没有方括号 可以定义反递增的数字范围,如5..2 散列(hash) 由逗号分隔的键/值列表,由大括号限定,键和值之间用冒号分隔,下面是 一个例子:{"name":"green mouse", "price":150}键和值都是表达式,但是键必须是字符串 获取变量 顶层变量:${variable},变量名只能是字母、数字、下划线、$、@和#的组合, 且不能以数字开头 从散列中获取数据 可以使用点语法或方括号语法,假设有下面的数据模型:(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"]使用点语法,变量名字有顶层变量一样的限制,但方括号语法没有该限制, 因为名字是任意表达式的结果 从序列获得数据:和散列的方括号语法语法一样,只是方括号中的表达式值必 须是数字;注意:第一个项目的索引是0 0 序列片断:使用[startIndex..endIndex] [startIndex..endIndex]语法,从序列中获得序列片断(也是 [startIndex..endIndex] 序列) ;startIndex 和 endIndex 是结果为数字的表达式 特殊变量:FreeMarker 内定义变量,使用.variablename 语法访问 .variablename 字符串操作 Interpolation(或连接操作) 可以使用${..} ${..}(或#{..} #{..})在文本部分插入表达式的值,例如: ${..} #{..}${"Hello ${user}!"} ${"${user}${user}${user}${user}"}可以使用+操作符获得同样的结果 +${"Hello " + user + "!"} ${user + user + user + user}${..}只能用于文本部分,下面的代码是错误的: ${..}<#if ${isBig}>Wow!</#if> <#if "${isBig}">Wow!</#if>应该写成:<#if isBig>Wow!</#if>子串 例子(假设 user 的值为“Big Joe”) :${user[0]}${user[4]} ${user[1..4]}结果是(注意第一个字符的索引是0) :BJ ig J序列操作 连接操作:和字符串一样,使用+,下面是一个例子: +<#list ["Joe", "Fred"] + ["Julia", "Kate"] as user>- ${user} </#list>输出结果是:- Joe - Fred - Julia - Kate散列操作 连接操作:和字符串一样,使用+,如果具有相同的 key,右边的值替代左边的 + 值,例如:<#assign ages = {"Joe":23, "Fred":25} + {"Joe":30, "Julia":18}> - Joe is ${ages.Joe} - Fred is ${ages.Fred} - Julia is ${ages.Julia}输出结果是:- Joe is30 - Fred is 25 - Julia is 18算术运算 +、-、×、/、%,下面是一个例子:${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比较操作符 使用=(或==,完全相等)测试两个值是否相等,使用!= 测试两个值是否不相 等 =和!=两边必须是相同类型的值,否则会产生错误,例如<#if 1 = "1">会引起 错误 Freemarker 是精确比较,所以对"x"、"x "和"X"是不相等的 对数字和日期可以使用<、<=、>和>=,但不能用于字符串 由于 Freemarker 会将>解释成 FTL 标记的结束字符, 所以对于>和>=可以使用括 号来避免这种情况,例如<#if (x > y)> 另一种替代的方法是,使用 lt、lte、gt 和 gte 来替代<、<=、>和>= 逻辑操作符 &&(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>内建函数 内建函数的用法类似访问散列的子变量,只是使用“?”替代“.”,下面列出 ? . 常用的一些函数 字符串使用的:html:对字符串进行 HTML 编码 cap_first:使字符串第一个字母大写 lower_case:将字符串转换成小写 upper_case:将字符串转换成大写 trim:去掉字符串前后的空白字符 序列使用的: size:获得序列中元素的数目 数字使用的: int:取得数字的整数部分(如-1.9?int 的结果是-1) 例子(假设 test 保存字符串"Tom & Jerry") :${test?html} ${test?upper_case?html}输出结果是:Tom & Jerry TOM & JERRY操作符优先顺序 操作符组 后缀 一元 内建 乘法 加法 关系 相等 逻辑 and 逻辑 or 数字范围 操作符 [subvarName] [subStringRange] . (methodParams) +expr、-expr、! ? *、 /、% +、<、>、<=、>=(lt、lte、gt、gte) ==(=) 、!= && || ..(4)Interpolation Interpolation 有两种类型: 通用 Interpolation:${expr} 数字 Interpolation:#{expr}或#{expr; format} 注意:Interpolation 只能用于文本部分 通用 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数字 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} #{y; M2} #{x; m1} #{y; m1} <#-- 2.58 --> <#-- 4 --><#-- 2.6 --> <#-- 4.0 -->#{x; m1M2} <#-- 2.58 --> #{y; m1M2} <#-- 4.0 -->4、杂项(1)用户定义指令 宏和变换器变量是两种不同类型的用户定义指令,它们之间的区别是宏是在模板 中使用 macro 指令定义,而变换器是在模板外由程序定义,这里只介绍宏 基本用法 宏是和某个变量关联的模板片断, 以便在模板中通过用户定义指令使用该变量, 下面是一个例子:<#macrogreet> <font size="+2">Hello Joe!</font> </#macro>作为用户定义指令使用宏变量时,使用@替代 FTL 标记中的#<@greet></@greet>如果没有体内容,也可以使用:<@greet/>参数 在 macro 指令中可以在宏变量之后定义参数,如:<#macro greetperson> <font size="+2">Hello ${person}!</font> </#macro>可以这样使用这个宏变量:<@greetperson="Fred"/> and <@greet person="Batman"/>输出结果是:<font size="+2">HelloFred!</font> and <font size="+2">HelloBatman!</font>宏的参数是 FTL 表达式,所以下面的代码具有不同的意思:<@greet person=Fred/>这意味着将 Fred 变量的值传给 person 参数,该值不仅是字符串,还可以是其 它类型,甚至是复杂的表达式 宏可以有多参数,下面是一个例子:<#macro greetperson color> <font size="+2" color="${color}">Hello ${person}!</font> </#macro>可以这样使用该宏变量:<@greet person="Fred" color="black"/>其中参数的次序是无关的,因此下面是等价的:<@greet color="black" person="Fred"/>只能使用在 macro 指令中定义的参数,并且对所有参数赋值,所以下面的代码 是错误的:<@greet person="Fred" color="black" background="green"/> <@greet person="Fred"/>可以在定义参数时指定缺省值,如:<#macro greet personcolor="black"> <font size="+2" color="${color}">Hello ${person}!</font> </#macro>这样<@greet person="Fred"/>就正确了 宏的参数是局部变量,只能在宏定义中有效 嵌套内容 用户定义指令可以有嵌套内容, 使用<#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</tr></td></table><#nested>指令可以被多次调用,例如:<#macro do_thrice> <#nested> <#nested> <#nested> </#macro> <@do_thrice> Anything. </@do_thrice>输出结果:Anything. Anything. Anything.嵌套内容可以是有效的 FTL,下面是一个有些复杂的例子:<@border> <ul> <@do_thrice> <li><@greet person="Joe"/> </@do_thrice> </ul> </@border>输出结果:<table border=4 cellspacing=0 cellpadding=4><tr><td> <ul> <li><font size="+2">Hello Joe!</font><li><font size="+2">Hello Joe!</font><li><font size="+2">Hello Joe!</font></ul></tr></td></table>宏定义中的局部变量对嵌套内容是不可见的,例如:<#macro repeat count> <#local y = "test"> <#list 1..count as x> ${y} ${count}/${x}: <#nested> </#list> </#macro> <@repeat count=3>${y?default("?")} ${x?default("?")}${count?default("?")}</@repeat>输出结果:test 3/1: ? ? ? test 3/2: ? ? ? test 3/3: ? ? ?在宏定义中使用循环变量 用户定义指令可以有循环变量,通常用于重复嵌套内容,基本用法是:作为 nested 指令的参数传递循环变量的实际值,而在调用用户定义指令时,在<@…>开 始标记的参数后面指定循环变量的名字 例子:<#macro repeat count> <#list 1..count as x> <#nestedx, x/2, x==count> </#list> </#macro> <@repeat count=4; c, halfc, last> ${c}. ${halfc}<#iflast> Last!</#if> </@repeat>输出结果:1. 0.52. 1 3. 1.5 4. 2 Last!指定的循环变量的数目和用户定义指令开始标记指定的不同不会有问题 调用时少指定循环变量,则多指定的值不可见 调用时多指定循环变量,多余的循环变量不会被创建 (2)在模板中定义变量 在模板中定义的变量有三种类型: plain 变量:可以在模板的任何地方访问,包括使用 include 指令插入的模板, 使用 assign 指令创建和替换 局部变量:在宏定义体中有效,使用 local 指令创建和替换 循环变量:只能存在于指令的嵌套内容,由指令(如 list)自动创建;宏的参 数是局部变量,而不是循环变量 局部变量隐藏(而不是覆盖)同名的 plain 变量;循环变量隐藏同名的局部变量和 plain 变量,下面是一个例子:<#assign x = "plain"> 1. ${x} <#-- we see the plain var. here --> <@test/> 6. ${x} <#-- the value of plain var. was not changed --> <#list ["loop"] as x> 7. ${x} <#-- now the loop var. hides the plain var. --> <#assign x = "plain2"> <#-- replace the plain var, hiding does not mater here --> 8. ${x} <#-- it still hides the plain var. --> </#list> 9. ${x} <#-- the new value of plain var. --><#macro test> 2. ${x} <#-- we still see the plain var. here --> <#local x = "local"> 3. ${x} <#-- now the local var. hides it --> <#list ["loop"] as x> 4. ${x} <#-- now the loop var. hides the local var. --></#list> 5. ${x} <#-- now we see the local var. again --> </#macro>输出结果:1. plain 2. plain 3. local 4. loop 5. local 6. plain 7. loop 8. loop 9. plain2内部循环变量隐藏同名的外部循环变量,如:<#list ["loop 1"] as x> ${x} <#list ["loop 2"] as x> ${x} <#list ["loop 3"] as x> ${x} </#list> ${x} </#list> ${x} </#list>输出结果:loop 1 loop 2 loop 3 loop 2loop 1模板中的变量会隐藏(而不是覆盖)数据模型中同名变量,如果需要访问数据模型 中的同名变量,使用特殊变量 global,下面的例子假设数据模型中的 user 的值是 Big Joe:<#assign user = "Joe Hider"> ${user} <#-- prints: Joe Hider -->${er} <#-- prints: Big Joe -->(3)名字空间 通常情况,只使用一个名字空间,称为主名字空间 为了创建可重用的宏、 变换器或其它变量的集合 (通常称库) 必须使用多名字空间, , 其目的是防止同名冲突 创建库 下面是一个创建库的例子(假设保存在 lib/my_test.ftl 中) :<#macro copyright date> <p>Copyright (C) ${date} Julia Smith. All rights reserved. <br>Email: ${mail}</p> </#macro> <#assign mail = "jsmith@">使用 import 指令导入库到模板中,Freemarker 会为导入的库创建新的名字空 间,并可以通过 import 指令中指定的散列变量访问库中的变量:<#import "/lib/my_test.ftl" as my> <#assign mail="fred@"> <@my.copyright date="1999-2002"/> ${my.mail} ${mail}输出结果:<p>Copyright (C) 1999-2002 Julia Smith. All rights reserved. <br>Email: jsmith@</p> jsmith@ fred@可以看到例子中使用的两个同名变量并没有冲突,因为它们位于不同的名字空间 可以使用 assign 指令在导入的名字空间中创建或替代变量,下面是一个例子:<#import "/lib/my_test.ftl" as my> ${my.mail}<#assign mail="jsmith@"in my> ${my.mail}输出结果:jsmith@ jsmith@数据模型中的变量任何地方都可见,也包括不同的名字空间,下面是修改的库:<#macro copyright date> <p>Copyright (C) ${date} ${user}. All rights reserved.</p> </#macro> <#assign mail = "${user}@">假设数据模型中的 user 变量的值是 Fred,则下面的代码:<#import "/lib/my_test.ftl" as my> <@my.copyright date="1999-2002"/> ${my.mail}输出结果:<p>Copyright (C) 1999-2002Fred. All rights reserved.</p> Fred@。
FreeMa rker学习1(Ft l)<# ... > 中存放所有f reema ker的内容,之外的内容全部原样输出。
<@ ... />是函数调用两个定界符内的内容中,第一个符号表示指令或者函数名,其后的跟随参数。
freem aker提供的控制包括如下:<#ifcondi tion><#els eif c ondit ion><#else></#i f> 条件判断<#listhash_or_se q asvar></#lis t> 遍历hash表或者col lecti on(fr eemak er称作s equen ce)的成员<#m acronameparam1 par am2 ... ><#nest ed pa ram></#mac ro> 宏,无返回参数<#f uncti on na me pa ram1param2><#r eturn val></#fu nctio n>函数,有返回参数var?membe r_fun ction(...)用函数对var进行转换,fr eemak er称为b uild-ins。
实际内部实现类似mem ber_f uncti on(va r, ...)st ringA[M .. N] 取子字符串,类似sub strin g(str ingA, M, N){ke y:val ue, k ey2:v alue2 ...}直接定义一个has h表[i tem0, item1, it em2 ...] 直接定义一个序列ha sh0[k ey0]存取has h表中ke y对应的元素seq0[5]存取序列指定下标的元素<@f uncti on1 p aram0 para m1 ... />调用函数f uncti on1<@macr o0 pa ram0param1 ; n est_p aram0 nest_para m1 ...> ne st_bo dy </@mac ro >调用宏,并处理宏的嵌套<#a ssign var= val ue >定义变量并初始化<#loca l var = va lue>在 mac ro 或者 func tion中定义局部变量并初始化<#g lobal var= val ue >定义全局变量并初始化${va r} 输出并替换为表达式的值<#vis it xm lnode> 调用m acro匹配xmln ode本身及其子节点<#re curse xmln ode>调用mac ro匹配x mlnod e的子节点<#i f con ditio n > </#if><#l ist S equen ceVar as v ariab le >repea tThis </#l ist><#inc lude"/cop yrigh t_foo ter.h tml">一个f tl标记不能放在另外一个ftl标记里面,但是注释标记能够放在ftl标记里面。
一、准备工作1.1 下载文件可以从/站点下载最新的freemarker.jar包(目前最新版本是2.3.18)与eclipse插件(最新版本是0.9.14)。
1.2 安装eclipse插件将下载来的eclipse插件解压缩到本地磁盘,更改hudson.freemarker_ide_0.9.14文件夹中的freemarker-2.3.6.jar文件更改成最新版本的freemarker-2.3.18.jar,并且将META-INF/MANIFEST.MF文件中的Bundle-ClassPath属性值修改为freemarker-2.3.18.jar。
最后将hudson.freemarker_ide_0.9.14放到eclipse的plugins目录中,完成eclipse 插件的安装。
1.3 freemarker文档下载从/官方网站中下载帮助文档(也有中文的手册)二、freemarker的使用2.1 简介2.1.1 FTL tag标签由于freemarker tag标签是属于freemarker的指令,它们仅仅是freemarker 处理过程中的信息,而不会输出到页面上,所以它们与html标签有一些区别。
这些标签都是以#号开头,如<#import "/public/work_public.ftl" as public>。
但用户自定义的标签是以@符号开头,如在freemarker中使用struts标签:<@s.if test="results!=null&&results.size()!=0">注意FTL标签不可以在其他FTL标签和插值中使用(注释可以在FTL标签和插值中使用,因为它在解析时,整个注释都将抛弃,不会影响具体代码),如下面这样就是一个错误的写法:<#if <#include 'foo'>='bar'>...</#if>2.1.2 注释freemarker的文档注释与html相似,但它是以<#--和-->来分割的。
任何介于这两个分隔符(包含分隔符本身)之间内容会被freemarker忽略,就不会输出出来了。
其他任何不是FTL 标签,插值或注释的内容将被视为静态文本,这些东西就不会被freemarker所解析,会被按照原样输出出来。
2.1.3 引入外部文件如果模板文件使用了struts2标签,则可以这样调用:<@s.include value="/public/publis.jsp" />在freemarker版本2.3.15及其以后都可以使用如下方式引入外部文件:<@include_page path="/public/publis.jsp"/>或者使用:<#include "/copyright_footer.html">的方式引入外部文件。
注意:<#include "/copyright_footer.html">是为了包含freemarker模板而不会牵涉到servlet容器,使用<#include..>包含的模板和包含它的模板共享模板处理状态,比如数据模型和模板语言变量,而<@include_page..>开始一个独立的HTTP请求处理。
对于js、css等其他外部资源的引入方式不变,依旧是类似:<script type="text/javascript" src="./public/work_public.js"> </script>注意该路径与ftl文件路径地址无关,而是真正的访问路径。
2.2 freemarker与spring的集成将freemarker.jar包放到web工程的lib目录中,并在web.xml文件中加入如下的代码:<servlet><servlet-name>freemarker</servlet-name><servlet-class>freemarker.ext.servlet.FreemarkerServlet</servlet-class><init-param><param-name>TemplatePath</param-name><param-value>/</param-value></init-param><init-param><param-name>NoCache</param-name><param-value>true</param-value></init-param><init-param><param-name>ContentType</param-name><param-value>text/html</param-value></init-param><init-param><param-name>template_update_delay</param-name><param-value>0</param-value></init-param><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>freemarker</servlet-name><url-pattern>*.ftl</url-pattern></servlet-mapping>2.3 freemarker中使用struts标签由于freemarker本身的标签在变量名不存在或变量为null的情况下处理比较复杂(它不允许出现这两种情况的变量,在使用可能出现变量名不存在或null值的变量时,首先需要判断该变量是否存在,否则当出现这两种情况时,freemarker会报解析错误,这将直接在最终生成的html页面中显示出来),所以当不能确定该值是否存在时,可以在freemarker中使用struts标签,它没有这类的问题(freemarker也提供了判断一个值是否为空的情况,如${list!}或者使用<#if指令来判断指定的变量是否存在:<#if list?exists && list!=null></#if>或<#if list!=null></#if>)。
首先将struts2-core.jar包中的struts-tags.tld文件加入到WEB-INF/tags 文件夹中然后在需要加入struts2标签的freemarker的ftl文件头部加入如下语句:<#assign s=JspTaglibs["/WEB-INF/tags/struts-tags.tld"]>注意:与在jsp中使用标签类似,每个使用ftl文件的头部都需要加上上述#assign 标签,在公共文件中加入上述#assign后,其他引用该公共文件的ftl文件中若想使用struts标签的话,也是需要再次加入的。
例如:strtus2的判断语句在freemarker文件中的使用方式如下:<@s.if test="results!=null&&results.size()!=0">${public_count_data}<@s.property value="results.size()"/> </@s.if><@s.else>${public_none_data}</@s.else>2.4 变量在freemarker中变量是区分大小写的,如list就不能写成List。
定义变量使用assign标签,具体使用如:<#assign test_string="字符串">,也可以使用如<#assign test_string_array=["字符串1","字符串2","字符串3"]>的方式来定义数组(或列表)可以使用如下两种方式在页面上显示一个变量:struts2的property标签<@s.property value="#er_name"/>freemarker的${}标签${myobj} myobj可以是后台传递的变量,也可以是在模板文件中定义的变量处理不存在的变量由于直接使用freemarker标签会经常碰到不存在的变量或变量值为null的情况,而freemarker则不支持使用这样的变量,因此在可能出现不存在的变量或变量值为null 时,首先需要判断该变量是否存在(是否不为null)。
如:${RequestParameters['locale']!'zh_CN',这时,如果URL参数中的locale属性不存在,则返回'zh_CN'这段字符串,如果存在,则'zh_CN'将不起任何作用。
或者使用<#if user??><h1>Welcome ${user}!</h1></#if>判断指定的变量user 是否存在(??需要结合if使用)。
2.5 列表一般界面上可以使用两种形式来循环列表,一种是使用struts2中的iterator标签,另一种是使用freemarker的list标签。
下面就这两种标签做一些描述:struts2的iterator标签<@s.iterator id="user" value="results" status="index"> <@s.property value="#er_name"/></@s.iterator>说明:value="results"指的是从后台action中传递过来的列表results,即在action 中定义一个results的变量,然后定义一个get方法即可在前台页面中使用。