freemarker中文手册

合集下载

ftl编辑器(freemarker)的使用和说明

ftl编辑器(freemarker)的使用和说明

一、准备工作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相似,但它是以<#--和-->来分割的。

freemaeker全面教程

freemaeker全面教程

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 &amp; Jerry TOM &amp; 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常用指令

freemarker常用指令

freemarker常用指令Freemarker常用指令一、概述Freemarker是一种Java模板引擎,常用于生成动态网页、电子邮件和其他文本格式。

它使用简单的模板语言来定义模板,并通过替换模板中的占位符来生成最终的文本输出。

本文将介绍Freemarker 常用指令,帮助读者更好地理解和使用Freemarker。

二、输出指令1. #-- 输出文本 --#这是Freemarker中最基本的输出指令,用于直接输出文本内容。

例如:#-- 这是一段文本 --#。

2. ${expression}这是Freemarker中最常用的输出指令,用于输出表达式的值。

表达式可以是变量、方法调用或其他Freemarker支持的表达式。

例如:${name}表示输出变量name的值。

3. #if-#else-#elseif-#end这是Freemarker中的条件判断指令,用于根据条件来输出不同的内容。

可以使用if、else if和else来定义多个条件分支。

例如:#if (score > 90)优秀#elseif (score > 80)良好#else需要努力4. #list-#items-#sep-#end这是Freemarker中的循环指令,用于遍历一个集合并输出其中的元素。

可以使用items定义要遍历的集合,使用sep定义元素之间的分隔符。

例如:#list users as user${}#sep,#end三、变量指令1. #assign这个指令用于定义一个局部变量,并为其赋值。

例如:#assign count = 10。

2. #global这个指令用于定义一个全局变量,并为其赋值。

全局变量可以在整个模板中使用。

例如:#global count = 10。

3. #local这个指令用于在指定的作用域中定义一个局部变量,并为其赋值。

作用域可以是当前模板、当前循环或当前条件分支。

例如:#local count = 10。

常用freemarker使用文档

常用freemarker使用文档

常⽤freemarker使⽤⽂档设置价格格式<#setting number_format = "currency" /><#assign price = 42 />${price}-${price?string}--${price?string.number}---${price?string.currency}----${price?string.percent}-----输出结果:设置价格格式¥42.00- ¥42.00-- 42--- ¥42.00---- 4,200%-----设置⽇期格式<#assign lastUpdated = "2009-01-07 15:05"?datetime("yyyy-MM-dd HH:mm") />${lastUpdated?string("yyyy-MM-dd HH:mm:ss zzzz")};${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')'")};${lastUpdated?string.short};${lastUpdated?string.long};输出结果:2009-01-07 15:05:00 中国标准时间;2009-01-07 15:05:00 中国标准时间;星期三,⼀⽉ 7,09;星期三,⼀⽉ 07,2009,03:05:00 下午 (CST);09-1-7 下午3:05;2009年1⽉7⽇下午03时05分00秒;判断布尔<#assign foo=true />${foo?string("是foo","⾮foo")}输出结果:是foo集合<#assign mynums=[11,12,13,14,15,16,17,18,19]/><#list mynums as mn>${mn}<br></#list>输出结果:(¥是默认格式数字)¥12.00¥13.00¥14.00¥15.00¥16.00¥17.00¥18.00¥19.00拆分序列<#-- 这⾥是将mynums序列中下标从3到6之间的元素拆分出来,组成⼀个新的序列 --> <#assign mynum01=mynums[3..6]/><#list mynum01 as mn01>${mn01}</#list>输出结果:¥14.00¥15.00¥16.00¥17.00字符串的拆分(截取字符串)<br>${"你好,你来了吗今天看书了吗!"[0..8]}<br>你好,你来了吗今天...输出结果:你好,你来了吗今天你好,你来了吗今天...连续序列(即num01为完整集合不是拆分的)从55到58:注意此时若写成[55..58]或者[66..68]则会报错<#assign num01=55..58/><#list num01 as num>${num}</#list><#list 66..68 as num>${num}</#list>哈希表(Map)定义哈希表<#assign maps={"1":"张三","2":"李四"}>${maps["1"]}输出结果:张三<#--以下代码可以将map的key转换为相应的序列--><#assign keys=maps?keys><#list keys as key>${key}---${maps[key]}</#list>输出结果:1---张三2---李四<#assign users={"username":"张三","password":"123"}>${ername}---${users["password"]}输出结果:张三---123字符串操作a、字符串链接字符串连接有两种语法A、使⽤${..}(或#{..})在字符串常量部分插⼊表达式的值,从⽽完成字符串连接B、直接使⽤连接运算符(+)来连接字符串使⽤第⼀种语法来连接字符串${"Hello,${user}!"}第⼆种使⽤连接符号来连接字符串${"Hello,"+user+"!"};值的注意的是,${..}只能⽤于⽂本部分,因此,下⾯的代码是错误的:<#if ${isBig}>Wow!</#if><#if "${isBig}">Wow!</#if>应该写成:<#if isBig>Wow!</#if>集合连接运算符这⾥所说的集合连接运算时将两个集合连接成⼀个新的集合,连接集合的运算符是+,例如<#list ["星期⼀"," 星期⼆","星期三"]+["星期四","星期五"] as x>${x}</#list>Map连接运算符Map对象的连接运算也是将两个Map对象连接成⼀个新的Map对象,Map对象的连接运算符是+。

freemarker(ftl)模板开发常用方法(迭代,数值格式化等)

freemarker(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 内置函数 数字、字符串、日期格式化freemarker

Freemarker 内置函数 数字、字符串、日期格式化freemarker

Freemarker 内置函数数字、字符串、日期格式化freemarker一、Sequence的内置函数1. sequence?first 返回sequence的第一个值。

2. sequence?last 返回sequence的最后一个值。

3. sequence?reverse 将sequence的现有顺序反转,即倒序排序4. sequence?size 返回sequence的大小5. sequence?sort 将sequence中的对象转化为字符串后顺序排序6. sequence?sort_by(value) 按sequence中对象的属性value进行排序二、Hash的内置函数1. hash?keys 返回hash里的所有key,返回结果为sequence2. hash?values 返回hash里的所有value,返回结果为sequence例如:<#assign user={“name”:“hailang”, “sex”:“man”}><#assign keys=user?keys><#list keys as key>${key}=${user[key]}</#list>三、操作字符串函数1. substring(start,end)从一个字符串中截取子串start:截取子串开始的索引,start必须大于等于0,小于等于endend: 截取子串的长度,end必须大于等于0,小于等于字符串长度,如果省略该参数,默认为字符串长度。

例子:${…str‟?substring(0)},结果为str${…str‟?substring(1)},结果为tr${…str‟?substring(2)},结果为r${…str‟?substring(3)},结果为${…str‟?substring(0,0)},结果为${…str‟?substring(0,1)},结果为s${…str‟?substring(0,2)},结果为st${…str‟?substring(0,3)},结果为str2. cap_first 将字符串中的第一个单词的首字母变为大写。

freemarker中文手册文档

freemarker中文手册文档

FreeMarkerFreeMarker JavaFreeMarker HTML Web MVC FreeMarker Java FreeMarkerFreeMarker Web WebFreeMarker HTTP Servlet FreeMarker WebFreeMarker Model2 Struts JSPFreeMarker1HTML XML RTF JavaServletEmail Web Web2include if/elseif/elseHTML3FreeMarker Java JavaJavaBean XML SQL4 WebWeb HTMLModel2 Web JSPJSPMVC5UNICODEUS6 XML<#recurse> <#visit> 2.3 XMLXMLFreeMarker (1)11 + =FreeMarker—— HTML WebWebHTML 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 latestProductFreeMarker <html><head><title>Welcome!</title></head><body><h1>Welcome Big Joe!</h1><p>Our latest product:<a href="products/greenmouse.html">green mouse</a>!</body></html>2(root)|+- animals| || +- mouse| | || | +- size = "small" | | || | +- price = 50| || +- elephant| | || | +- size = "large" | | || | +- price = 5000| || +- python| || +- size = "medium" | || +- price = 4999|+- test = "It is a test"|+- whatnot|+- because = "don't know"hashesscalarsscalarsscalars root “. animals.mouse.pricesequences hashes(root)|+- animals| || +- (1st)| | || | +- name = "mouse"| | || | +- size = "small"| | || | +- price = 50| || +- (2nd)| | || | +- name = "elephant" | | || | +- size = "large"| | || | +- price = 5000| || +- (3rd)| || +- name = "python"| || +- size = "medium"| || +- price = 4999|+- whatnot|+- fruits|+- (1st) = "orange"|+- (2nd) = "banana"scalars animals[0].name3FreeMarker${…} interpolations FreeMarkerFTL 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>FreeMarker (3)31FTL FreeMarkerInterpolation ${ } #{ }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}InterpolationFTL 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] ...2FreeMarker FTLFTL 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>FreeMarkerFreeMarker FTL <#list[BR]animals as[BR]being[BR]>[BR]${} for ${being.price} Euros[BR]</#list >< </3${"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: \\" (u0022)\' (u0027)\\ (u005C)\n (u000A)\r Return (u000D)\t Tab (u0009)\b Backspace (u0008)\f Form feed (u000C)\l<\g>\a&\{{\x Code4 16 Unicoderaw \ { r ${r"${foo}"}${r"C:\foo\bar"}${foo}C:\foo\bar“.“1E30 “.58 +8 08 8.00true false<#list ["winter", "spring", "summer", "autumn"] as x>${x}</#list>winterspringsummerautumn[2 + 2, [1, 2, 3, 4], "whatnot"]2..5 [2, 3, 4, 5]5..2hash/{"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"].namebook.author.["name"]book["author"]["name"][startIndex..endIndex] startIndex endIndexFreeMarker .variablenameInterpolation${..} #{..} ${"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]}BJig 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 is 30- Fred is 25- Julia is 18${x * x - 100}${x / 2}${12 % 10}x 5-752.52${3 * "5"} <#-- WRONG! -->+ ${3 + "5"}35int${(x/2)?int}${1.1?int}${1.999?int}${-1.1?int}${-1.999?int}x 5211-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 HTMLcap_firstlower_caseupper_casetrimsizeint -1.9?int -1 test "Tom & Jerry"${test?html}${test?upper_case?html}Tom &amp; JerryTOM &amp; JERRY[subvarName] [subStringRange]. (methodParams) +expr -expr !?* / %+ -< > <= >= lt lte gt gte== = !=and &&or ||..4 InterpolationInterpolationInterpolation ${expr}Interpolation #{expr} #{expr; format}InterpolationInterpolation#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.0042$42.004,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 TimeTue, Apr 8, '03Tuesday, April 08, 2003, 09:24:44 PM (PDT)#settingstring Interpolation<#assign foo=true/>${foo?string("yes", "no")}yesInterpolation #{expr; format} format mX XMX 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 -->FreeMarker (4)41macro<#macro greet><font size="+2">Hello Joe!</font></#macro>@ FTL #<@greet></@greet><@greet/>macro<#macro greet person><font size="+2">Hello ${person}!</font></#macro><@greet person="Fred"/> and <@greet person="Batman"/><font size="+2">Hello Fred!</font>and <font size="+2">Hello Batman!</font>FTL<@greet person=Fred/>Fred person<#macro greet person 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 person color="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><#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!2plain include assignlocallistplain 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 materhere -->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 1global user Big Joe<#assign user = "Joe Hider">${user} <#-- prints: Joe Hider -->${er} <#-- prints: Big Joe -->3lib/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-2002 Fred. All rights reserved.</p> Fred@。

FreeMarker使用手册

FreeMarker使用手册

FreeMarker思想模板在FreeMarker模板中可以包括下面三种特定部分:1.${..}:称为interpolations,FreeMarker会在输出时用实际值进行代替2.FTL标记(FreeMarker模板语言标记):类似于HTML标记,为了与HTML标记区分,用#开始(有些以@开始)3.注释:包含在<#--和-->之间数据模型典型的数据模型是树型结构,可以任意复杂和深层次:(root)|+- animals| || +- mouse| | || | +- size = "small"| | || | +- price = 50| || +- elephant| | || | +- size = "large"| | || | +- price = 5000| || +- python| || +- size = "medium"| || +- price = 4999|+- test = "It is a test"|+- whatnot|+- because = "don't know"${animals.elephant.price}另外一种变量是sequences,和hashes类似,只是不使用变量名字,而使用数字索引(root)|+- animals| || +- (1st)| | || | +- name = "mouse"| | || | +- size = "small"| | || | +- price = 50| || +- (2nd)| | || | +- name = "elephant"| | || | +- size = "large"| | || | +- price = 5000| || +- (3rd)| || +- name = "python"| || +- size = "medium"| || +- price = 4999|+- whatnot|+- fruits|+- (1st) = "orange"|+- (2nd) = "banana"${animals[1].name}FreeMarker基本语法注释语句<#-- 注释语句-->If语句●语法:<#if condition><#else></#if>●例子:1.boolean对象<% request.setAttribute("flag",true); %><#if flag>flag的值是True<#else>flag的值是false</#if>输出的结果:flag的值是True2.String对象<% request.setAttribute("str",”string”); %><#if str == “string” >str的值是string<#else>str的值是${str}</#if>输出的结果:str的值是string3.Number对象<% request.setAttribute("number",20); %><#if number == 20 >number的值是20<#else>number的值是${number}</#if>输出的结果:number的值是20<#if number gt 20 >number的值是大于20<#else>number的值是${number}</#if>(gt代表>号) 或者这样写( <#if (number > 20) >)输出的结果:number的值是大于204.自定义对象<% Student student = new Student();student.setName(“张三”);student.setAge(20);request.setAttribute(“student”,student);%>首先判断Student对象是否为空,再次输出Student对象的属性值<#if student?exists>学生名称:${}学生年龄:${student.age}<#else>Student对象是空值</#if>5.Map 、List对象<%Map map = new HashMap<String,Student>();List list = new ArrayList();Student student = new Student();student.setName(“张三”);student.setAge(20);list.add(student);map.put(“student”,student);request.setAttribute(“list”,list);request.setAttribute(“map”,map);%>首先判断对象是否为空,再次输出对象的属性值<#if list?exists && list?size != 0><#list list as student>学生名称:${}学生年龄:${student.age}</#list><#else>List对象是空的</#list><#if map?exists && map?size != 0><#list map?keys as students>输出map中的key的值:${students}Map对象中key必须是String类型,别的类型不支持<@assign stu = map[students]><#list stu as student >学生名称:${}学生年龄:${student.age}</#list><#else>Map对象是空的</#if>list语句●语法:<#list list as list_value></#list>●例子:Map 、List对象<%Map map = new HashMap<String,Student>();List list = new ArrayList();Student student = new Student();student.setName(“张三”);student.setAge(20);list.add(student);map.put(“student”,student);request.setAttribute(“list”,list);request.setAttribute(“map”,map);%>首先判断对象是否为空,再次输出对象的属性值<#if list?exists && list?size != 0><#list list as student>学生名称:${}学生年龄:${student.age}</#list><#else>List对象是空的</#list><#if map?exists && map?size != 0><#list map?keys as students>students_index:当前变量的索引值students_has_next: 是否存在下一个对象也可以使用<#break>指令跳出迭代输出map中的key的值:${students}Map对象中key必须是String类型,别的类型不支持<@assign stu = map[students]><#list stu as student >学生名称:${}学生年龄:${student.age}</#list><#else>Map对象是空的</#if><#list [“星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"] as days> ${days_index}list的索引位置<#if days_has_next>判断是否有下个值</#if><#if days == “星期四”><#break></#if></#list>switch语句语法:<#switch value><#case refValue1>语句<#break><#case refValue2>语句<#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>include语句●作用:类似于jsp的包含作用,用于包含指定页●语法:<#include filename[options]>filename:该参数指定被包含的模板文件options:该参数可以省略,指定包含时的选项,包含encoding和parse两个选项,其中encoding指定包含页面时所用的解码集,而parse指定被包含文件是否作为FTL文件来解析,省略默认True●例子:<#include “/html/index.html”> 、<#include “/template/one.ftl”>import语句●作用:用于导入FreeMarker模板中的所有变量,并将该变量放置在指定的Map对象中●语法:<#import “/lib/common.ftl” as com>说明:将导入/lib/common.ftl模板文件中的所有变量,将这些变量放置在一个名为com的Map对象中●例子:文件common.ftl中的内容:<#assign aa = “FreeMarKer”><#import “/lib/common.ftl” as com> ${com.aa}输出结果:FreeMarkernoparse语句●作用:指定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> 没有做处理setting语句●作用:用于设置FreeMarker的运行环境●语法:<#setting name = value> name的取值范围包含如下:locale:该选择指定该模板所用的国家/语言选择number_format:指定格式化输出数字的格式boolean_format:指定两个布尔值的语法格式,默认值是true,falsedate_fromat,time_format,datetimr_format:指定格式化输出日期的格式time_zone:设置格式化输出日期时所使用的时区url_escaping_charset:classic_compatible:●例子:<#setting locale = “en_US”><#setting number_format="0.##">${1.234}输出结果:1.23escape、noescape语句●作用:导致body区的插值都会被自动加上escape表达式,但不会影响字符串内的插值,只会影响body内出现的插值●语法:<#escape identitier as expression>….<#noescape>…..</#noescape></#escape>●例子:class User{private String name;pringvate String userName;private UserInfo userInfo;}Class UserInfo{private String idCardNo;private String telephone;private String mobile;private String email;private String address;private String resume;private Sex gendar;}Public enum Sex implements EnumI18n{MAIE(0,”el.enum.human.status.male”),FEMALE(1,”el.enum.human.status.female”),Private String i18n;Sex(String i18n){This.i18n = i18n;}Public String getI18n(){Return this.i18n;}}<#escape x as x?if_exists?html>用户名:${user?if_erName}<br>姓名:${'name'}<br><#escape xx as user?if_erInfo?if_exists[xx]><#noescape>性别:<#if user?if_erInfo?if_exists.gendar?if_exists.i18n?exists>${action.getText(erInfo.gendar.i18n)}</#if></#noescape>身份证:${'idCardNo'}<br>联系电话:${'telephone'}<br>手机:${'mobile'}<br>邮箱:${'email'}<br>地址:${'address'}<br>个人简介:${'resume'}<br></#escape></#escape>assign语句作用:为模板创建和替换顶层变量●语法:1. <#assign name=value [in namespacehash]>2. :<#assign name1=value1 name2=value2 ... nameN=valueN [in namespacehash]>capture tHis</#assign>●例子:<#assign xx = “assign”>${xx} 输出assign<#assign s=JspTaglibs["/WEB-INF/struts-tags.tld"]><#assign bb ><#list ["free","marker","freemarker"] as aa>${aa}</#list></#assign>${bb}输出结果:free marker freemarkermacro,newsted,return语句●语法:<#macro name param1 param2 …..paramN>…….<#nested loopvar1,loopvar2,…,loopvarN>……<#return>….</macro>描述:name : 是macro变量的名字Param1 … paramN:macro变量保存参数值的名称,可以有默认的参数值●例子:<#-- create the macro variable →<#macro test>Test text</#marco><#-- call the macro: -→<@test/> 输出结果:Test tex<#-- Macro 带着参数→<#macro test foo bar baaz>Test text , and the params : ${foo},${bar}, ${baaz}</#macro><#-- call the macro: →<@test foo = “a” bar = “b” baaz = 5*5-2/>输出结果:Test text ,and the params : a, b, 23<#-- macro 参数带有默认值→<#macro test foo bar=”bar” baaz = -1>Test text,and the params: ${foo} ,${bar} ,${baaz}</#macro><@test foo = “a”/><@test foo = “a” bar=”b”/>输出结果:Test text , and the params : a ,Bar,-1Test text , and the params : a , b, -1一个更复杂的例子<#macro list title items><p>${title?cap_first}:<ul><#list items as x><li>${x?cap_first}</#list></ul></#macro><@list items=["mouse", "elephant", "python"] title="Animals"/> 输出结果:<p>Animals:<ul><li>Mouse<li>Elephant<li>Python</ul>A macro with support for a variable number of named parameters:<#macro img src extra...><img src="/context${src?html}"<#list extra?keys as attr>${attr}="${extra[attr]?html}"</#list>></#macro><@img src="/images/test.png" width=100 height=50 alt="Test"/>输出结果:<img src="/context/images/test.png" alt="Test"height="50"width="100">nested 例子<#macro do_thrice><#nested 1><#nested 2><#nested 3></#macro><@do_thrice ; x>${x} Anything.</@do_thrice>输出结果:1 Anything.2 Anything.3 Anything.一个复杂的nested例子<#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> </@repeat>输出结果:1. 0.52. 13. 1.54. 2 Last!一个macro带有return的例子<#macro test>Test text<#return>Will not be printed.</#macro><@test/>输出结果:Test textt,lt,rt语句●语法:<#t> 去掉一行前后空格和换行<#lt> 去掉一行左边的空格<#rt> 去掉右边的空格和换行<#nt> 取消去掉空格和换行的效果●例子:--1 <#t>2<#t>3<#lt>45<#rt>6--输出结果:--1 2345 6--compress语句●语法:<#compress> …. </#compress> ●作用:去掉多余的空格和空行●例子:<#assign x = " moo \n\n "> (<#compress>1 2 3 4 5${moo}test onlyI said, test only</#compress>)输出结果:(1 2 3 4 5mootest onlyI said, test only)global语法●语法<#global name=value>or<#global name1=value1 name2=value2 ... nameN=valueN>or<#global name>capture this</#global>●说明:全局赋值语法,利用这个语法给变量赋值,那么这个变量在所有的namespace中是可见的,如果这个变量被当前的assign语法覆盖如<#global x=2> <#assign x=1> 在当前页面里x=2将被隐藏,或者通过${.global.x}来访问FreeMarker内置函数substring()作用:取字串${“FreeMarker”?substring(0,2)} 输出结果:Fr作用:求字串在原串中的位置${“FreeMarker”?index_of(“ee”)) 输出结果:2cap_first作用:第一个字母大写${“freeMarker”?cap_first} 输出结果:FreeMarkeruncap_first作用:第一个字母不大写$(“FreeMarker”?uncap_first) 输出结果:freeMarkercaptitalize作用:单词之间的首字母大写例子:${“green mouse”?captitalize}输出结果:Green Mousechop_linebreakdate(),time(),datetime()作用:以某个时间格式,输出时间的值例子:<#assign date_val = “10/25/1995”?date(“MM/dd/yyyy”)><#assign time_val = “15:05:30”?time(“HH:mm:ss”)><#assign datatime_val = “1995-10-25 03:05 PM"?datetime("yyyy-MM-dd hh:mm a")>输出结果:Oct 25, 19953:05:30 PMOct 25, 1995 3:05:00 PM作用:从字符串后面判断是否存在某个字符,返回true和false 例子:${“freemarker”?ends_with(“marker”)} true${“freemarker”?ends_with(“free”)} truehtmlgroupsj_string作用:在字符串引号前加”\”例子:<#assign beanName = …The “foo” bean.‟>${beanName?j_string} 输出结果:”The \”foo\” bean.”js_string作用:在字符串引号前加”\”例子:<#assign beanName = “The …foo‟ bean.”>${beanName?js_string} 输出结果:”The \‟foo\‟bean.”last_index_of()作用:求子串在原串最后出现的位置例子:${“freemarker”?last_index_of(“ar”)} 输出结果:5 length作用:字符串的长度例子:${“freemarker”?length} 输出结果:10lower_case作用:把大写字母转换成小写字母例子:${“FreeMARker”?lower_case} 输出结果:freemarke rleft_pad()注意:freemarker2.3以后的版本才出现作用:从左侧起填充字符例子:1.left_pad()只有一个参数时,默认空格填充,如果变量长度小于参数的长度填充空格,否则不填充[${""?left_pad(5)}][${"a"?left_pad(5)}][${"ab"?left_pad(5)}][${"abc"?left_pad(5)}][${"abcd"?left_pad(5)}][${"abcde"?left_pad(5)}][${"abcdef"?left_pad(5)}][${"abcdefg"?left_pad(5)}][${"abcdefgh"?left_pad(5)}]输出结果:[ ][ a][ ab][ abc][ abcd][abcde][abcdef][abcdefg][abcdefgh]2.如果left_pad()有两个参数,第一个参数是填充的数量,第二个参数是填充的字符[${""?left_pad(5, "-")}][${"a"?left_pad(5, "-")}][${"ab"?left_pad(5, "-")}][${"abc"?left_pad(5, "-")}][${"abcd"?left_pad(5, "-")}][${"abcde"?left_pad(5, "-")}]输出结果:[-----][----a][---ab][--abc][-abcd][abcde]right_pad()注意:freemarker2.3以后的版本才出现作用:从右侧填充字符串例子:参考left_pad() [${""?right_pad(5)}] [${"a"?right_pad(5)}] [${"ab"?right_pad(5)}] [${"abc"?right_pad(5)}] [${"abcd"?right_pad(5)}] [${"abcde"?right_pad(5)}] [${"abcdef"?right_pad(5)}] [${"abcdefg"?right_pad(5)}] [${"abcdefgh"?right_pad(5)}][${""?right_pad(8, ".oO")}] [${"a"?right_pad(8, ".oO")}] [${"ab"?right_pad(8, ".oO")}] [${"abc"?right_pad(8, ".oO")}] [${"abcd"?right_pad(8, ".oO")}]输出结果:[ ][a ][ab ][abc ][abcd ][abcde][abcdef][abcdefg][abcdefgh][.oO.oO.o][aoO.oO.o][abO.oO.o][abc.oO.o][abcdoO.o]contains()作用:判断一个集合是否存在某个对象例子:<#assign bb ><#list ["free","marker","freemarker"] as aa>${aa}</#list></#assign><#if bb?contains("marker")>包含了${bb}</#if>输出结果:包含了free marker freemarkermatchsnumberreplace()作用:替换字符串例子:${“this is the car”?replace(“car”,”freemarker”)} 输出结果:this is the freemarker rtfurlsplit()作用:分隔字符串例子:<#list "someMOOtestMOOtext"?split("MOO") as x>- ${x}</#list>输出结果:- some- test- textstarts_with()作用:判断是否存在字串,顺序是从左到右例子:${“FreeMarker”?starts_with(“ree”)} 输出结果:truestring()作用:例子:1.对数字类型的变量,默认的有四种格式:computer,currency,percent,number<#assign x=42>${x}${x?string} <#-- the same as ${x} -->${x?string.number}${x?string.currency}${x?string.percent}${x?puter}输出结果:424242$42.004,200%42也可以自己定义格式<#assign x = 1.234>${x?string("0")}${x?string("0.#")}${x?string("0.##")}${x?string("0.###")}${x?string("0.####")}${1?string("000.00")}${12.1?string("000.00")}${123.456?string("000.00")}${1.2?string("0")}${1.8?string("0")}${1.5?string("0")} <-- 1.5, rounded towards even neighbor ${2.5?string("0")} <-- 2.5, rounded towards even neighbor${12345?string("0.##E0")}输出结果:11.21.231.2341.234001.00012.10123.46122 <-- 1.5, rounded towards even neighbor2 <-- 2.5, rounded towards even neighbor1.23E42.对布尔值对象的使用例子:<#assign bl = true>${ bl?string(“yes”,”no”)} 输出结果:yestrim作用:去掉前后空格例子:${“FreeMarker “trim} 输出结果:FreeMarker upper_case作用:转换成大写例子:${“freemarker”?upper_case} 输出结果:FREEMARKER word_list作用:把字符串按照空格转化成sequence例子:<#assign seq = “the Free marker”?word_list><#list seq as item>${item}</#list>输出结果:theFreemarkerXmlC例子:${10?c} 输出结果: 10round ,floor,ceiling例子:<#assign testlist=[0, 1, -1, 0.5, 1.5, -0.5,-1.5, 0.25, -0.25, 1.75, -1.75]><#list testlist as result>${result} ?floor=${result?floor} ?ceiling=${result?ceiling} ?round=${ result?round}</#list>输出结果:0 ?floor=0 ?ceiling=0 ?round=01 ?floor=1 ?ceiling=1 ?round=1-1 ?floor=-1 ?ceiling=-1 ?round=-10.5 ?floor=0 ?ceiling=1 ?round=11.5 ?floor=1 ?ceiling=2 ?round=2-0.5 ?floor=-1 ?ceiling=0 ?round=0-1.5 ?floor=-2 ?ceiling=-1 ?round=-10.25 ?floor=0 ?ceiling=1 ?round=0-0.25 ?floor=-1 ?ceiling=0 ?round=01.75 ?floor=1 ?ceiling=2 ?round=2-1.75 ?floor=-2 ?ceiling=-1 ?round=-2first作用:返回sequence的第一个值例子:<% request.setAttribute(“lists”,list);%>${lists?first}<#assign x = [“free”,”marker”,”freemarker”]>${x?first} 输出结果:freelast作用:返回sequence的最后一个值例子:<% request.setAttribute(“lists”,list);%>${lists?last}<#assign x = [“free”,”marker”,”freemarker”]>${x?last} 输出结果:freemarkerseq_contains()作用:判断sequence中是否包含给出的值,返回true和false例子:<#assign x = ["red", 16, "blue", "cyan"]>"blue": ${x?seq_contains("blue")?string("yes", "no")} "yellow": ${x?seq_contains("yellow")?string("yes", "no")} 16: ${x?seq_contains(16)?string("yes", "no")}"16": ${x?seq_contains("16")?string("yes", "no")}输出结果:"blue": yes"yellow": no16: yes"16": noseq_index_of()作用:返回子串在sequence中第一出现的索引值,返回-1代表不存在子串例子:<#assign colors = ["red", "green", "blue"]>${colors?seq_index_of("blue")}${colors?seq_index_of("red")}${colors?seq_index_of("purple")}输出结果:2-1存在第二个参数的例子<#assign names = ["Joe", "Fred", "Joe", "Susan"]>No 2nd param: ${names?seq_index_of("Joe")}-2: ${names?seq_index_of("Joe", -2)}-1: ${names?seq_index_of("Joe", -1)}0: ${names?seq_index_of("Joe", 0)}1: ${names?seq_index_of("Joe", 1)}2: ${names?seq_index_of("Joe", 2)}3: ${names?seq_index_of("Joe", 3)}4: ${names?seq_index_of("Joe", 4)}输出结果:No 2nd param: 0-2: 0-1: 00: 01: 22: 23: -14: -1seq_last_index_of作用:返回子串在sequence最后出现的索引值,返回-1代表不存在该子串例子:<#assign names = ["Joe", "Fred", "Joe", "Susan"]>No 2nd param: ${names?seq_last_index_of("Joe")}-2: ${names?seq_last_index_of("Joe", -2)}-1: ${names?seq_last_index_of("Joe", -1)}0: ${names?seq_last_index_of("Joe", 0)}1: ${names?seq_last_index_of("Joe", 1)}2: ${names?seq_last_index_of("Joe", 2)}3: ${names?seq_last_index_of("Joe", 3)}4: ${names?seq_last_index_of("Joe", 4)}输出结果:No 2nd param: 2-2: -1-1: -10: 01: 02: 23: 24: 2reverse作用:反序输出sequence中的值例子:<#assign x = ["red", "16", "blue", "cyan"]?reverse >${x?first} 输出结果:cyansize作用:获得sequence的元素的数量例子:<#assign x = ["red", "16", "blue", "cyan"] >${x?size} 输出结果:4sort作用:对sequence中对象的tostring()结果进行排序例子:<#assign ls = ["whale", "Barbara", "zeppelin", "aardvark", "beetroot"]?sort> <#list ls as i> ${i}</#list>输出结果:aardvark Barbara beetroot whale zeppelinsort_by作用:对sequence 按里面的对象的属性value进行排序例子:<#assign ls = [{"name":"whale", "weight":2000},{"name":"Barbara", "weight":53},{"name":"zeppelin", "weight":-200},{"name":"aardvark", "weight":30},{"name":"beetroot", "weight":0.3}]>Order by name:<#list ls?sort_by("name") as i>- ${}: ${i.weight}</#list>Order by weight:<#list ls?sort_by("weight") as i>- ${}: ${i.weight}</#list>输出结果:Order by name:- aardvark: 30- Barbara: 53- beetroot: 0.3- whale: 2000- zeppelin: -200Order by weight:- zeppelin: -200- beetroot: 0.3- aardvark: 30- Barbara: 53- whale: 2000对于高级排序,在sequence中属性值也是sequence<#assign members = [{"name": {"first": "Joe", "last": "Smith"}, "age": 40},{"name": {"first": "Fred", "last": "Crooger"}, "age": 35},{"name": {"first": "Amanda", "last": "Fox"}, "age": 25}]> Sorted by st:<#list members?sort_by(['name', 'last']) as m>- ${st}, ${.first}: ${m.age} years old</#list>输出结果:Sorted by st:- Crooger, Fred: 35 years old- Fox, Amanda: 25 years old- Smith, Joe: 40 years oldchunk作用:分隔sequence成为几个子sequence,也可以给出默认的填充符例子:<#assign seq = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']><#list seq?chunk(4) as row><#list row as cell>${cell} </#list></#list><#list seq?chunk(4, '-') as row><#list row as cell>${cell} </#list></#list>输出结果:a b c de f g hi ja b c de f g hi j - -keys注意:不是所有的hash类型支持这个操作作用:返回hash里的所有keys,返回结果类型sequence例子:<#assign h = {"name":"mouse", "price":50}><#assign keys = h?keys><#list keys as key>${key} = ${h[key]}; </#list> 输出结果:name = mouse; price = 50;values注意:不是所有的hash类型支持这个操作作用:返回hash里的所有value, 返回结果类型sequence例子:<#assign h = {"name":"mouse", "price":50}> <#assign values = h?values><#list values as val>${val}-</#list>输出结果:mouse-50childrenParentRootAncestorsNode_name Node_typeNode_namespace。

freemarker !用法

freemarker !用法

freemarker !用法Freemarker是一种模板引擎,可以在Web应用中轻松地生成HTML,XML,JSON等文件。

它允许我们将数据和静态模板分离,从而使我们的代码更加清晰易读。

在这篇文章中,我们将探讨Freemarker的用法和一些最佳实践。

首先,我们需要了解Freemarker的基本语法。

Freemarker使用尖括号标记“<% %>"来定义内容块。

在这些标记内,我们可以使用变量,表达式,条件和迭代语句等。

例如,以下是一个简单的Freemarker模板:```<html><head><title>Hello, ${name}!</title></head><body><p>Welcome to our website!</p></body></html>```在这个模板中,我们使用了变量“name”。

这个变量可以在Java 代码中设置,并在生成HTML时插入到相应的位置。

为了在Java中使用Freemarker,我们需要引入Freemarker库,并创建一个Configuration对象:```Configuration cfg = newConfiguration(Configuration.VERSION_2_3_30);cfg.setClassForTemplateLoading(Main.class, "/templates"); cfg.setDefaultEncoding("UTF-8");```在这个例子中,我们设置了模板目录,并设置了默认编码为UTF-8。

然后,我们可以使用TemplateLoader从模板文件读取模板:```Template template = cfg.getTemplate("hello.ftl");```接下来,我们需要将我们的数据传递给数据模型。

Freemarker教程 中文版

Freemarker教程 中文版
1.1、创建配置实例..............................................................................4 1.2、创建数据模型(Data Model) ..........................................................4 1.3、获取模版(template) ..................................................................5 1.4、把模版与数据模型合并...................................................................6 1.5、完整的代码 ................................................................................6
你仅仅只需要这么一个配置就可以了 。注意: 如果你的系统中有多个独立的模块都要使 用 FreeMarker 那么你就需要多个 Configuration 实例(也就是说你每一个组建都需要一个 私有的配置)
1.2、创建数据模型(Data Model)
如果配置简单的数据模型,你可能只需要 ng 和 java.util 以及一些 Java Beans 来构建 FreeMarker 的数据库模型。
பைடு நூலகம்
前言
FreeMarker 官方参考文档总共有四份,它们分别是 Designer's Guide(网上已有翻译,主要从 FreeMarker 的概念上介绍) Programmer's Guide(本文档所以翻译的部分,主要从框架的设计方面介绍) XML Processing Guide(对 XML 数据模型处理的介绍) Reference(FreeMarker 的参考文档,语言使用介绍)

FreeMarker教程

FreeMarker教程

入门教程作者:熊师虎前言 (1)第一章:Freemarker简介 (2)1、数据模型 (2)2、模板 (3)1,开始标签: (3)2,结束标签: (4)3,集合标签: (4)4,赋值标签: (4)5,自定义标签及使用: (4)6,<#include>标签 (4)7,常用的操作 (4)第二章:Freemarker的使用 (5)1.创建配置实例 (5)2创建数据模型 (5)3获取模板 (6)4.合并模板与数据模型 (6)第三章:格式化,strust标签,JSTL标签,传值范围 (8)1,日期:string(当和一个日期值一起使用) (8)2、数字 (10)3、struts标签 (12)4、作用域 (13)尾声:参考资料代码下载地址 (13)前言大三时,我在与我的同学接的项目里面,都要求web应用程序有利于SEO,当时SEO很火。

前台页面的静态化就有利于SEO,所以这个问题摆在了我的面前,在网上一搜,关于这方面的资料不是很多,又很杂,关于这方面的知识,越来或多的程序员将会碰到,原来项目中这部分静态化的功能主要由我来做的,现在我将我的一点经验和大家分享。

写程序和写教程还是差别很大的,写的教程面向的人群更广,他们的水平可能相差很大,写教程的时候需要在语言上面反复提炼,在写教程之前,在李刚所著的《webwork权威指南》上有关于FreeMarker的介绍,现在我仅仅所知这本书上有介绍,当然他是放在struts2.0中讲的,如果一个程序员在他的开发过Struts2.0框架,那么他可能永远不晓得李刚所著书中有系统的介绍,我在写这个教程中没有看过《webwork权威指南》章节中的FreeMarker那部分类容,只是大概扫了一眼目录,但我觉得我讲的可能会更通用,更好理解一些。

有的人说传统的字符替代的方式也能实现静态话的功能,具体就是在一个html页面中不确定值的地方使用类似于用#temp#的标示,然后在java程序运行的过程中用实际值代替#temp#,为什么还要用FreeMarker呢?当你看完本教程后你就会明白为什么要用FreeMarker了。

Freemarker基础入门

Freemarker基础入门

简介:最简单的模板是普通HTML 文件(或者是其他任何文本文件—FreeMarker本身不属于HTML)。

当客户端访问页面时,FreeMarker 要发送HTML 代码至客户端浏览器端显示。

如果想要页面动起来,就要在HTML 中放置能被FreeMarker所解析的特殊部分。

${…}:FreeMarker将会输出真实的值来替换花括号内的表达式,这样被称为interpolations 插值,可以参考第上面一个示例的内容。

FTL tags 标签(FreeMarker模板的语言标签):FTL 标签和HTML 标签有一点相似,但是它们是FreeMarker的指令而且是不会直接输出出来的东西。

这些标签的使用一般以符号#开头。

(用户自定义的FTL 标签使用@符号来代替#,但这是更高级的主题了,后面会详细讨论)。

Comments 注释:FreeMarker的注释和HTML 的注释相似,但是它用<#--和-->来分隔。

任何介于这两个分隔符(包含分隔符本身)之间内容会被FreeMarker忽略,就不会输出出来了。

其他任何不是FTL 标签,插值或注释的内容将被视为静态文本,这些东西就不会被FreeMarker所解析,会被按照原样输出出来。

directives 指令就是所指的FTL 标签。

这些指令在HTML 的标签(如<table>和</table>)元素(如table 元素)中的关系是相同的。

(如果现在你还不能区分它们,把“FTL 标签”和“指令”看做是同义词即可。

)三大指令1.if指令<#if condition>...<#elseif condition2>...<#elseif condition3>......<#else>...其中空值判断可以写成<#if ?? ></#if>2.list指令遍历集合中的数据:<#list sequence as item>...</#list><#list>空值判断<#if bookList?size = 0></#list>例子:<#list employees.part1 as e>${}<#if e_has_next>集合还有数据,不是最后一个!<#else>已经没有数据了!<#/if></#list>3. include指令include 指令,我们可以插入其他文件的内容到当前的模板中。

freemarker:初识(搭建环境、对象、集合、索引、赋值、null、时间、宏定义)

freemarker:初识(搭建环境、对象、集合、索引、赋值、null、时间、宏定义)

freemarker:初识(搭建环境、对象、集合、索引、赋值、null、时间、宏定义)1、Freemarker环境搭建(1)导⼊依赖<dependency><groupId>org.freemarker</groupId><artifactId>freemarker</artifactId><version>2.3.16</version></dependency>(2)创建freemarker.html(模板⽂件)<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title></head><body>${zhai}</body></html>(3)创建测试类(数据模型)public class FMDemo {public static void main(String[] args) throws IOException, TemplateException {//配置对象Configuration configuration=new Configuration();//模板路径String dir="D:\\IdeaProjects\\Freemarker_01\\ftl\\";//导⼊模板⽬录configuration.setDirectoryForTemplateLoading(new File(dir));//获取模板Template template=configuration.getTemplate("freemarker.html");//数据Map root=new HashMap();root.put("zhai","hello");Writer out=new FileWriter(new File(dir)+"\\hello.html");//⽣成开始template.process(root,out);//关闭资源out.close();}}(4)测试(⽣成的html⽂件)(5)项⽬结构是⼀个由模板⽂件和数据⽂件⽣成⽬标⽂件的过程2、对象(1)测试类public class FMDemo {public static void main(String[] args) throws IOException, TemplateException {//配置对象Configuration configuration=new Configuration();//模板路径String dir="D:\\IdeaProjects\\Freemarker_01\\ftl\\";//导⼊模板⽬录configuration.setDirectoryForTemplateLoading(new File(dir));//获取模板Template template=configuration.getTemplate("freemarker.html");//数据Map root=new HashMap();Student student=new Student();student.setSex("男");student.setSname("zhai");root.put("student",student);Writer out=new FileWriter(new File(dir)+"\\hello.html");//⽣成开始template.process(root,out);//关闭资源out.close();}}(2)freemarker.html<body>${student.sex}/////${student.sname}</body>(3)创建学⽣类public class Student {private String sname;private String sex;public String getSname() {return sname;}public void setSname(String sname) {this.sname = sname;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}}(4)测试3、List集合(1)测试类public class FMDemo {public static void main(String[] args) throws IOException, TemplateException { //配置对象Configuration configuration=new Configuration();//模板路径String dir="D:\\IdeaProjects\\Freemarker_01\\ftl\\";//导⼊模板⽬录configuration.setDirectoryForTemplateLoading(new File(dir));//获取模板Template template=configuration.getTemplate("freemarker.html");//数据Map root=new HashMap();List students =new ArrayList<String>();students.add("zhang");students.add("zhai");students.add("ma");root.put("students",students);Writer out=new FileWriter(new File(dir)+"\\hello.html");//⽣成开始template.process(root,out);//关闭资源out.close();}}(2)freemarker.html<body><#list students as student>${student}</#list></body>(3)测试4、Map集合(1)创建Map集合Map root=new HashMap();Map map=new HashMap();map.put("z","zhai");map.put("l","liu");root.put("map",map);(2)freemarker.html<body><#list map?keys as key>${map[key]}</#list></body>(3)测试5、List_map集合(1)测试类//获取模板Template template=configuration.getTemplate("freemarker.html");//数据Map root=new HashMap();List<Map> maps=new ArrayList<Map>();Map stu1=new HashMap();stu1.put("num1","zhai");stu1.put("num2","zhang");Map stu2=new HashMap();stu1.put("num3","ma");stu1.put("num4","zhao");maps.add(stu1);maps.add(stu2);root.put("maps",maps);Writer out=new FileWriter(new File(dir)+"\\hello.html");(2)freemarker.html<#list maps as map><#list map?keys as key>${map[key]}</#list></#list>(3)测试6、索引(1)测试类Map root=new HashMap();List students =new ArrayList<String>();students.add("zhang");students.add("zhai");students.add("ma");root.put("students",students);Writer out=new FileWriter(new File(dir)+"\\hello.html");(2)freemarker.html<body><#list students as student>${student_index}</#list></body>(3)测试7、在模板中进⾏赋值(1)取标签数据<body><#assign x=0/>${x}</body>(2)取后台数据<body><#assign x='${zhai}'/>${x}</body>(3)集合<body><#assign x><#list ["a","b","c"] as n>${n}</#list> </#assign>${x}</body>(4)条件<#assign x><#list ["a","b","c"] as n><#if n!="a">${n}</#if></#list></#assign>${x}</body>8、时间(1)time格式<body>${time?time}</body>(2)datetime格式<body>${time?datetime}</body>9、对象存⼊数据:root.put("Student",new Student("zhai",12));模板:<body>${Student.sname}</body>⽣成的html:10、宏定义<body><#macro table pageNo>${pageNo}</#macro><@table pageNo=8/></body>。

FreeMarker+中文手册

FreeMarker+中文手册

FreeMarker 手册用于FreeMarker 2.3.16Translated By Nan Lei南磊译Copyright:The Chinese translation of the FreeMarker Manual by Nan Lei is licensed under a Creative Commons Attribution 3.0 Unported License (see /licenses/by/3.0/ ).This licence only applies to the Chinese translation, not to the original (English) FreeMarker Manual.FreeMarker中文版手册由南磊翻译,本文档基于Creative Commons Attribution 3.0 Unported授权许可(参见/licenses/by/3.0/deed.zh)本许可仅应用于中文版,不对原版英文手册。

(译者联系方式为:nanlei1987@)目录目录 (2)前言 (5)什么是FreeMarker? (5)我们应该阅读什么内容? (5)文档规约 (6)联系我们 (6)几点说明 (6)第一部分模板开发指南 (7)第一章模板开发入门 (7)1.1 简介 (7)1.2 模板+ 数据模型= 输出 (7)1.3 数据模型一览 (9)1.4 模板一览 (11)第二章数值和类型 (17)2.1 基本内容 (17)2.2 类型 (20)第三章模板 (24)3.1 总体结构 (24)3.2 指令 (25)3.3 表达式 (26)3.4 插值 (41)第四章其它 (44)4.1 自定义指令 (44)4.2 在模板中定义变量 (50)4.3 命名空间 (52)4.4 空白处理 (56)4.5替换(方括号)语法 (59)第二部分程序开发指南 (61)第一章程序开发入门 (61)1.1 创建配置实例 (61)1.2 创建数据模型 (61)1.3 获得模板 (62)1.4 合并模板和数据模型 (63)1.5将代码放在一起 (63)第二章数据模型 (65)2.1 基本内容 (65)2.2 标量 (66)2.3 容器 (67)2.4 方法 (68)2.5 指令 (69)2.6 节点变量 (76)第三章配置 (80)3.1 基本内容 (80)3.2 共享变量 (81)3.3 配置信息 (81)3.4 模板加载 (83)3.5 错误控制 (86)第四章其它 (90)4.1 变量 (90)4.2 字符集问题 (91)4.3 多线程 (92)4.4 Bean的包装 (93)4.5 日志 (99)4.6 在servlets中使用FreeMarker (99)4.7 为FreeMarker配置安全策略 (106)4.8 遗留的XML包装实现 (107)4.9 和Ant一起使用FreeMarker (110)4.10 Jython 包装器 (111)第三部分XML处理指南 (113)前言 (113)第一章揭示XML文档 (113)1.1 节点树 (113)1.2 将XML放到数据模型中 (115)第二章必要的XML处理 (116)2.1 通过例子来学习 (116)2.2 形式化描述 (124)第三章声明的XML处理 (127)3.1 基础内容 (127)3.2 详细内容 (130)第四部分参考文档 (133)第一章内建函数参考文档 (133)1.1 处理字符串的内建函数 (133)1.2 处理数字的内建函数 (146)1.3 处理日期的内建函数 (150)1.4 处理布尔值的内建函数 (153)1.5 处理序列的内建函数 (153)1.6 处理哈希表的内建函数 (159)1.7 处理节点(XML)的内建函数 (159)1.8 很少使用的和专家级的内建函数 (161)第二章指令参考文档 (164)2.1 if,else,elseif指令 (164)2.2 switch,case,default,break指令 (166)2.3 list,break 指令 (167)2.4 include指令 (168)2.6 noparse指令 (172)2.7 compress指令 (173)2.8 escape,noescape指令 (174)2.9 assign 指令 (176)2.10 global 指令 (178)2.11 local 指令 (179)2.12 setting 指令 (179)2.13 用户自定义指令(<@...>). (181)2.14 macro,nested,return 指令 (183)2.15 function,return 指令 (188)2.16 flush 指令 (189)2.17 stop 指令 (190)2.18 ftl 指令 (190)2.19 t,lt,rt 指令 (192)2.20 nt 指令 (193)2.21 attempt,recover 指令 (193)2.22 visit,recurse,fallback 指令 (195)第三章特殊变量参考文档 (199)第四章FTL中的保留名称 (200)第五章废弃的FTL结构 (200)5.1 废弃的指令列表 (200)5.2 废弃的内建函数列表 (200)5.3 老式的macro和call指令 (201)5.4 转换指令 (202)5.5 老式FTL语法 (204)5.6 #{...}式的数字插值 .. (205)前言什么是FreeMarker?FreeMarker是一款模板引擎:一种基于模板的、用来生成输出文本(任何来自于HTML 格式的文用本来自动生成源代码)的通用工具。

freemarker中文手册

freemarker中文手册

FreeMarker概述●FreeMarker是一个模板引擎,一个基于模板生成文本输出的通用工具,使用纯Java编写●FreeMarker被设计用来生成HTML Web页面,特别是基于MVC模式的应用程序●虽然FreeMarker具有一些编程的能力,但通常由Java程序准备要显示的数据,由FreeMarker生成页面,通过模板显示准备的数据(如下图)●FreeMarker不是一个Web应用框架,而适合作为Web应用框架一个组件●FreeMarker与容器无关,因为它并不知道HTTP或Servlet;FreeMarker同样可以应用于非Web应用程序环境●FreeMarker更适合作为Model2框架(如Struts)的视图组件,你也可以在模板中使用JSP标记库●FreeMarker是免费的1、通用目标●能够生成各种文本:HTML、XML、RTF、Java源代码等等●易于嵌入到你的产品中:轻量级;不需要Servlet环境●插件式模板载入器:可以从任何源载入模板,如本地文件、数据库等等●你可以按你所需生成文本:保存到本地文件;作为Email发送;从Web应用程序发送它返回给Web浏览器2、强大的模板语言●所有常用的指令:include、if/elseif/else、循环结构●在模板中创建和改变变量●几乎在任何地方都可以使用复杂表达式来指定值●命名的宏,可以具有位置参数和嵌套内容●名字空间有助于建立和维护可重用的宏库,或者将一个大工程分成模块,而不必担心名字冲突●输出转换块:在嵌套模板片段生成输出时,转换HTML转义、压缩、语法高亮等等;你可以定义自己的转换3、通用数据模型●FreeMarker不是直接反射到Java对象,Java对象通过插件式对象封装,以变量方式在1、快速入门(1)模板+ 数据模型= 输出●FreeMarker基于设计者和程序员是具有不同专业技能的不同个体的观念●他们是分工劳动的:设计者专注于表示——创建HTML文件、图片、Web页面的其它可视化方面;程序员创建系统,生成设计页面要显示的数据●经常会遇到的问题是:在Web页面(或其它类型的文档)中显示的信息在设计页面时是无效的,是基于动态数据的●在这里,你可以在HTML(或其它要输出的文本)中加入一些特定指令,FreeMarker会在输出页面给最终用户时,用适当的数据替代这些代码●下面是一个例子:●这个例子是在简单的HTML中加入了一些由${…}包围的特定代码,这些特定代码是FreeMarker的指令,而包含FreeMarker的指令的文件就称为模板(Template)●至于user、latestProduct.url和来自于数据模型(data model)●数据模型由程序员编程来创建,向模板提供变化的信息,这些信息来自于数据库、文件,甚至于在程序中直接生成●模板设计者不关心数据从那儿来,只知道使用已经建立的数据模型●下面是一个可能的数据模型:●数据模型类似于计算机的文件系统,latestProduct可以看作是目录,而user、url和name看作是文件,url和name文件位于latestProduct目录中(这只是一个比喻,实际并不存在)●当FreeMarker将上面的数据模型合并到模板中,就创建了下面的输出:(2)数据模型典型的数据模型是树型结构,可以任意复杂和深层次,如下面的例子:●类似于文件的变量称为scalars,保存单值●scalars保存的值有两种类型:字符串(用引号括起,可以是单引号或双引号)和数字(不要用引号将数字括起,这会作为字符串处理)●对scalars的访问从root开始,各部分用“.”分隔,如animals.mouse.price●另外一种变量是sequences,和hashes类似,只是不使用变量名字,而使用数字索引,如下面的例子:(3)模板●在FreeMarker模板中可以包括下面三种特定部分:${…}:称为interpolations,FreeMarker会在输出时用实际值进行替代FTL标记(FreeMarker模板语言标记):类似于HTML标记,为了与HTML 标记区分,用#开始(有些以@开始,在后面叙述)注释:包含在<#--和-->(而不是<!--和-->)之间●下面是一些使用指令的例子:if指令list指令输出为:3、模板(1)整体结构●模板使用FTL(FreeMarker模板语言)编写,是下面各部分的一个组合:文本:直接输出Interpolation:由${和},或#{和}来限定,计算值替代输出FTL标记:FreeMarker指令,和HTML标记类似,名字前加#予以区分,不会输出注释:由<#--和-->限定,不会输出●下面是以一个具体模板例子:●注意事项:FTL区分大小写,所以list是正确的FTL指令,而List不是;${name}和${NAME}是不同的Interpolation只能在文本中使用FTL标记不能位于另一个FTL标记内部,例如:(2)指令●在FreeMarker中,使用FTL标记引用指令●有三种FTL标记,这和HTML标记是类似的:开始标记:<#directivename parameters>结束标记:</#directivename>空内容指令标记:<#directivename parameters/>●有两种类型的指令:预定义指令和用户定义指令●用户定义指令要使用@替换#,如<@mydirective>...</@mydirective>(会在后面讲述)●FTL标记不能够交叉,而应该正确的嵌套,如下面的代码是错误的:●FreeMarker会忽略FTL标记中的空白字符,如下面的例子:(3)表达式●直接指定值字符串⏹使用单引号或双引号限定⏹如果包含特殊字符需要转义,如下面的例子:输出结果是:转义序列含义\"双引号(u0022)\'单引号(u0027)\\反斜杠(u005C)\n换行(u000A)\r Return (u000D)\t Tab (u0009)\b Backspace (u0008)\f Form feed (u000C)\l<\g>\a&\{{\x Code4位16进制Unicode代码⏹有一类特殊的字符串称为raw字符串,被认为是纯文本,其中的\和{等不具有特殊含义,该类字符串在引号前面加r,下面是一个例子:⏹直接输入,不需要引号⏹精度数字使用“.”分隔,不能使用分组符号⏹目前版本不支持科学计数法,所以“1E3”是错误的⏹不能省略小数点前面的0,所以“.5”是错误的⏹数字8、+8、08和8.00都是相同的布尔值⏹true和false,不使用引号序列⏹由逗号分隔的子变量列表,由方括号限定,下面是一个例子:输出的结果是:⏹可以使用数字范围定义数字序列,例如2..5等同于[2, 3, 4, 5],但是更有效率,注意数字范围没有方括号⏹可以定义反递增的数字范围,如5..2散列(hash)⏹由逗号分隔的键/值列表,由大括号限定,键和值之间用冒号分隔,下面是一个例子:●获取变量顶层变量: ${variable},变量名只能是字母、数字、下划线、$、@和#的组合,且不能以数字开头从散列中获取数据⏹可以使用点语法或方括号语法,假设有下面的数据模型:下面都是等价的:因为名字是任意表达式的结果从序列获得数据:和散列的方括号语法语法一样,只是方括号中的表达式值必须是数字;注意:第一个项目的索引是0序列片断:使用[startIndex..endIndex]语法,从序列中获得序列片断(也是序列);startIndex和endIndex是结果为数字的表达式特殊变量:FreeMarker内定义变量,使用.variablename语法访问●字符串操作Interpolation(或连接操作)⏹可以使用${..}(或#{..})在文本部分插入表达式的值,例如:⏹可以使用+操作符获得同样的结果⏹${..}只能用于文本部分,下面的代码是错误的:应该写成:子串⏹例子(假设user的值为“Big Joe”):结果是(注意第一个字符的索引是0):●序列操作连接操作:和字符串一样,使用+,下面是一个例子:输出结果是:●散列操作连接操作:和字符串一样,使用+,如果具有相同的key,右边的值替代左边的值,例如:输出结果是:●算术运算+、-、×、/、%,下面是一个例子:输出结果是(假设x为5):操作符两边必须是数字,因此下面的代码是错误的:使用+操作符时,如果一边是数字,一边是字符串,就会自动将数字转换为字符串,例如:输出结果是:使用内建的int(后面讲述)获得整数部分,例如:输出结果是(假设x为5):●比较操作符使用=(或==,完全相等)测试两个值是否相等,使用!=测试两个值是否不相等=和!=两边必须是相同类型的值,否则会产生错误,例如<#if 1 = "1">会引起错误Freemarker是精确比较,所以对"x"、"x "和"X"是不相等的对数字和日期可以使用<、<=、>和>=,但不能用于字符串由于Freemarker会将>解释成FTL标记的结束字符,所以对于>和>=可以使用括号来避免这种情况,例如<#if (x > y)>另一种替代的方法是,使用lt、lte、gt和gte来替代<、<=、>和>=●逻辑操作符&&(and)、||(or)、!(not),只能用于布尔值,否则会产生错误例子:●内建函数内建函数的用法类似访问散列的子变量,只是使用“?”替代“.”,下面列出常用的一些函数字符串使用的:⏹html:对字符串进行HTML编码⏹cap_first:使字符串第一个字母大写⏹lower_case:将字符串转换成小写⏹upper_case:将字符串转换成大写⏹trim:去掉字符串前后的空白字符序列使用的:⏹size:获得序列中元素的数目数字使用的:⏹int:取得数字的整数部分(如-1.9?int的结果是-1)例子(假设test保存字符串"Tom & Jerry"):输出结果是:●操作符优先顺序操作符组操作符后缀[subvarName] [subStringRange]. (methodParams)一元+expr、-expr、!内建?乘法*、/ 、%加法+、-关系<、>、<=、>=(lt、lte、gt、gte)相等==(=)、!=逻辑and &&逻辑or ||数字范围..(4)Interpolation●Interpolation有两种类型:通用Interpolation:${expr}数字Interpolation:#{expr}或#{expr; format}●注意:Interpolation只能用于文本部分●通用Interpolation插入字符串值:直接输出表达式结果插入数字值:根据缺省格式(由#setting指令设置)将表达式结果转换成文本输出;可以使用内建函数string格式化单个Interpolation,下面是一个例子:输出结果是:插入日期值:根据缺省格式(由#setting指令设置)将表达式结果转换成文本输出;可以使用内建函数string格式化单个Interpolation,下面是一个使用格式模式的例子:输出的结果类似下面的格式:插入布尔值:根据缺省格式(由#setting指令设置)将表达式结果转换成文本输出;可以使用内建函数string格式化单个Interpolation,下面是一个例子:输出结果是:●数字Interpolation的#{expr; format}形式可以用来格式化数字,format可以是:mX:小数部分最小X位MX:小数部分最大X位例子:4、杂项(1)用户定义指令●宏和变换器变量是两种不同类型的用户定义指令,它们之间的区别是宏是在模板中使用macro指令定义,而变换器是在模板外由程序定义,这里只介绍宏●基本用法宏是和某个变量关联的模板片断,以便在模板中通过用户定义指令使用该变量,下面是一个例子:作为用户定义指令使用宏变量时,使用@替代FTL标记中的#如果没有体内容,也可以使用:●参数在macro指令中可以在宏变量之后定义参数,如:可以这样使用这个宏变量:输出结果是:宏的参数是FTL表达式,所以下面的代码具有不同的意思:这意味着将Fred变量的值传给person参数,该值不仅是字符串,还可以是其它类型,甚至是复杂的表达式宏可以有多参数,下面是一个例子:可以这样使用该宏变量:其中参数的次序是无关的,因此下面是等价的:只能使用在macro指令中定义的参数,并且对所有参数赋值,所以下面的代码是错误的:可以在定义参数时指定缺省值,如:这样<@greet person="Fred"/>就正确了宏的参数是局部变量,只能在宏定义中有效●嵌套内容用户定义指令可以有嵌套内容,使用<#nested>指令执行指令开始和结束标记之间的模板片断例子:这样使用该宏变量:输出结果:<#nested>指令可以被多次调用,例如:输出结果:嵌套内容可以是有效的FTL,下面是一个有些复杂的例子:输出结果:宏定义中的局部变量对嵌套内容是不可见的,例如:输出结果:●在宏定义中使用循环变量用户定义指令可以有循环变量,通常用于重复嵌套内容,基本用法是:作为nested指令的参数传递循环变量的实际值,而在调用用户定义指令时,在<@…>开始标记的参数后面指定循环变量的名字例子:输出结果:指定的循环变量的数目和用户定义指令开始标记指定的不同不会有问题⏹调用时少指定循环变量,则多指定的值不可见⏹调用时多指定循环变量,多余的循环变量不会被创建(2)在模板中定义变量●在模板中定义的变量有三种类型:plain变量:可以在模板的任何地方访问,包括使用include指令插入的模板,使用assign指令创建和替换局部变量:在宏定义体中有效,使用local指令创建和替换循环变量:只能存在于指令的嵌套内容,由指令(如list)自动创建;宏的参数是局部变量,而不是循环变量●局部变量隐藏(而不是覆盖)同名的plain变量;循环变量隐藏同名的局部变量和plain变量,下面是一个例子:输出结果:输出结果:●模板中的变量会隐藏(而不是覆盖)数据模型中同名变量,如果需要访问数据模型中的同名变量,使用特殊变量global,下面的例子假设数据模型中的user的值是Big Joe:(3)名字空间●通常情况,只使用一个名字空间,称为主名字空间●为了创建可重用的宏、变换器或其它变量的集合(通常称库),必须使用多名字空间,其目的是防止同名冲突●创建库下面是一个创建库的例子(假设保存在lib/my_test.ftl中):间,并可以通过import指令中指定的散列变量访问库中的变量:输出结果:●可以使用assign指令在导入的名字空间中创建或替代变量,下面是一个例子:●数据模型中的变量任何地方都可见,也包括不同的名字空间,下面是修改的库:Freemarker - 几个比较实用的例子- -用Freemarker做模本语言有一段时间了,列出几个和JSP或者Velocity相比起来比较方便的用途,目的是引诱更多的人跳上Freemarker这个贼船,1. String内置的JavaScript转换: js_string用途:用于JavaScript转义,转换',",换行等特殊字符模板:<script>alert("${errorMessage?js_string}");输出:<script>alert("Readonly\'s pet name is \"Cross Bone\"");</script>2.内置的默认值处理:default用途: 用于处理默认值模本:User: ${?default("Anonymous")}<td>${()?default(" ")}</td> 输出:User: Anonymous注,可以对整个对象树加上(),再用内置处理器这种方便的做法,偶也是最近刚学会的,以前一直用很傻的方法做.....3. Sequence内置的计数器: xxx_index用途:显示序号模板:<#list employees as e>${e_index}. ${}</#list>输出:1. Readonly2. Robbin4. Sequence内置的分段器: chunk用途:某些比较BT的排版需求模板:<#assign seq = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']><#list seq?chunk(4) as row><ul><li><#list row as cell>${cell} </#list></li></ul></#list><#list seq?chunk(4, '-') as row><tr><td><#list row as cell>${cell} </#list></td></tr></#list>输出:<ul><li>a</li><li>b</li><li>d</li> </ul><ul><li>e</li> <li>f</li> <li>g</li> <li>h</li> </ul><ul><li>i</li> <li>j</li> </ul><tr><td>a</td> <td>b</td> <td>c</td> <td>d</td> </tr><tr><td>e</td><td>g</td> <td>h</td> </tr><tr><td>i</td> <td>j</td> <td>-</td> <td>-</td> </tr>。

freemaker模板引擎使用详解

freemaker模板引擎使用详解

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, "法国巴黎圣母院为教堂恐袭案遇害神⽗举⾏⼤弥撒", "⽽据美国战略司令部证实,其实这是中国长征七号⽕箭重新进⼊⼤⽓层,刚好经过加利福利亚附近。

freemarker(FTL)常见语法大全

freemarker(FTL)常见语法大全

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指令创建和替换。

Freemarker使用总结

Freemarker使用总结

迭代一个可迭代对象的一部分 将几个迭代器合并为一个 对一个迭代器排序 表达式语言 Situation Current (WW-2.1) Referring to an object in the PageContext scope #attr['itemIdOrName'] Referring to an object in the Request scope Same, but use #request['itemIdOrName'] if nested in an iteration. Referring to an object in the Session scope #session['itemIdOrName'] Referring to an object in the Application scope #application['itemIdOrName'] Property Setters foo.bar translates to getFoo().setBar() Property Getters foo.bar translates to getFoo().getBar() Boolean/boolean Property Getters Same, except uses dot notation instead of a slash (i.e. foo.bar) Collections as Properties Collections (including arrays) are similar to other objects, except they allow indexing: foo.bar[indexOrKeyName] translates to getFoo().getBar().get(indexOrKeyName) 获取类的属性 Java code OGNL expression (Muppet is the root) muppet.getName() name muppet.getMother().getName() mother.na me muppet.getFather().getFather().getAge() father.father .age 文字类型和操作符 Literal type Example char 'a' String 'hello world' "hello world" Boolean true false int 123 double 123.5 BigDecimal 123b BigInteger 123h Operation Example add (+) 2 + 4 'hello' + OGNL expression list.get(0) list[ 0] array[0] arra y[0] ((Muppet) list.get(0)).getName(); list[0].name array.length array.l egnth list.size() list.si ze list.isEmpty() list. isEmpty Java code OGNL expression List list = new ArrayList(3); {1, 3, 5} list.add(new Integer(1)); list.add(new Integer(3)); list.add(new Integer(5)); return list; List list = new ArrayList(2); {"foo", "bar"}[1] list.add("foo"); list.add("bar"); return list.get(1); 。。。 国际化 使用标签 key可以硬编码也可以使用参数化形式%{expression} > ... ... <#else> ... 用例 <#if x = 1> x is 1 <#if x = 1> x is 1 <#else> x is not 1 switch, case, default, break

FreeMarker学习1(Ftl)

FreeMarker学习1(Ftl)

FreeM‎a rker‎学习1(F‎t l)‎<# .‎.. > ‎中存放所有‎f reem‎a ker的‎内容,之外‎的内容全部‎原样输出。

‎<@ .‎.. />‎是函数调‎用两个定‎界符内的内‎容中,第一‎个符号表示‎指令或者函‎数名,其后‎的跟随参数‎。

free‎m aker‎提供的控制‎包括如下:‎<#if‎cond‎i tion‎><#el‎s eif ‎c ondi‎t ion>‎<#els‎e></#‎i f> 条‎件判断<‎#list‎hash‎_or_s‎e q as‎var>‎</#li‎s t> 遍‎历hash‎表或者co‎l lect‎i on(f‎r eema‎k er称作‎s eque‎n ce)的‎成员<#‎m acro‎name‎para‎m1 pa‎r am2 ‎... >‎<#nes‎t ed p‎a ram>‎</#ma‎c ro> ‎宏,无返回‎参数<#‎f unct‎i on n‎a me p‎a ram1‎para‎m2><#‎r etur‎n val‎></#f‎u ncti‎o n>函数‎,有返回参‎数var‎?memb‎e r_fu‎n ctio‎n(...‎)用函数‎对var进‎行转换,f‎r eema‎k er称为‎b uild‎-ins。

‎实际内部实‎现类似me‎m ber_‎f unct‎i on(v‎a r, .‎..)s‎t ring‎A[M .‎. N] ‎取子字符串‎,类似su‎b stri‎n g(st‎r ingA‎, M, ‎N){k‎e y:va‎l ue, ‎k ey2:‎v alue‎2 ...‎}直接定‎义一个ha‎s h表[‎i tem0‎, ite‎m1, i‎t em2 ‎...] ‎直接定义一‎个序列h‎a sh0[‎k ey0]‎存取ha‎s h表中k‎e y对应的‎元素se‎q0[5]‎存取序列‎指定下标的‎元素<@‎f unct‎i on1 ‎p aram‎0 par‎a m1 .‎.. />‎调用函数‎f unct‎i on1‎<@mac‎r o0 p‎a ram0‎para‎m1 ; ‎n est_‎p aram‎0 nes‎t_par‎a m1 .‎..> n‎e st_b‎o dy <‎/@ma‎c ro >‎调用宏,‎并处理宏的‎嵌套<#‎a ssig‎n var‎= va‎l ue >‎定义变量‎并初始化‎<#loc‎a l va‎r = v‎a lue>‎在 ma‎c ro 或‎者 fun‎c tion‎中定义局‎部变量并初‎始化<#‎g loba‎l var‎= va‎l ue >‎定义全局‎变量并初始‎化${v‎a r} 输‎出并替换为‎表达式的值‎<#vi‎s it x‎m lnod‎e> 调用‎m acro‎匹配xml‎n ode本‎身及其子节‎点<#r‎e curs‎e xml‎n ode>‎调用ma‎c ro匹配‎x mlno‎d e的子节‎点<#‎i f co‎n diti‎o n > ‎</#if‎><#‎l ist ‎S eque‎n ceVa‎r as ‎v aria‎b le >‎repe‎a tThi‎s </#‎l ist>‎<#in‎c lude‎"/co‎p yrig‎h t_fo‎o ter.‎h tml"‎>一个‎f tl标记‎不能放在另‎外一个ft‎l标记里面‎,但是注释‎标记能够放‎在ftl标‎记里面。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
FTL标记:FreeMarker指令,和HTML标记类似,名字前加#予以区分,不会输出
注释:由<#--和-->限定,不会输出
下面是以一个具体模板例子:
<html>[BR]
<head>[BR]
<title>Welcome!</title>[BR]
</head>[BR]
<body>[BR]
<#--Greettheuserwithhis/hername-->[BR]
(root)
|
+- animals
| |
| +- (1st)
| | |
| | +- name = "mouse"
| | |
| | +- size = "small"
| | |
| | +- price = 50
| |
| +- (2nd)
| | |
| | +- name = "elephant"
| | |
| | +- size = "large"
| | |
| | +- price = 5000
| |
| +- (3rd)
| |
| +- name = "python"
| |
| +- size = "medium"
| |
| +- price = 4999
|
+- whatnot
|
+- fruits
|
+- (1st) = "orange"
<html>
<head>
<title>Welcome!</title>
</head>
<body>
<h1>WelcomeBig Joe!</h1>
<p>Our latest product:
<a href="products/">green mouse</a>!
</body>
</html>
(2)数据模型
|
+- url = "products/"
|
+- name = "green mouse"
数据模型类似于计算机的文件系统,latestProduct可以看作是目录,而user、url和name看作是文件,url和name文件位于latestProduct目录中(这只是一个比喻,实际并不存在)
当FreeMarker将上面的数据模型合并到模板中,就创建了下面的输出:
<h1>Welcome${user}!</h1>[BR]
<p>Wehavetheseanimals:[BR]
<ul>[BR]
<#listanimalsasbeing>[BR]
<li>${}for${}Euros[BR]
</#list>[BR]
</ul>[BR]
</body>[BR]
</html>
[BR]是用于换行的特殊字符序列
经常会遇到的问题是:在Web页面(或其它类型的文档)中显示的信息在设计页面时是无效的,是基于动态数据的
在这里,你可以在HTML(或其它要输出的文本)中加入一些特定指令,FreeMarker会在输出页面给最终用户时,用适当的数据替代这些代码
下面是一个例子:
<html>
<head>
<title>Welcome!</title>
FreeMarker不是一个Web应用框架,而适合作为Web应用框架一个组件
FreeMarker与容器无关,因为它并不知道HTTP或Servlet;FreeMarker同样可以应用于非Web应用程序环境
FreeMarker更适合作为Model2框架(如Struts)的视图组件,你也可以在模板中使用JSP标记库
有两种类型的指令:预定义指令和用户定义指令
用户定义指令要使用@替换#,如<@mydirective>...</@mydirective>(会在后面讲述)
FTL标记不能够交叉,而应该正确的嵌套,如下面的代码是错误的:
<ul>
<#list animals as being>
<li>${} for ${} Eice = 5000
| |
| +- python
| |
| +- size = "medium"
| |
| +- price = 4999
|
+- test = "It is a test"
|
+- whatnot
|
+- because = "don't know"
类似于目录的变量称为hashes,包含保存下级变量的唯一的查询名字
典型的数据模型是树型结构,可以任意复杂和深层次,如下面的例子:
(root)
|
+- animals
| |
| +- mouse
| | |
| | +- size = "small"
| | |
| | +- price = 50
| |
| +- elephant
| | |
| | +- size = "large"
<tr>
<td>
<#if = "large"><b></#if>
${}
<#if = "large"></b></#if>
<td>${} Euros
</#list>
</table>
3、模板
(1)整体结构
模板使用FTL(FreeMarker模板语言)编写,是下面各部分的一个组合:
文本:直接输出
Interpolation:由${和},或#{和}来限定,计算值替代输出
|
+- (2nd) = "banana"
这种对scalars的访问使用索引,如animals[0].name
(3)模板
在FreeMarker模板中可以包括下面三种特定部分:
${…}:称为interpolations,FreeMarker会在输出时用实际值进行替代
FTL标记(FreeMarker模板语言标记):类似于HTML标记,为了与HTML标记区分,用#开始(有些以@开始,在后面叙述)
<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>
至于user、和来自于数据模型(data model)
数据模型由程序员编程来创建,向模板提供变化的信息,这些信息来自于数据库、文件,甚至于在程序中直接生成
模板设计者不关心数据从那儿来,只知道使用已经建立的数据模型
下面是一个可能的数据模型:
(root)
|
+- user = "Big Joe"
|
+- latestProduct
3、通用数据模型
FreeMarker不是直接反射到Java对象,Java对象通过插件式对象封装,以变量方式在模板中显示
你可以使用抽象(接口)方式表示对象(JavaBean、XML文档、SQL查询结果集等等),告诉模板开发者使用方法,使其不受技术细节的打扰
4、为Web准备
在模板语言中内建处理典型Web相关任务(如HTML转义)的结构
animalsas[BR]
being[BR]
>[BR]
注释:包含在<#--和-->(而不是<!--和-->)之间
下面是一些使用指令的例子:
if指令
<#if <Pythons are cheaper than elephants today.
<#else>
Pythons are not cheaper than elephants today.
</#if>
<h1>Welcome${user<#-- The name of user -->}!</h1>[BR]
<p>Wehavetheseanimals:[BR]
<ul>[BR]
<#list<#-- some comment... -->animals as<#-- again... -->being>[BR]
相关文档
最新文档