Freemarker学习--模版开发

一、什么是Freemarker

FreeMarker 是一款模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本。模板文件即ftl文件,数据对象是java对象。

模板 + 数据模型 = 输出

二、Freemarker的数据模型

1、顶层数据模型

数据模型是树状结构的,顶层默认为root节点

(root)

    |+- animals

    |     |+- mouse

    |     |     |+- size = "small"

    |     |     |+- price = 50

    |     |+- elephant

2、Hashes类型

这种类型可以通过名字来查找。顶层节点就是这种类型。例如可以通过animals.mouse来访问mouse。

3、sequences 类型

它们像哈希表那样存储子变量,但是子变量没有名字,它们只是列表中的项。

(root)

    | +- animals

    |     |+- (1st)

    |     |     |+- name = "mouse"

    |     |     |+- size = "small"

    |     |     |+- price = 50

    |     |+- (2nd)

要访问序列的子变量,可以使用方括号形式的数字索引下标。 索引下标从0开始

4、scalars 类型

包括:

  • 字符串:就是文本,也就是任意的字符序列。
  • 数字:这是数值类型,就像上面的 price。 在FreeMarker中,字符串 "50" 和数字 50 是两种完全不同的东西。前者是两个字符的序列 (这恰好是人们可以读的一个数字),而后者则是可以在数学运算中直接被使用的数值。

  • 日期/时间: 可以是日期-时间格式(存储某一天的日期和时间), 或者是日期(只有日期,没有时间),或者是时间(只有时间,没有日期)。

  • 布尔值:对应着对/错(是/否,开/关等值)类似的值。 比如动物可以有一个 protected (受保护的,译者注) 的子变量, 该变量存储这个动物是否被保护起来的值。

 

三、Freemarker的模板

  • ${...}: FreeMarker将会输出真实的值来替换大括号内的表达式,这样的表达式被称为 interpolation(插值,译者注)。

  • FTL 标签 (FreeMarker模板的语言标签): FTL标签和HTML标签有一些相似之处,但是它们是FreeMarker的指令,是不会在输出中打印的。 这些标签的名字以 # 开头。(用户自定义的FTL标签则需要使用 @ 来代替 #。)

  • 注释: 注释和HTML的注释也很相似, 但是它们使用 <#-- and --> 来标识。 不像HTML注释那样,FTL注释不会出现在输出中(不出现在访问者的页面中), 因为 FreeMarker会跳过它们。

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

if 指令

<#if animals.python.price < animals.elephant.price> Pythons are cheaper than elephants today. <#elseif animals.elephant.price < animals.python.price> Elephants are cheaper than pythons today. <#else> Elephants and pythons cost the same today. </#if>

 通常来讲,如果 condition 是false(布尔值),那么介于 <#if condition> 和 </#if> 标签中的内容会被略过。

 

list 指令

<p>Fruits: <#list misc.fruits as fruit>${fruit}<#sep>, </#list>

使用分隔符 <#sep>

 

include 指令

使用 include 指令, 我们可以在模板中插入其他文件的内容。

事实上,指令有两种类型: 预定义指令 和 用户自定义指令。 对于用户自定义的指令使用 @ 来代替 #,比如,<@mydirectiveparameters>...</@mydirective>。 更深的区别在于如果指令没有嵌套内容,那么必须这么使用 <@mydirective parameters />自定义指令也可以通过代码自定义

 自定义指令示例:

<#macro printAnimal animal>

  <animal name="${animal.name}" size="${animal.size}">

  <#nested>

</#macro>

 

<#list animals.getMap()?values as animal>

<@printAnimal animal>

<!-- xml注释内容 -->

</@printAnimal>

</#list>

四、Freemarker的内建函数

内建函数很像子变量(如果了解Java术语的话,也可以说像方法), 它们并不是数据模型中的东西,是 FreeMarker 在数值上添加的。 为了清晰子变量是哪部分,使用 ?(问号)代替 .(点)来访问它们。常用内建函数的示例:

  • user?html 给出 user 的HTML转义版本, 比如 & 会由 &amp; 来代替。

  • user?upper_case 给出 user 值的大写版本 (比如 "JOHN DOE" 来替代 "John Doe")

  • animal.name?cap_first 给出 animal.name 的首字母大写版本(比如 "Mouse" 来替代 "mouse")

  • user?length 给出 user 值中 字符的数量(对于 "John Doe" 来说就是8)

  • animals?size 给出 animals 序列中 项目 的个数(我们示例数据模型中是3个)

  • 如果在 <#list animals as animal> 和对应的 </#list> 标签中:

    • animal?index 给出了在 animals 中基于0开始的 animal的索引值

    • animal?counter 也像 index, 但是给出的是基于1的索引值

    • animal?item_parity 基于当前计数的奇偶性,给出字符串 "odd" 或 "even"。在给不同行着色时非常有用,比如在 <td class="${animal?item_parity}Row">中。

一些内建函数需要参数来指定行为,比如:

  • animal.protected?string("Y", "N") 基于 animal.protected 的布尔值来返回字符串 "Y" 或 "N"。

  • animal?item_cycle('lightRow','darkRow') 是之前介绍的 item_parity 更为常用的变体形式。

  • fruits?join(", ") 通过连接所有项,将列表转换为字符串, 在每个项之间插入参数分隔符(比如 "orange,banana")

  • user?starts_with("J") 根据 user 的首字母是否是 "J" 返回布尔值true或false。

内建函数应用可以链式操作,比如user?upper_case?html 会先转换用户名到大写形式,之后再进行HTML转义。(这就像可以链式使用 .(点)一样)

处理不存在的变量

<h1>Welcome ${user!"visitor"}!</h1> 当user为空时,使用默认只visitor

<#if user??><h1>Welcome ${user}!</h1></#if> ??表示条件判断,相当于if(null!=user)

猜你喜欢

转载自fengozl.iteye.com/blog/2287310