一、什么是FreeMarker?
FreeMarker基于设计者和程序员是具有不同专业技能的不同个体的观念
他们是分工劳动的:设计者专注于表示——创建HTML文件、图片、Web页面的其它可视化方面;程序员创建系统,生成设计页面要显示的数据 经常会遇到的问题是:在Web页面(或其它类型的文档)中显示的信息在设计页面时是无效的,是基于动态数据的 在这里,你可以在HTML(或其它要输出的文本)中加入一些特定指令,FreeMarker会在输出页面给最终用户时,用适当的数据替代这些代码1 2 3Welcome! 4 5 6Welcome ${user}!
7Our latest product: 8 ${latestProduct.name}! 9 10
这个例子是在简单的HTML中加入了一些由${…}包围的特定代码,这些特定代码是
FreeMarker的指令,而包含FreeMarker的指令的文件就称为模板(Template) 至于user、latestProduct.url和latestProduct.name来自于数据模型(data model) 数据模型由程序员编程来创建,向模板提供变化的信息,这些信息来自于数据库、文件,甚至于在程序中直接生成 模板设计者不关心数据从那儿来,只知道使用已经建立的数据模型所以 模版+数据模型=输出
当FreeMarker将上面的数据模型合并到模板中,就创建了下面的输出
1 2 3Welcome! 4 5 6Welcome Big Joe!
7Our latest product: 8 green mouse! 9 10
二、什么是数据模型?
典型的数据模型是树型结构,可以任意复杂和深层次,如下面的例子:
(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" 类似于目录的变量称为hashes,包含保存下级变量的唯一的查询名字 类似于文件的变量称为scalars,保存单值 scalars保存的值有两种类型:字符串(用引号括起,可以是单引号或双引号)和数字(不要用引号将数字括起,这会作为字符串处理) 对scalars的访问从root开始,各部分用“.”分隔,如animals.mouse.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" 这种对scalars的访问使用索引,如animals[0].name三、什么是模版?
在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>${being.name}<td>${being.price} Euros</#list></table> include指令
1 2 3Test page 4 5 6Test page
7Blah blah... 8 <#include "/copyright_footer.html"> 9 10
注意事项:
FTL区分大小写,所以list是正确的FTL指令,而List不是;${name}和${NAME}是不同的 Interpolation只能在文本中使用 FTL标记不能位于另一个FTL标记内部 注释可以位于FTL标记和Interpolation内部
四、FreeMarker指令
在FreeMarker中,使用FTL标记引用指令
有三种FTL标记,这和HTML标记是类似的: 开始标记:<#directivename parameters> 结束标记:</#directivename> 空内容指令标记:<#directivename parameters/> 有两种类型的指令:预定义指令和用户定义指令 用户定义指令要使用@替换#,如<@mydirective>...</@mydirective>有一类特殊的字符串称为raw字符串,被认为是纯文本,其中的\和{等不
具有特殊含义,该类字符串在引号前面加r,下面是一个例子:${r"${foo}"}${r"C:\foo\bar"}输出的结果是:${foo}C:\foo\bar
字符串的操作
${..}只能用于文本部分,下面的代码是错误的:
<#if ${isBig}>Wow!</#if><#if "${isBig}">Wow!</#if>应该写成:<#if isBig>Wow!</#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 & JerryTOM & JERRYInterpolation(插值)
Interpolation有两种类型: 通用Interpolation:${expr} 数字Interpolation:#{expr}或#{expr; format} 注意:Interpolation只能用于文本部分 通用Interpolation 插入字符串值:直接输出表达式结果 插入数字值:根据缺省格式(由#setting指令设置)将表达式结果转换成文本输出;可以使用内建函数string格式化单个Interpolation五、在模板中定义变量
在模板中定义的变量有三种类型:
plain变量:可以在模板的任何地方访问,包括使用include指令插入的模板,使用assign指令创建和替换 局部变量:在宏定义体中有效,使用local指令创建和替换 循环变量:只能存在于指令的嵌套内容,由指令(如list)自动创建;宏的参数是局部变量,而不是循环变量局部变量隐藏(而不是覆盖)同名的plain变量;循环变量隐藏同名的局部变量和plain变量
未完待续。。。