freemarker

2022-07-18

freemarker

什么是freemarker

	FreeMarker 是一款 模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页,电子邮件,配置文件,源代码等)的通用工具。 它不是面向最终用户的,而是一个Java类库,是一款程序员可以嵌入他们所开发产品的组件。

入门

模板+数据模型=输出

	为模板准备的数据整体被称作为 数据模型。

注:模板就相当于jsp,使用el表达式,数据模型就是后台所绑定的数据

常用指令

  1. if指令

    <#if student.gender == 0>

    <#elseif student.gener == 1>

    <#else>
    保密
    </#if>

  2. list指令

    <#list sequence as loopVariable>repeatThis</#list>

解释如下:

	相当于foreach遍历
	sequence	要遍历的值
	loopVariable	遍历值中每一个子项

例子:

	<#list misc.fruits>
	  <p>Fruits:
	  <ul>
	    <#items as fruit>
	      <li>${fruit}<#sep> and</#sep>
	    </#items>
	  </ul>
	<#else>
	  <p>We have no fruits.
	</#list>

解释如下

	<#items> 就代表上面的misc.fruits
	<#sep>		分隔符
	<#else>		如果没有内容,显示
  1. include指令

    <#include "a.html">
    将a.html的内容包含进来

使用内建函数(就是ftl的一些内置方法,?调用就行)

	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 序列中 项目 的个数

	如果在 <#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。

处理不存在的变量

  1. <h1>Welcome ${user!"visitor"}</h1>

    ! 是一种处理方式,当user存在时原值输出,不存在时输出后面的字符串

  2. <#if user??><h1>Welcome ${user}</h1></#if>

    ?? 表示当user不存在时不执行,存在时执行

  3. animals.python.price!0 仅处理price不存在的情况,当python不存在时会出错

  4. (animals.python.price)!0 处理animals和python不存在的情况

注:对于 ?? 也是同样用来的处理这种逻辑的; 将 animals.python.price?? 对比 (animals.python.price)??来看。

模板(FTL)

	文本:原样输出
	插值:即${}
	FTL标签:
	注释:<#-- -->

	直接指定值
		字符串: "Foo" 或者 'Foo' 或者 "It's \"quoted\"" 或者 'It\'s "quoted"' 或者 r"C:\raw\string"
		数字: 123.45
		布尔值: true, false
		序列: ["foo", "bar", 123.45]; 值域: 0..9, 0..<10 (或 0..!10), 0..
		哈希表: {"name":"green mouse", "price":150}
		检索变量
		顶层变量: user
		从哈希表中检索数据: user.name, user["name"]
		从序列中检索数据: products[5]
		特殊变量: .main
	字符串操作
		插值(或连接): "Hello ${user}!" (或 "Hello " + user + "!")
		获取一个字符: name[0]
		字符串切分: 包含结尾: name[0..4],不包含结尾: name[0..<5],基于长度(宽容处理): name[0..*5],去除开头: name[5..]
	序列操作
		连接: users + ["guest"]
		序列切分:包含结尾: products[20..29], 不包含结尾: products[20..<30],基于长度(宽容处理): products[20..*10],去除开头: products[20..]
	哈希表操作
		连接: passwords + { "joe": "secret42" }
		算术运算: (x * 1.5 + 10) / 2 - y % 100
		比较运算: x == y, x != y, x < y, x > y, x >= y, x <= y, x lt y, x lte y, x gt y, x gte y, 等等。。。。。。
		逻辑操作: !registered && (firstVisit || fromEurope)
		内建函数: name?upper_case, path?ensure_starts_with('/')
		方法调用: repeat("What", 3)
		处理不存在的值:
		默认值: name!"unknown" 或者 (user.name)!"unknown" 或者 name! 或者 (user.name)!
		检测不存在的值: name?? 或者 (user.name)??
		赋值操作: =, +=, -=, *=, /=, %=, ++, --

插值

	插值只能用在文本区和字符串表达式中

自定义指令

<#macro name>...</#macro>

	macro 指令自身不输出任何内容, 它只是用来创建宏变量,所以就会有一个名为 name 的变量。在 <#macro name> 和 </#macro> 之间的内容 (称为 宏定义体) 将会在使用该变量作为指令时执行

程序员通常将使用 <@...> 这称为 宏 调用。

参数

	<#macro greet person>
	  <font size="+2">Hello ${person}!</font>
	</#macro>

	<@greet person="Fred"/> and <@greet person="Batman"/>

person就是greet的一个参数

嵌套内容

	<#nested> 指令执行位于开始和结束标记指令之间的模板代码段。
  1. 自定义for循环

    宏:
    <#macro person name age>
    我是${name},今年${age}岁
    </#macro>

    <#macro for count>
    <#list 1..count?number as x>
    <#nested>
    </#list>
    </#macro>

    引用:
    <@for count = "${count}">
    <@person name="马皓楠" age=23/>
    /@for

解释如下

	for 				宏名字
	count 				宏参数
	1..count?number		遍历count次	?number转为数字
	<#nested>			指代循环体的内容
	"${count}"		后台传的数据,也可以直接写

在模板中定义变量

  1. "简单"变量

    它能从模板中的任何位置来访问,或者从使用 include 指令引入的模板访问。可以使用 assign 指令来创建或替换这些变量。因为宏和方法只是变量,那么 macro 指令 和 function 指令 也可以用来设置变量,就像 assign 那样。

  2. 局部变量

    它们只能被设置在 宏定义体内, 而且只在宏内可见。一个局部变量的生命周期只是宏的调用过程。可以使用 local指令 在宏定义体内创建或替换局部变量。

  3. 循环变量

    循环变量是由如 list 指令自动创建的,而且它们只在指令的开始和结束标记内有效。宏 的参数是局部变量而不是循环变量。

<#assign>

	<#assgin x = 1> 创建变量

	<#assgin x = x + 3>	替换变量

命名空间

	当运行FTL模板时,就会有使用 assign 和 macro 指令创建的变量的集合(可能是空的).像这样的变量集合被称为 命名空间。 简单的情况下可以只使用一个命名空间,称之为 主命名空间。

	命名空间就相当于两个不同的文件,变量彼此独立

	<#import "/lib/my_test.ftl" as my>
	<@my.copyright date="1999-2002"/>
	${my.mail}

	使用import指令,创建一个新的命名空间,然后使用as,为这个新的命名空间赋予一个变量来访问

使用<#assign>编写变量

	<#assign mail="jsmith@other.com" in my>
	${my.mail}

常见内置函数

  1. css?seq_contains("jQuery6")

    seq_contains() 某个序列中是否包含某个元素