包含FreeMarker的指令的文件就称为模板(Template)。 

模板设计者不关心数据从那儿来,只知道使用已经建立的数据模型。 

数据模型由程序员编程来创建,向模板提供变化的信息,这些信息来自于数据库、文件,甚至于在程序中直接生成。 


数据类型: 


一、基本: 

1、scalars:存储单值 


字符串:简单文本由单或双引号括起来。 

数字:直接使用数值。 

日期:通常从数据模型获得 

布尔值:true或false,通常在<#if …>标记中使用 


2、hashes:充当其它对象的容器,每个都关联一个唯一的查询名字 


具有一个唯一的查询名字和他包含的每个变量相关联。 


3、sequences:充当其它对象的容器,按次序访问 


使用数字和他包含的每个变量相关联。索引值从0开始。 


4、集合变量: 


除了无法访问它的大小和不能使用索引来获得它的子变量:集合可以看作只能由<#list...>指令使用的受限sequences。 


5、方法:通过传递的参数进行计算,以新对象返回结果 


方法变量通常是基于给出的参数计算值在数据模型中定义。 


6、用户自定义FTL指令:宏和变换器 


7、节点 


节点变量表示为树型结构中的一个节点,通常在XML处理中使用。 


模板: 


使用FTL(freeMarker模板语言)编写 


组成部分 


一、整体结构 


1、注释:<#--注释内容-->,不会输出。 


2、文本:直接输出。 


3、interpolation:由 ${var} 或 #{var} 限定,由计算值代替输出。 


4、FTL标记 


二、指令: 

freemarker指令有两种: 

1、预定义指令:引用方式为<#指令名称> 

2、用户定义指令:引用方式为<@指令名称>,引用用户定义指令时须将#换为@。 

注意:如果使用不存在的指令,FreeMarker不会使用模板输出,而是产生一个错误消息。 


freemarker指令由FTL标记来引用,FTL标记和HTML标记类似,名字前加#来加以区分。如HTML标记的形式为 

则FTL标记的形式是<#list></#list>(此处h1标记和list指令没有任何功能上的对应关系,只是做为说明使用一下)。 


有三种FTL标记: 

1)、开始标记:<#指令名称> 

2)、结束标记:</#指令名称> 

3)、空标记:<#指令名称/> 


注意: 


1) FTL会忽略标记之中的空格,但是,<#和指令 与 </#和指令 之间不能有空格。 

2) FTL标记不能够交叉,必须合理嵌套。每个开始标记对应一个结束标记,层层嵌套。 如: 

<#list> 

# 


${数据} 

<#if 变量> 


game over! 


</#if> 


</#list> 


注意事项: 

1)、FTL对大小写敏感。所以使用的标记及interpolation要注意大小写。name与NAME就是不同的对象。<#list>是正确的标记,而<#List>则不是。 

2)、interpolation只能在文本部分使用,不能位于FTL标记内。如<#if ${var}>是错误的,正确的方法是:<#if var>,而且此处var必须为布尔值。 

3)、FTL标记不能位于另一个FTL标记内部,注释例外。注释可以位于标记及interpolation内部。 



三、表达式 


1、直接指定值: 


1-1、字符串: 

由双引号或单引号括起来的字符串,其中的特殊字符(如' " \等)需要转义。 



1-2、raw字符串: 

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

${r"/${data}"year""}屏幕输出结果为:/${data}"year" 



转义 含义 

序列 


\" 双引号(u0022) 


\' 单引号(u0027) 


\\ 反斜杠(u005C) 


\n 换行(u000A) 


\r Return (u000D) 


\t Tab (u0009) 


\b Backspace (u0008) 


\f Form feed (u000C) 


\l < 


\g > 


\a & 


\{ { 


\xCode 4位16进制Unicode代码 


1-3、数字:直接输入,不需要引号 


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

2)、目前版本不支持科学计数法,所以“1E3”是错误的 

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

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


1-4、布尔值:true和false,不使用引号 


1-5、序列:由逗号分隔的子变量列表,由[]方括号限定。 

1)、子变量列表可以是表达式 

2)、可以使用数字范围定义数字序列,不需要方括号限定,例如2..5等同于[2, 3, 4, 5],但是更有效率,可以定义反递增范围如:5..2。 


1-6、散列(hash) 

1)、由逗号分隔的键/值列表,由{}大括号限定,键和值之间用冒号分隔,如:{"key1":valu1,"key2":"character string"....} 

2)、键和值都是表达式,但是键必须是字符串。 


2、获取变量: 


2-1、顶层变量:${变量名} 


变量名只能是字母、数字、下划线、$、#、@ 的组合,且不能以数字开头。 


2-2、散列:有两种方法 


1)、点语法:变量名字和顶层变量的名字受同样的限制 

2)、方括号语法:变量名字无限制,可以是任意的表达式的结果 

book.author.name 

book.author.["name"] 

book["author"].name 

book["author"]["name"] 

以上是等价的。 


2-3、序列:使用散列的方括号语法获取变量,方括号中的表达式结果必须为数字。注意:第一个项目的索引为0。可以使用 

[startindex..endindex]语法获取序列片段。 


2-4、特殊变量:FreeMarker内定义变量,使用.variablename语法访问。 


3、字符串操作 


3-1、interpolation:使用${}或#{}在文本部分插入表达式的值,例如: 


${"hello${username}!"} 

${"${username}${username}${username}"} 


也可以使用+来获得同样的结果: 

${"hello"+username+"!"} 

${username+username+username} 


注意:${}只能用于文本部分而不能出现于标记内。 


<#if ${user.login}>或<#if "${user.login}">都是错误的; 

<#if user.login>是正确的。 

本例中user.login的值必须是布尔类型。 


3-2、子串: 

举例说明:假如user的值为"Big Joe" 

${user[0]}${user[4]}结果是:BJ 

${user[1..4]}结果是:ig J 


4、序列操作 


4-1、连接操作:可以使用+来操作,例如: 

["title","author"]+["month","day"] 


5、散列操作 

5-1、连接操作:可以使用+来操作,如果有相同的KEY,则右边的值会替代左边的值,例如: 

{"title":散列,"author":"emma"}+{"month":5,"day":5}+{"month":6}结果month的值就是6。 


6、算术运算 


6-1、操作符:+、-、*、/、% 

除+号以外的其他操作符两边的数据,必须都是数字类型。 

如果+号操作符一边有一个字符型数据,会自动将另一边的数据转换为字符型数据,运算结果为字符型数据。 


6-2、比较操作符: 

1)、= 

2)、== 

3)、!= 

4)、< 

5)、<= 

6)、> 

7)、>= 

1-3的操作符,两边的数据类型必须相同,否则会产生错误 

4-7的操作符,对于日期和数字可以使用,字符串不可以使用。 


注意: 

1)、FreeMarker是精确比较,所以"x" "x " "X"是不等的。 

2)、因为<和>对FTL来说是开始和结束标记,所以,可以用两种方法来避免这种情况: 

一种是使用括号<#if (a 

另一是使用替代输出,对应如下: 

< lt 

<= lte 

> gt 

>= gte 


6-3、逻辑操作符:只能用于布尔值,否则会出现错误。 


&&(and)与运算 

||(or)或运算 

!(not)非运算 


6-4、内建函数:使用方法类似于访问散列的子变量,只是使用?代替.例如:${test?upper_case?html} 


常用的内建函数列举如下: 


1)、字符串使用: 


html:对字符串进行HTML编码 

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

lower_first:字符串第一个字母小写 

upper_case:将字符串转换成大写 

trim:去年字符前后的空白字符 


2)、序列使用: 

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


3)、数字使用: 

int:取得数字的整数部分 


7、操作符的优先顺序: 


后缀:[subbarName][subStringRange].(mathodParams) 

一元:+expr、-expr、! (not) 

内建:? 

乘法:*、/、% 

加法:+、- 

关系:<、<=、>、>= (lt、lte、gt、gte) 

相等:=、==、!= 

逻辑与:&& (and) 

逻辑或:|| (or) 

数字范围:.. 


四、interpolation 


inperpolation只能用于文本,有两种类型:通用interpolation及数字interpolation 


1、通用interpolation 


如${expr} 


1-1、插入字符串值:直接输出表达式结果。 

1-2、插入数字值:根据缺省格式(由setting指令设置)将表达式结果转换成文本输出;可以使用内建函数string来格式化单个interpolation 


如: 

<#setting number_format="currency" /> 

<#assign answer=42 /> 

${answer} <#-- ¥42.00 --> 

${answer?string} <#-- ¥42.00 --> 

${answer?string.number} <#-- 42 --> 

${answer?string.currency} <#-- ¥42.00 --> 

${answer?string.percent} <#-- 42,00% --> 


1-3、插入日期值:根据缺省格式(由setting指令设置)将表达式结果转换成文本输出;可以使用内建函数string来格式化单个interpolation