freemarker 模板

1 总体结构

模板(FTL 编程)是由如下部分混合而成的:
Text 文本:文本会照着原样来输出。
Interpolation 插值:这部分的输出会被计算的值来替换。插值由${和}所分隔(或者#{和},这种风格已经不建议再使用了)。
FTL tags 标签:FTL 标签和 HTML 标签很相似,但是它们却是给 FreeMarker 的指示,而且不会打印在输出内容中。
Comments 注释:FTL 的注释和 HTML 的注释也很相似,但它们是由<#--和-->来分隔的。注释会被 FreeMarker 所忽略,更不会在输出内容中显示。


2 指令

使用 FTL 标签来调用 directives 指令,比如调用 list 指令。

指令有两种类型:预定义指令和用户自定义指令。对于用户自定义的指令使用@来代替#

更深的区别在于如果指令没有嵌套内容,那么必须这么使用 <@mydirective parameters />而预定义指定则为<#directive something>

FreeMarker 可以不需要#来理解预定义指令(比如<if user == "Big Joe">...</if>)。而我们不建议这样来使用。


3 表达式
当需要给插值或者指令参数提供值时,可以使用变量或其他复杂的表达式。例如,我们设 x 为 8,y 为 5,那么(x+y)/2 的值就会被处理成数字类型的值 6.5

当给插值提供值时:插值的使用方式为${expression}

当给指令参数提供值时:在入门章节我们已经看到 if 指令的使用了。这个指令的语法是:<#if expression>...</#if>。这里的表达式计算结果必须是布尔类型的。


快速浏览(备忘单)



直接确定值

_1 字符串

如果文本本身包含用于字符引用的引号(双引号”或单引号’)或反斜杠时,应该在它们的前面再加一个反斜杠,这就是转义。转义允许你直接在文本中输入任何字符,也包括反斜杠。

下面的表格是 FreeMarker 支持的所有转义字符。



原生字符串:在原生字符串中,反斜杠和${没有特殊的含义,它们被视为普通的字符。为了表明字符串是原生字符串,在开始的引号或单引号之前放置字母 r,例如:

${r"${foo}"} 
${r"C:\foo\bar"} 
将会打印:
${foo} 
C:\foo\bar

_2 数字输入不带引号的数字就可以直接指定一个数字,必须使用点作为小数的分隔符而不能是
其他的分组分隔符。

_3 布尔值 直接写 true 或 false 就表征一个布尔值了,不需使用引号。


_4 序列
指定一个文字的序列,使用逗号来分隔其中的每个子变量,然后把整个列表放到方括号中。例如:

<#list ["winter", "spring", "summer", "autumn"] as x> 
${x} 
</#list>
列表中的项目是表达式,那么也可以这样做:[2 + 2, [1, 2, 3, 4], "whatnot"],其中第一个子变量是数字 4,第二个子变量是一个序列,第三个子变量是字符串”whatnot”。 也可以用 start..end 定义存储数字范围的序列,这里的 start 和 end 是处理数
字值表达式,比如 2..5 和[2, 3, 4, 5]是相同的,但是使用前者会更有效率(内存占用少而且速度快)。可以看出前者也没有使用方括号,这样也可以用来定义递减的数字范围,比如 5..2。(此外,还可以省略 end,只需 5..即可,但这样序列默认包含 5,6,7,8
等递增量直到无穷大)

_5 哈希表
在模板中指定一个哈希表,就可以遍历用逗号分隔开的“键/值”对,把列表放到花括号内。键和值成对出现并以冒号分隔。看这个例子:{"name":"green mouse", "price":150}。注意到名字和值都是表达式,但是用来检索的名字就必须是字符串类型的。

4 检索变量
_1 顶层变量

为了访问顶层的变量,可以简单地使用变量名。


_2 从哈希表中检索数据

如果有一个表达式的结果是哈希表,那么我们可以使用点和子变量的名字得到它的值.

下面这些示例它们含义都是相等的:book.author.name, book["author"].name, book.author.["name"], book["author"]["name"]

如果我们想 指 定 同一个表达式 的 子变量,那么还有另外一种语法格式 :在方括号中可以给出任意长度字符串的表达式。在上面这个数据模型示例中你还可以这么来获取 title:book[test] :这里的test是根元素test中的值.

_3 从序列中检索数据

这和从哈希表中检索是相同的,但是你只能使用方括号语法形式来进行,而且方括号内的表达式最终必须是一个数字而不是字符串。在第一章的数据模型示例中,为了获取第一个动物的名字(记住第一项数字索引是 0 而不是 1)可以这么来写:animals[0].name。


_4 特殊变量

特殊变量是由 FreeMarker 引擎本身定义的,为了使用它们,可以按照如下语法形式来
进行:.variable_name。
通常情况下是不需使用特殊变量,而对专业用户来说可能用到。所有特殊变量的说明可
以参见参考手册。


5 字符串操作

_1 插值(或连接)

可以在字符串的文字中使用${…}(#{…})。${...}的作用和在文本区的是相同的。

也可以使用+号来达到类似的效果,这是比较老的方法,也叫做字符串连接。


_2 获取一个字符

user[0]

获取一定范围内的字符,比如${user[1..4]}和${user[4..]}。然而现在这种使用方法已经被废弃了,作为它的替代,可以使用内建
函数 substring,

6 序列操作
_1 连接

序列的连接可以使用+号来进行,例如:

<#list ["Joe", "Fred"] + ["Julia", "Kate"] as user> 
- ${user} 
</#list> 
- Joe 
- Fred 
- Julia 
- Kate 

_2 序列切分

使 用 [firstindex..lastindex] 可 以 获 取 序 列 中的一部分 ,这里的firstindex 和lastindex 表达式的结果是数字。如果seq 存储序列"a", "b", "c", "d", "e", "f",那么表达式 seq[1..4]将会是含有"b", "c", "d", "e"的序列(索引为 1 的项是"b",索引为 4 的项是"e")。 lastindex 可以被省略,那么这样将会读取到序列的末尾。如果 seq 存储序列"a", "b", "c", "d", "e", "f",那么 seq[3..]将是含有"d", "e", "f"的序列。

7 哈希表操作
_1 连接

像连接字符串那样,也可以使用+号的方式来连接哈希表。如果两个哈希表含有键相同的项,那么在+号右侧的哈希表中的项目优先。

<#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

8 算数运算
有时我们只想获取计算结果的整数部分,这可以使用内建函数 int 来解决。
${(x/2)?int} 
${1.1?int} 
${1.999?int} 
${-1.1?int} 
${-1.999?int} 

9 比较运算
测试两个值相等使用=(或者采用 Java 和 C 语言中的==,二者是完全等同的。) 测试两个值不等使用!=。

FreeMarker 解释>的时候可以把它当作 FTL 标签的结束符。为了避免这种问题,不得不将表达式放到括号内:<#if (x > y)>,或者可以在比较关系处使用>和<:<#if x > y>。可以使用 lt 代替<,lte代替<=,gt 代替>,gte 代替>=, 由于历史遗留的原因,FTL 也支持\lt, \lte, \gt 和 \gte,使用他们和使用不带反斜杠的效果一样。

10 逻辑操作

11 内建函数
内建函数以?形式提供变量的不同形式或者其他信息。使用内建函数的语法和访问哈希表子变量的语法很像,除了使用?号来代替
点,其他的都一样。例如得到字符串的大写形式:user?upper_case。

示例:
${test?html} 
${test?upper_case?html} 
假设字符串 test 存储”Tom & Jerry”,那么输出为:
Tom & Jerry 
TOM & JERRY 

12 方法调用
${repeat("What", 3)} 
将会打印出:
WhatWhatWhat 

13 处理不存在的值

_1 默认值
使用形式 概 览 : unsafe_expr!default_expr 或 unsafe_expr! 或(unsafe_expr)!default_expr 或(unsafe_expr)!
这个操作符允许你为可能不存在的变量指定一个默认值。

例如,假设下面展示的代码中没有名为 mouse 的变量:

${mouse!"No mouse."} 
<#assign mouse="Jerry"> 
${mouse!"No mouse."}
将会输出
No mouse. 
Jerry 
默认值可以是任何类型的表达式,也可以不必是字符串。你也可以这么写:hits!0或 colors!["red", "green", "blue"]。默认值表达式的复杂程度没有严格限制,你还可以这么来写:cargo.weight!(item.weight * itemCount + 10) 。

_2 检测不存在的值
使用形式概览:unsafe_expr??或(unsafe_expr)?? 这个操作符告诉我们一个值是否存在。基于这种情况,结果是 true 或 false。
示例如下,假设并没有名为 mouse 的变量:
<#if mouse??> 
 Mouse found 
<#else> 
 No mouse found 
</#if> 
Creating mouse... 
<#assign mouse = "Jerry"> 
<#if mouse??> 
 Mouse found 
<#else> 
 No mouse found 
</#if> 
No mouse found 
Creating mouse... 
 Mouse found

14 括号
括号可以用来给表达式分组。示例如下:
 <#-- 输出是: --> 
${3 * 2 + 2} <#-- 8 --> 
${3 * (2 + 2)} <#-- 12 --> 
${3 * ((2 + 2) * (1 / 2))} <#-- 6 --> 
${"green " + "mouse"?upper_case} <#-- green MOUSE --> 
${("green " + "mouse")?upper_case} <#-- GREEN MOUSE --> 
<#if !( color = "red" || color = "green")> 
 The color is nor red nor green 
</#if> 

15 表达式中的空格
FTL 忽略表达式中的多余空格

16 操作符的优先级

插值
插值的使用语法是:${expression},expression 可以是所有种类的表达式(比如${100 + x})。
插值是用来给插入具体值然后转换为文本(字符串)。插值仅仅可以在两种位置使用:
文本区(如<h1>Hello ${name}!</h1> )和字符串表达式(如<#include "/footer/${company}.html">)中。

如果插值在文本区(也就是说,不再字符串表达式中),如果 escapse 指令起作用了,即将被插入的字符串会被自动转义。

<#escape x as x?html> 
 ... 
 <p>Title: ${book.title}</p> 
 <p>Description: 
<#noescape>${book.description}</#noescape></p> 
 <h2>Comments:</h2> 
 <#list comments as comment> 
 <div class="comment"> 
 ${comment} 
 </div> 
 </#list> 
 ... 
</#escape>







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值