一、类型
1、标量: 标量存储单一的值
(1)字符串:在模板中,字符串必须放在引号内,数字是不用放在引号内的
字符串内可以用“\”可以进行转义,FreeMarker支持的转义字符见末尾
为了表示原生字符串,可以在开始的引号或单引号之前放置字母r:
正确使用插值
(2)数字:
(3)布尔值:
(4)日期:有三种格式
精确到天的日期;
每天的时间(不包括日期部分),时间的存储精确到毫秒;
日期-时间(也称作“时间戳”),时间部分的存储精确到毫秒。
2、容器:
(1)哈希表:
什么是哈希表?
每个子变量都可以通过一个唯一的名称来查找,这个名称是不受限制的字符串。哈希表并不确定其中子变量的顺序,也就是说没有第一个变量,
第二个变量这样的说法,变量仅仅是通过名称来访问的。(就像Java中的HashMap一样,是实现了Hash算法的Map,不记录内部元素的顺序,
仅仅通过名称来访问。)
哈希表可以通过使用点和子变量的名字得到它的值
(2)序列:序列是存储有序变量的容器。存储的变量可以通过数字索引来检索,索引通常从零开始。序列是数组吗?
可以使用数组的方括号方式来访问一个序列的自变量:animals[0].name
(3)集:从模板设计者角度来看,集是由限制的序列。不能获取集的大小,也不能通过索引取出集中的子变量,但是它们仍然可以通过list指令来遍
历。
3、子程序:
(1)方法和函数: 函数与方法有什么区别?这是模板作者所关心的,它们没有关系,但也不是一点关系都没有。方法是来自于数据模型(它们反射了Java对象的方法),而函数是定义在模板内的(使用了函数指令),但二者可以用同一种方式来使用
(2)用户自定义指令
4、其他/很少使用:
(1)节点:节点变量代表了树状结构中的一个节点,而且通常是配合XML格式来处理的,这是专业而且更高级的主题。
二、Tags标签
标签不可以在其他的标签或插值中使用,标签大小写敏感
directives 指令:就是所指的 FTL 标签
1、常用FTL标签
2、NULL值的处理,有两种方式:
(1)在变量后面跟一个!和默认值。默认值可以是任何类型的表达式,默认表达式的复杂度没有严格的限制。如果!后面没有任何值,则默认结果是空串
(2)在变量名后面跟上两个问好,来询问freemark这个变量是否存在。
语法:unsafe_expr??或(unsafe_expr)??
3、用户自定义指令
list、if等是预定义指令
(1)自定义指令可以使用 macro 指令来定义,也可以在Java 中实现指令,可以使用freemarker.template.TemplateDirectiveModel 类来扩展
(2)宏传参
(3)嵌套内容
(4)循环变量
自定义指令也可以有循环变量,
4、 函数/方法和用户自定义指令的比较:
如果要使用函数/方法或自定义指令去实现一些东西的时候,二者之间的选择是两难的。按经验来说,如果能够实现,请先用自定义指令而不要用函数/方法。指令的特征如下:
(1)输出(返回值)的是标记(HTML、XML等)。主要原因是函数的返回结果可以自动进行XML转移(这是因为${ }的特性),而用户自定义指令的输出则不是(这是因为<@...>的特性所致,它的输出假定为是标记,因此就不再转义。)
(2)副作用也是很重要的一点,它每一返回值。例如一个指令的目的是往服务器日志中添加一条目。(事实上你不能得到自定义指令的返回值,但有些反馈的类型是由可能设置非本地变量的)
(3)会进行流程的控制(就像list或If指令那样),但是不能再函数/方法上这么做。
三、内建函数
1、语法:变量?内建函数
2、了解重要的内建函数:
(1)字符串使用的内建函数
1)html:字符串中所有的特殊HTML字符都需要用实体引用来代替(比如<代替为<,比如${test?html},假设test的值为“Tom & Jerry”输
出为Tom & Jerry)
2)cap_first:字符串的第一个字母变大写
3)lower_case:字符串的小写形式
4)upper_case:字符串的大写形式
5)trim:去掉字符串首尾的空格
(2)序列使用的内建函数:
size:序列中元素的个数
(3)数字使用的内建函数:
int:数字的整数部分(比如-1.9?int就是-1)
(4)内嵌函数的双重使用:
注意 test?upper_case?html,内嵌函数双重使用,test?upper_case 的结果是字符串了,但也还可以继续在其后使用 html 内建函数
四、在模板中定义变量
在数据模型之外,模板本身也可以定义变量来使用。这些临时变量可以适应FTL指令来创建和替换。要注意每一次模板执行时都维护它自己的这些变量的私有设置,这些变量是在页面用以呈现信息的。变量的初始值是空,当模板执行结束这些变量便被销毁了。模板变量比同名的数据模型上的变量的优先级要高,模板变量与数据模型上的变量同名时,模板变量会将数据模型根上的变量隐藏而不是覆盖
在模板中可以定义三种类型的变量:
(1)简单变量:它能从模板中的任何位置来访问,或者使用include指令引入的模板访问。可以使用assign或macro指令来创建或替换变量。
(2)局部变量:它们只能被设置在宏定义体内,而且只在宏内可见。可以使用local指令在宏定义内创建或替换局部变量
(3)循环变量:是由指令(如list,as后的)自动创建,宏的参数是局部变量而不是循环变量
五、命名空间
当运行 FTL 模板时,就会有使用 assign 和 macro 指令创建的变量的集合(可能是空的),像这样的变量集合被称为 namespace 命名空间。在简单的情况下可以只使用一个命名空间,称之为 main namespace 主命名空间。因为通常只使用本页上的命名空间,所以就没有意识到这点。如果想创建可以重复使用的宏,函数和其他变量的集合,通常用术语来说就是引用library 库。 但要确保库中没有宏(或其他变量)名和数据模型中变量同名,而且也不能和模板中引用其他库中的变量同名。 通常来说,变量因为名称冲突也会相互冲突。所以要为每个库中的变量使用不同的命名空间
(1)import与include指令的区别
如果是用include,那么就会在主命名空间创建两个变量,这样就不是很好,因为想让他们只在同一个命名空间“My Test Library”中。所以就不得不使用import指令来代替include。使用include会在my_test.ftl创建一个空的命名空间,然后再那里执行。如果要在主命名空间中使用:
在引入的命名空间上编写变量
多次import命名空间,只会为第一次的import引用创建命名空间执行模板,其他的只是创建一个哈希表当作访问相同命名空间的“门”,其实他们访问的都是相同的命名空间。
命名空间是部分层次的,它们之间是相互独立存在的。如果在命名空间N1中import命名空间N2,N2也不在N1中,N1只是可以通过哈希表来访问N2。
六、其他
1、FreeMark背后(确切的说是在MVC模式背后)的重要思想就是表现逻辑和业务逻辑相分离。freemark模板能用的数据被包装成data-model数据模型。
3、Interpolation 插值:这部分会被计算的值替换。插值由${ }(或者#{ },这个种风格已经不建议了)
插值仅仅可以在两种位置使用:
文本区 (如 <h1>Hello ${name}!</h1> )和
字符串表达式(如 <#include "/footer/${company}.html" >
4、模板也被称为FTL,代表FreeMarker模板语言。5、FTL tags 标签(FreeMarker 模板的语言标签) :FTL 标签,这些标签的使用一般以符号#开头。(用户自定义的 FTL 标签使用@符号来代替#)
6、FreeMarker注释:是用<#--和-->来分隔的。
8、当使用点式语法时,顶层变量名的命名也有相同的限制(命名时只能使用字母,数字,下划线,$,@等),而使用方括号语法形式时命名有没有这样的限制,它可以是任意的表达式。(为了 FreeMarker 支持 XML,如果变量名是*(星号)或者**,那么就应该使用方括号语法格式。 )
9、数据模型中的变量在任何位置都是可见的
10、替换方括号语法:那么就用[#ftl]来开始模板,要记住这个要放在文件的最前面即可(除了它前面的空格)
11、freemarker标签在session中取值,FreeMarker内部对象
${Session.loginSession.userId!}
调用repeat方法${repeat("What", 3)}
FreeMarker支持的转义字符