模板语言语法
(1) 基本语法
表达式 | 表示 |
---|---|
${…} | 显示后端返回的数据 |
${r"…"} | 表示r后面的字符串为原生字符串,不用ftl语法解析 |
[“a”, “b”, “c”] | 定义一个序列 |
list[index] | 显示序列index索引处的元素 |
start…end | 定义值域,1…3 表示[1,2,3]序列;3…1 表示[3,2,1]序列 |
start…<end或 start…!end |
不包含尾部,1…3 表示[1,2]序列 |
start…*length | 指定长度,5…*3表示[5,6,7]序列;5…*-3表示[3,4,5]序列 |
start… | 向右无限序列 |
{ “a”: “b”, “c”: “d”} | 定义一个哈希表 |
${a.b} 或 ${a[“b”]} | 显示哈希表的值 |
. | 显示内置常量,例如: .variable_name |
[start…end] [start… [start*…**length] [start…] |
可用于按索引截取字符串 可用于按索引截取序列 |
+ | 字符串相加为拼接 数字相加为求和 序列相加合并 哈希表相加合并,键值已有后覆盖前 |
+ - * / % | 可用于数字计算 |
== != < <= > => | 可用于比较计算 |
&& || ! | 可用于逻辑计算 |
= += -= *= ++ – | 常用的赋值符 |
? | 用于使用内建函数,例如: ${“abc”?upper_case} |
! | 设置变量不存在要显示的默认值, 例如: ${user!“admin”} 如果默认为空字符串,!后可省略,例如: u s e r ! < b r / > {user!} user!<br/>{user.name!} user不能不存在,name可未定义; ${(user.name)!} user与name都可不存在 |
?? | 判断变量是否存在;例如 <#if user??>#if> |
<#…>#…> | 内置的指令标签 |
<@…>@…> | 自定义指令(宏)的调用 |
定义字符中的转义符
转义序列 | 含义 |
---|---|
\" |
引号 (u0022) |
\' |
单引号(又称为撇号) (u0027) |
\{ |
起始花括号:{ |
\\ |
反斜杠 (u005C) |
\n |
换行符 (u000A) |
\r |
回车 (u000D) |
\t |
水平制表符(又称为tab) (u0009) |
\b |
退格 (u0008) |
\f |
换页 (u000C) |
\l |
小于号:< |
\g |
大于号:> |
\a |
&符:& |
\x*Code* |
字符的16进制 Unicode 码 (UCS 码) |
(2) 基本常用指令
a. 判断指令
-- if elseif else
<#if key == 1>
-- key=1时显示
<#elseif key == 2>
-- key=2时显示
<#else>
-- 其他情况时显示
#if>
-- switch case
<#switch key>
<#case 1>
-- key=1时显示
<#break>-- 有该标签时当key=1时不会判断下面其他条件
<#case 2>
-- key=2时显示
<#break>
<#default>
-- 其他情况时显示
#switch>
b. 遍历指令
-- list遍历 list要遍历的集合,item为遍历出的单个数据 <#else>可选
<#list list as item>
${item} -- 获取单个数据展示
<#else>
-- 集合为空时显示
#list>
-- list遍历
<#list list as item>
${item} <#sep>, #sep> -- <#sep>可为每个遍历出的元素之前添加分割元素
#list>
-- list遍历
<#list list as item>
${item}
<#if item == "C">
<#break> -- <#break>可在遍历过程中停止之后的遍历
#if>
#list>
-- list遍历: 遍历项 索引(0开始) 行号(1开始) 单双行(odd/even)
<#list list as item>
${item} ${item?index} ${item?counter} ${item?item_parity}
#list>
-- map遍历
<#list map?keys as key>
${key} ${map[key]}
#list>
(3) 高级指令
a. 定义变量
-- 创建新常量及覆盖已有变量,in namespace指定模板命名空间(import标签设置),也就是设置指定命名空间(模板)的常量
<#assign name1="value1" name2="${key}" .... in namespace>
${name1} ${name2} ${key}
<#assign name>
<#list list as item>
${item}
#list>
#assign>
-- 设置全局变量,在所有的 命名空间 中都可用
<#global name1="value1" name2="${key}" ...>
<#global name>
value
#global>
-- 设置局部变量,
<#local name1="value1" name2=${key} ...>
<#local name>
value
#local>
b. 异常处理
<#attempt>
-- 未抛异常显示
<#recover>
-- 抛异常显示
#attempt>
-- 停止页面渲染,后台抛出异常
<#stop reason>
c 文本处理
-- 去除文本空行及每行前后端的空字符串
<#compress>
${key}
#compress>
-- 把所有引入的值(${key}) 值做 x?html 处理. x?html可换为其他表达式
<#escape x as x?html>
${key}
<#noescape> -- 不做 x?html 处理
${key}
#noescape>
#escape>
-- 不使用ftl语法解析文本
<#noparse>
#noparse>
d. 剥离空白
-- 这些指令在行内的放置不重要,行首行尾中间都一样。
<#t> -- 忽略本行中首和尾的所有空白
<#lt> -- 忽略本行中首部所有的空白。
<#rt> -- 忽略本行中尾部所有的空白。
<#nt> -- 禁用行中出现的 剥离空白,去除t, rt,lt的效果
e. 其他
-- 刷新渲染页面
<#flush>
-- 标注模板的信息,必须是模板的第一句代码
<#ftl param1=value1 param2=value2 ...>
-- 常用参数有:
-- encoding ="utf-8" 编码集
-- strip_whitespace =true 设置剥离空白,设置为true时ftl标签不占行
-- strip_text = false 从模板中删除所有顶级文本
-- ns_prefixes 关联结点命名空间前缀的哈希表
-- attributes 关联模板任意属性(名-值对)的哈希表
-- 定义函数 name为方法名param为参数,returnValue为返回的值
<#function name param1 param2 ...> -- 可使用...定义可变参数
-- 可根据参数进行逻辑处理,可用<#local a=1>定义常量,也可直接采用引入的值
<#return returnValue>
#function>
-- 引入一个库 path为模板路径,hash为引用名称,可以使用 hash.xxx 方式使用path路径下模板的定义的常量,函数等
<#import path as hash>
${hash.key}
-- 引入其他模板数据,path为模板路径,options可选配置参数
<#include path options>
-- options(encoding="utf-8", parse=true)可选参数:
-- encoding 设置编码集
-- parse = true 是否采用ftl语法解析引入的模板
-- ignore_missing = true 是否模板不存在时压制错误
-- 设置一个配置信息
<#setting name=value>
-- 可选参数:
-- locale 输出的本地化(语言),可以影响数字,日期等显示格式.可以配置多个,用下滑线分割,例如:en, en_US,en_US_MAC
-- number_format 数字格式化,值可为number(默认的),computer,currency, percent;支持 ##.## 格式保留小数位数
-- boolean_format 以逗号分隔的一对字符串来分别展示true和false值,例如:"Y,N"
-- date_format, time_format, datetime_format
-- time_zone 设置时区
-- sql_date_and_time_time_zone
-- url_escaping_charset
-- output_encoding
-- classic_compatible
f. 宏变量
-- m为调用名称,p为参数,可多个
<#macro m p1 p2 >
-- 可在此处添加宏调用所展示的数据,可使用ftl指令及常量和变量等
${p} -- 参数的获取
#macro>
-- 宏的调用
<@m p1="zp1" p2="zp2"/>
<@m "zp1" "zp2"/>
-- 设置不定参,接收到的类型为哈希表
<#macro m p... >
<#list p?keys as i>
${i} ${p[i]}
#list>
#macro>
-- 可通过k=v的方式添加多个参数
<@m p1="zp1" p2="zp2"/>
<#macro m>
<#nested> -- 可直接引入<@m>@m>标签体中的内容,可以多次被调用
#macro>
<@m p="zp1">嵌套内容@m>
-- 循环变量
<#macro m p>
<#nested p+1,p+2,p+3>
#macro>
<@m p=3 ; a,b,c>
${a} ${b} ${c}
@m>
<#macro m>
12345
<#return> -- 标签后的文本不会显示
67890
#macro>
<@m/>
内置常量
常量 | 描述 |
---|---|
.current_template_name | 当前页面模板名 |
.data_model | 直接访问数据模型的哈希表,也就是process方法设置的map数据 |
.error | 用在<#recover>标签后面,用于存储异常信息 |
.globals | 全局变量的哈希表,可通过${.globals[“key”]} 获取全局变量值 |
.lang | 获取当前本地化设置语言的值 |
.locale | 获取当前本地化设置的值 |
.locale_object | 以 java.util.Locale 对象返回本地化设置的当前值 |
.locals | 局部变量的哈希表 |
.main | 主命名空间的哈希表 |
.main_template_name | 顶级模板的名称 |
.namespace | 当前 命名空间 的哈希表,无全局变量 |
.node | 可以用访问者模式(也就是用 visit , recurse 等指令)处理的当前结点。 而且,当使用 FreeMarker XML Ant 任务 时, 它初始存储根结点 |
.now | 返回当前的日期-时间 |
.output_encoding | 返回当前输出字符集的名称;没有指定输出字符集时这个特殊变量是不存在的 |
.template_name | 模板名称,但当 nested 被调用时,它会变成模板所属当前命名空间的名字 |
.url_escaping_charset | URL转义的字符集,没指定则不存在 |
.vars | 表达式 .vars.foo 返回和表达式 foo 相同的变量 |
.version | 获取freemarker版本号 |
内置函数
(1) 字符串
函数 | 描述 |
---|---|
boolean | 字符串转为布尔值,由 boolean_format 设置格式 |
cap_first | 字符串首字母大写 |
uncap_first | 字符串首字母小写 |
capitalize | 字符串中所有单词首字母大写 |
chop_linebreak | 去除字符串末尾的\n |
contains(“str”) | 判断字符串是否包含str字符串 |
date time datetime |
字符串转时间或日期 datetime[“format”] 可指定日期格式 |
ends_with(“ends”) | 判断字符串是否以 ends 结尾 |
starts_with(“starts”) | 判断字符串是否以 starts开头 |
ensure_ends_with(“ends”) | 返回以 ends结尾字符串,原有直接返回,没有加上返回 |
ensure_starts_with(“starts”) | 返回以 starts开头字符串,原有直接返回,没有加上返回 |
groups | 只作用于内建函数 matches 的结果 |
html | 字符串按照HTML标记输出。例如; < 转换为< |
xhtml | 字符串作为XHTML格式文本 |
xml | 字符串作为XML格式文本 |
index_of(“index”) | 返回index在字符串中第一次出现的索引 |
j_string | 根据Java语言字符串转义规则来转义字符串 |
js_string | 根据JavaScript语言字符串转义规则来转义字符串 |
json_string | 根据JSON语言的字符串规则来转义字符串 |
keep_after(“str”) | 移除字符串中第一次出现str之前的部分 |
keep_after_last(“str”) | 移除字符串中最后一次出现str之前的部分 |
keep_before | 移除字符串中第一次出现str之后的部分 |
keep_before_last | 移除字符串中最后一次出现str之后的部分 |
remove_beginning(“begin”) | 移除首部begin,首部不为begin返回原字符串 |
remove_ending(“end”) | 移除尾部end,首部不为end返回原字符串 |
last_index_of(“index”) | 返回index在字符串中最后一次出现的索引 |
left_pad(10,“0”) | 不够10的字符串向前补0,第二参数可选,默认空格 |
right_pad(10,“0”) | 不够10的字符串向后补0,第二参数可选,默认空格 |
length | 获取字符串长度 |
lower_case | 字符串转小写 |
upper_case | 字符串转大写 |
matches("[0-9]*") | 正则匹配,返回布尔类型或匹配到的字符串列表 |
number | 字符串转化为数字格式 |
replace(“a”, “b”) | 字符串中的a替换为b |
rtf | 字符串作为富文本(RTF 文本) |
split(",") | 以,分割字符串 |
string | 仅仅返回和其内容一致的字符串 |
trim | 去掉字符串首尾的空格 |
url | URL字符串进行转义 |
url_path | 它和 url 相同,只是它不转义斜杠 (/ )字符。 |
word_list | 获取单词列表,按单个或多个空格分隔 |
通用标识,以下函数可添加一个参数进行配置
内建函数 | i (忽略大小写) |
r (正则表达式) |
m (多行模式) |
s (dot-all模式) |
c (空白和注释) |
f (仅第一个) |
---|---|---|---|---|---|---|
replace |
是 | 是 | 仅 r |
仅 r |
仅 r |
是 |
split |
是 | 是 | 仅 r |
仅 r |
仅 r |
否 |
matches |
是 | 忽略 | 是 | 是 | 是 | 否 |
keep_after |
是 | 是 | 是 | 是 | 是 | 忽略 |
keep_after_last |
是 | 是 | 是 | 是 | 是 | 忽略 |
keep_before |
是 | 是 | 是 | 是 | 是 | 忽略 |
keep_before_last |
是 | 是 | 是 | 是 | 是 | 忽略 |
ensure_starts_with |
是 | 忽略 | 是 | 是 | 是 | 忽略 |
(2) 数字
函数 | 描述 |
---|---|
abs | 绝对值 |
c | 根据程序语言的用法来进行格式化 |
is_infinite | 判断数字是否是无限浮点数 |
is_nan | 判断数字是否是浮点数NaN |
lower_abc | 将数字转为字母1->a… 当大于z时转换为aa,ab… |
upper_abc | 将数字转为字母1->A… 当大于Z时转换为AA,AB… |
round | 四舍五入 |
floor | 舍弃小数点后的整数,向负无穷舍弃 |
ceiling | 进1,向正无穷进位 |
string | 数字转字符串,通过 number_format 和 locale 设置的默认格式 |
(3) 日期
函数 | 描述 |
---|---|
date | 只有年月日的日期 |
time | 只有时分秒的时间 |
datetime | 含有年月日时分秒的日期 |
date_if_unknown | 不知道类型时用date |
time_if_unknown | 不知道类型时用time |
datetime_if_unknown | 不知道类型时用datetime |
iso_… | 按格式转换日期为字符串 |
string[“yyyy-MM-dd HH:mm:ss”] | 按格式转换日期为字符串 |
(4) 布尔值
函数 | 描述 |
---|---|
c | 根据程序语言的用法来进行格式化 |
string(“yes”, “no”) | 布尔转字符串,可指定格式 |
then(whenTrue, whenFalse) | 类似三元运算符 |
(5) 集合
函数 | 描述 |
---|---|
chunk(4, ‘-’) | 大集合截取为长度为4的多个小集合,不够用-补 第二个参数为可选,不设置最后一个小集合不填充 |
first | 获取第一个元素 |
last | 获取最后一个元素 |
join(",","-",".") | 用分隔符拼接所有元素,第一二参数为可选 第二个集合为空时显示的字符串,第三参数为最后显示的字符串 |
reverse | 反转集合 |
seq_contains(“a”) | 判断元素是否存在集合中 |
seq_index_of(“a”) | 返回第一次出现指定元素的索引 |
seq_last_index_of | 返回最后一次出现指定元素的索引 |
size | 获取集合大小 |
sort | 以升序方式返回集合。 |
sort_by(“name”) | 按指定字段升序排序集合 |
(5) 哈希表
函数 | 描述 |
---|---|
keys | 获取所有哈希表的键值 |
values | 获取所有哈希表的值 |
(6) 结点(对于XML)
函数 | 描述 |
---|---|
ancestors | 一个包含所有结点祖先结点的序列,以直接父结点开始,以根结点结束。 |
children | 一个包含该结点所有子结点(也就是直接后继结点)的序列。 |
node_name | 返回用来决定哪个自定义指令来调用控制这个结点的字符串。 |
node_namespace | 返回结点命名空间的字符串。 |
node_type | 描述结点类型的字符串。 |
parent | 在结点树中,返回该结点的直接父结点。 |
root | 该结点所属结点树的根结点。 |
(7) 循环变量
函数 | 描述 |
---|---|
counter | 获取从1开始的索引 |
has_next | 判断是否有下一个元素 |
index | 获取从0开始的索引 |
is_even_item | 判断是否时偶数行 |
is_odd_item | 判断是否时奇数行 |
is_first | 判断是否是第一个 |
is_last | 判断是否是最后一个 |
item_cycle(“1”,“2”,“3”) | 循环输出参数值 |
item_parity | 获取单偶标识,odd/even |
item_parity_cap | 获取单偶标识,Odd/Even |
(8) 独立类型
函数 | 描述 |
---|---|
switch(case1, result1, case2, result2, … , defaultResult) | 匹配不同值输出不同结果 |
(9) 高级函数
函数 | 描述 |
---|---|
api.myMethod(“parameter”) has_api |
调用模板引入对象方法 判断是否可以使用api函数 |
byte, double, float, int, long, short | 类型转换, long也可以转换时间日期 |
eval | 求一个表达式(“1+1”?eval)字符串的值 |
has_content | 判断一个变量是否有值,是否为null为空 |
interpret | 能够将文本的值解析为宏 |
namespace | 返回和宏变量或函数变量关联的命名空间 只能和宏和函数一起来用它 |
new | 模版里创建一个java对象,而不是传入进去的 |
number_to_date number_to_time number_to_datetime |
数字转时间日期类型 |
is_…
内建函数 | 如果值是 … 时返回 true |
---|---|
is_string |
字符串 |
is_number |
数字 |
is_boolean |
布尔值 |
is_date |
不要使用它!使用 is_date_like 来代替, 它们是相同的。往后也许会修改它的含义为 date_only 。 |
is_date_like |
日期,也就似乎日期,时间或者日期-时间, 亦或者是未知精确类型的日期(从 FreeMarker 2.3.21 版本开始) |
is_date_only |
日期 (没有时间部分) (从 FreeMarker 2.3.21 版本开始) |
is_time |
时间 (没有年-月-日部分) (从 FreeMarker 2.3.21 版本开始) |
is_datetime |
日期-时间 (包含年-月-日和时间两者) |
is_unknown_date_like |
不清楚是日期或时间或日期-时间的日期 |
is_method |
方法 |
is_transform |
变换 |
is_macro |
宏或函数(当然,由于历史问题,也对函数有效) |
is_hash |
哈希表 (包含扩展的哈希表) |
is_hash_ex |
扩展的哈希表 (支持 ?keys 和 ?values ) |
is_sequence |
序列 |
is_collection |
集合 (包含扩展的集合) |
is_collection_ex |
扩展的集合 (支持 ?size ) |
is_enumerable |
序列或集合 |
is_indexable |
序列 |
is_directive |
指令类型 (例如宏 或 TemplateDirectiveModel , TemplateTransformModel , 等…), 或者函数 (由于历史问题) |
is_node |
结点 |