-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathfreemarker-模板语言-指令.java
267 lines (219 loc) · 6.16 KB
/
freemarker-模板语言-指令.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
-----------
指令 |
-----------
# 使用 FTL标签来调用 指令
# 如果标签没有嵌套内容(在开始标签和结束标签之间的内容),那么可以忽略关闭标签
# 存在两种指令
* 自定义指令,使用@
<@my parameters ></@my>
* 系统指令,使用#
<#if parameters ></if>
# FreeMarker会忽略FTL标签中多余的空白标记
------------
assign |
------------
# 创建一个新的变量, 或者替换一个已经存在的变量
# 注意仅仅顶级变量可以被创建/替换 (也就是说你不能创建/替换 some_hash.subvar, 除了 some_hash)
<#assign seq = ["foo", "bar", "baz"]>
<#assign x++>
<#assign
seq = ["foo", "bar", "baz"]
x++
>
# 名称可以有双引号
# 保存输出
------------
compress |
------------
# 移除多余的空白是很有用的,它捕捉在指令体中生成的内容,然后缩小所有不间断的空白序列到一个单独的空白字符
# 如果被替代的序列包含换行符或是一段空间,那么被插入的字符也会是一个 换行符, 开头和结尾的空白符会被移除
# 有点儿压缩内容的意思
# 属性
single_line
* bool值,如果该值为 true,则会连换行都一起移除
<#compress>
...
</#compress>
------------
escape |
------------
# 会对该指令标签下${}输出的内容进行指定的编码
# 这是一个避免编写相似表达式的很方便的方法
* 它不会影响在字符串形式的插值(比如在 <#assign x = "Hello ${user}!">)
* 而且,它也不会影响数值插值 (#{...})
# Demo
<#escape x as x?html>
First name: ${firstName}
Last name: ${lastName}
Maiden name: ${maidenName}
</#escape>
* x 表示${}输出的内容
* x?html 对输出内容的处理,表示用html编码去处理,也可以换成自己定义的函数啥的
* 甚至可以让x作为map的key
<#escape x as skills[x]>....
* 其实等于
First name: ${firstName?html}
Last name: ${lastName?html}
Maiden name: ${maidenName?html}
# 关闭转义,可以在escape中嵌套#noescape指令
<#escape x as x?html>
First name: ${firstName}
<#noescape>Message: ${message}</#noescape>
</#escape>
* message 不会被转义
# 转义可以嵌套多个
<#escape x as x?html>
Customer Name: ${customerName}
Items to ship:
<#escape x as itemCodeToNameMap[x]>
${itemCode1}
${itemCode2}
${itemCode3}
${itemCode4}
</#escape>
</#escape>
* 上代码等于
Customer Name: ${customerName?html}
Items to ship:
${itemCodeToNameMap[itemCode1]?html}
${itemCodeToNameMap[itemCode2]?html}
${itemCodeToNameMap[itemCode3]?html}
${itemCodeToNameMap[itemCode4]?html}
* 嵌入的转义区块内使用非转义指令时,它仅仅不处理一个单独层级的转义
* 因此,为了在两级深的转义区块内完全关闭转义,你需要使用两个嵌套的非转义指令
------------
ftl |
------------
# 对于模板引擎的一些设置
<#ftl param1=value1 param2=value2 ... paramN=valueN>
* 参数名称固定
* 参数值是常量,不能使用变量
# 属性
encoding
* 编码
strip_whitespace
* 这将开启/关闭 空白剥离
* 合法的值是布尔值常量 true 和 false (为了向下兼容,字符串 "yes","no", "true","false" 也是可以的)
* 默认值是 true。
strip_text
* 当开启它时,当模板被解析时模板中所有顶级文本被移除
* 这个不会影响宏,指令,或插值中的文本
* 合法值是布尔值常量 true 和 false (为了向下兼容,字符串 "yes","no", "true","false" 也是可以的)
* 默认值(也就是当你不使用这个参数时)是 false
strict_syntax
* 这会开启/关闭"严格的语法"
* 合法值是布尔值常量 true 和 false (为了向下兼容,字符串 "yes","no", "true","false" 也是可以的)
* 默认值(也就是当你不使用这个参数时)是依赖于程序员对 FreeMarker 的配置, 但是对新的项目还应该是 true。
attributes
* 这是关联模板任意属性(名-值对)的哈希表, 属性的值可以是任意类型(字符串,数字,序列等)。
* reeMarker 不会尝试去理解属性的含义,它是由封装 FreeMarker(比如Web应用框架)的应用程序决定的
* 因此,允许的属性的设置是它们依赖的应用(Web应用框架)的语义
* 可以通过关联 Template 对象的 getCustomAttributeNames 和 getCustomAttribute 方法 (从 freemarker.core.Configurable 继承而来)获得属性
* 如当模板被解析时,关联 Template 对象的模板属性, 属性可以在任意时间被读取,而模板不需要被执行。 上面提到的方法返回未包装的属性值,也就是说, 使用 FreeMarker 独立的类型,如 java.util.List。
------------
global |
------------
# 设置全局变量,在所有命名空间中都可见
# 语法
<#global name=value>
<#global name1=value1 name2=value2 ... nameN=valueN>
# 如果变量名称包含特殊字符,可以用""包裹
--------------------
if, else, elseif |
--------------------
# 太简单了,不说
# 判断尽量使用括号
<#if (x > 0)>
</#if>
* 不然的话 ><会被解析为指令的结束符
# 最终的结果必须是一个bool类型,不然异常
--------------------
import |
--------------------
# 用于导入一个库
<#import "/libs/mylib.ftl" as my>
<@my.foo/>
${my.func("123")}
--------------------
include |
--------------------
# 包含
# 语法
<#include path>
<#include path options>
* path表示路径
* ptions 一个或多个这样的选项
encoding 编码
parse 是否当作ftl解析,如果为false则把内容当作纯字符串
ignore_missing 是否忽略异常,如果目标目标异常,则不会有任何输出
# 本地化模板查找
* 假设模板使用本地化 en_US 来加载, 就是美国英语,当包含其它模板时
<#include "footer.ftl">
//引擎实际上就会按照这个顺序寻找模板
footer_en_US.ftl,
footer_en.ftl
footer.ftl
* 通过程序关闭本地检索机制
//禁用本地化模板查找
configuration.setLocalizedLookup(false);
* 也可以控制这个查找的过程
configuration.setTemplateLookupStrategy(TemplateLookupStrategy);
--------------------
noparse |
--------------------
# 会忽略该指令中间的所有ftl表达式,会把它们直接当作字符串原样输出
# 模板
<#noparse>
<#list animals as animal>
<tr><td>${animal.name}<td>${animal.price} Euros
</#list>
</#noparse>
# 输出
Example:
--------
<#list animals as animal>
<tr><td>${animal.name}<td>${animal.price} Euros
</#list>
--------------------
setting |
--------------------
# 设置是影响 FreeMarker 行为的值
<#setting name=value>
# 可以设置的属性
locale
number_format
boolean_format
date_format
time_format
datetime_format
time_zone
sql_date_and_time_time_zone
url_escaping_charset
output_encoding
classic_compatible
--------------------
#switch |
--------------------
# 官方说不建议用,建议用if elseif
<#switch value>
<#case refValue1>
...
<#break>
<#case refValue2>
...
<#break>
<#case refValueN>
...
<#break>
<#default>
...
</#switch>
------------------------
t, lt, rt |
------------------------
t
* 忽略本行中首和尾的所有空白。
lt
* 忽略本行中首部所有的空白。
rt
* 忽略本行中尾部所有的空白