变量类型
String "Foo" or 'Foo'
Number 123.4
Date
Boolean true,false
sequence ["foo", "bar", 123.45] 索引访问
hash {"name":"green mouse", "price":150}
指令:
-
预定义指令:
-
assign ,定义变量
1. <#assign name1=value1 name2=value2 ... nameN=valueN> 2. <#assign same as above... in namespacehash> 3. <#assign name> capture this </#assign> 4. <#assign name in namespacehash> capture this </#assign>
-
attempt,recover,如果attempt中产生异常,那么会执行recover中的语句
<#attempt> ....... <#recover> ....... </#attempt>
-
ftl
<#ftl param1=value1 param2=value2 ... paramN=valueN> param代指参数,如encoding,attributes,output_format
-
function,定义函数
<#function 函数名 变量1 变量2 ...> 例子 <#function add x y> ... <#return x+y> <#return 返回结果> </#function> ... 调用 ${add(10,20)} </#function> 结果:30
-
global,定义全局变量
1.<#global name=value> 2.<#global name1=value1 name2=value2 ... nameN=valueN> 3.<#global name> capture this </#global> 如果存在变量冲突,${.globals.变量名}调用全局变量
-
if,else,else if,条件语句
<#if condition1> ... <#elseif condition2> ... <#else> ... </#if>
-
import ,导入其他模板中的变量
<#import "/libs/mylib.ftl" as my> 路径相对于模板根目录 <@my.copyright date="1999-2002"/>
-
incluede,引入其他模板
1.ftl 输出: Some test <h1>Some test</h1> hello <#include "/common/2.ftl"> 2.ftl <h1>hello</h1>
-
list
<#list sequence as item> <#items as 变量名> ---嵌入list中循环 ... ${变量名} <#else> //list为空时执行 </#items> ... </#list> <#list hash as key, value> ... </#list>
-
.
- <#t> 忽略前后空格
- <#lt>忽略前空格
- <#rt>忽略后空格
-
-
用户自定义指令:
-
定义宏
<#macro directivename >
Hello Joe!
</#macro> -
使用宏
<@directivename >…</@>
<@directivename />
结果: Hello Joe! -
为宏定义参数
定义宏: <#macro directivename person>
Hello ${person}!
</#macro>
使用: <@directivename person=“Fred”/>
结果: Hello Fred! -
Nested content
<#nested>用法定义宏 <#macro border> <table border=4 cellspacing=0 cellpadding=4> <tr> <td> <#nested> </tr> </td> </table> </#macro> 模板使用 <@border>The bordered text</@border> 结果 <table border=4 cellspacing=0 cellpadding=4> <tr> <td> The bordered text </td> </tr> </table>
-
定义宏 <#macro do_thrice> <#nested> <#nested> <#nested> </#macro> 模板使用 <@do_thrice> Anything. </@do_thrice> 结果 Anything. Anything. Anything.
定义模板变量
- plain var 模板中访问(可以引入其他模板)
- local var macro或函数中(覆盖同名plain var)
- loop var(隐藏plain var,local var,内部var隐藏外部var) <#list xs as x>…</#list> x就是loop var
- global var 所有模板都可访问
user=“jerry”(后端传递)
${user} jerry
<#assign user=“tom”> tom
${.globals.user} jerry
引入其他模板变量
<#import "文件名.ftl" as e> 使用 ${e.变量名}
-
表达式操作
访问hash: user.name , user["name"]
访问sequence: products[0]
-
字符串操作
- 获取值 ${user}
- 获取字符 ${name[0]}
- 截取字符串 <#assign name = “ABCDEF”>
- ${s[2…3]} CD
- ${s[2…<4]} CD
- ${s[2…*3]} CDE
- ${s[2…*100]} CDEF
- ${s[2…]} CDEF
-
Sequence 操作
- <#list [“Joe”, “Fred”,“Julia”, “Kate”] as user> ${user} </#list>
Joe Fred Julia Kate
<#assign seq = ["A", "B", "C", "D", "E"]> <#list seq[1..3] as i>${i}</#list> 结果: BCD
-
hash操作
-
<#assign ages = {“Joe”:23, “Fred”:25}
Joe is ${ages.Joe}
Fred is ${ages.Fred}Joe is 30 Fred is 25
-
算术运算
-
比较
x==y x!=y x < y x <= y x > y x >= y x lt y x lte y x gt y x gte y
-
逻辑运算 || && !
<#if x < 12 && color == "green">.... </#if>
-
Built-in
String ="Tom & Jerry" ${String ?upper_case} TOM & JERRY ${String ?html} Tom & Jerry ${String ?upper_case?html} TOM & JERRY Sequence =["foo","bar","baz"] ${Sequence ?size} 3 ${Sequence ?join(", ")} foo, bar, baz
-
默认值操作
${mouse!"No mouse."} No mouse. <#assign mouse="Jerry"> ${mouse!"No mouse."} Jerry
-
错误变量,无效变量
假定mouse不存在 <#if mouse??> Mouse found <#else> No mouse found </#if> 结果:No mouse found
Interpolations
<h1>Hello ${name}!</h1>
<#include "/footer/${company}.html">
错误用法: <#if ${big}>...</#if>
<#if "${big}">...</#if>
正确用法 :<#if big>...</#if>
创建configuration实例
-
创建Configuration
Configuration cfg = new Configuration(Configuration.VERSION_2_3_27)
-
设置模板的目录
cfg.setDirectoryForTemplateLoading(new File("/where/you/store/templates"))
-
设置编码格式
cfg.setDefaultEncoding("UTF-8")
-
设置模板异常处理
cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
-
异常产生时是否产生日志
cfg.setLogTemplateExceptions(true/false);
-
是否包装未检查的异常
cfg.setWrapUncheckedExceptions(true/false);
-
创建数据模型(javaBean / java.lang / java.util)
java.lang.String ------------------- strings. java.lang.Number subclasses ---------numbers. java.lang.Boolean -------------------boolean values. java.util.Date and its subclasses ---date/time values java.util.List or Java arrays -------sequences. java.util.Map with String keys ------hashes.
数据源
1. Map数据源: Map<String, Object> root = new HashMap<>() 2. javaBean数据源:Product latest = new Product();
-
获取模板
Template temp = cfg.getTemplate("test.ftlh");
-
填充数据
Writer out = new OutputStreamWriter(System.out); temp.process(map/bean, out);
Configuration应设置为单例,重新创建Configuration会丢失缓存
Build-in(内置方法)
用法:${ expression?指令 }
-
string
- boolean(字符串转boolean),string必须是true/false, 大小写敏感
- cap_first,字符串首字母大写
- capitalize,单词首字母大写
- contains(“abc”),判断是否存在字符串abc
- ends_with(“abc”),判断字符串是否以abc结尾
- replace(“abc”,“def”)将字符串中的abc替换为def
- split(“abc”)将字符串根据abc切割成字符串数组
- trim(" ab c ")移除"ab c"开头和结尾的空格
-
number
- abs ,数字绝对值
- round 小数点后5~ 9向上数取整, 0~4向下取整
- floor 向下取整
- ceiling 向上取整
- string 数字转为字符串
- string(“0”) 保留整数部分1位
- string(".##") 保留小数点2位
-
date
- date 保留年月日
- time 保留时间
-
boolean
- expression?string(“yes”, “no”) 根据expression=true /false 返回yes/no , foo是数字返回第一个字符串
- expression?then(exp1, exp2) 根据expression=true/false 返回exp1/exp2
-
sequences
-
chunk
<#assign seq = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']> <#list seq?chunk(4) as row> <#list row as cell>${cell} </#list> </#list> <#list seq?chunk(4, '-') as row> <#list row as cell>${cell} </#list> </#list> 结果: a b c d e f g h i j a b c d e f g h i j - -
-
first ,返回数组中第一个值
-
join (三个参数)
-
第一个参数,数组中每个值尾部添加
~~例子 <#assign colors = ["red", "green", "blue"]> ${colors?join(", ")} 结果: red, green, blue
-
第二个参数,默认为空,当数组为空时,用该参数代替
-
第三个参数,默认为空,数组结尾添加该参数
-
-
reverse ,翻转数组
-
seq_contains(),数组中是否包含指定值
-
sort,从小到大排序
-
sort_by(key),根据key从小到大排序,
-
-
hash
1. keys<#assign myHash = { "name": "mouse", "price": 50 }> <#list myHash?keys as k> ${k} </#list> 结果: name price 2. values <#assign myHash = { "name": "mouse", "price": 50 }> <#list myHash?values as v> ${v} </#list> 结果: mouse 50
-
loop
- index, 数组下标,从0开始
- counter,下标,从1开始
- has_next,判断当前元素是否是最后一个元素
- item_parity_cap,根据当前元素奇偶性返回"odd"/“even”