FreeMarker使用简记

概念

FreeMarker是一款模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页、电子邮件、配置文件、源代码等)的通用工具。

基础指令

If指令

if指令可以条件性的跳过部分模板块

条件包括相等(==),不相等(!=),……

1
2
3
4
5
6
7
<#if animals.python.price < animals.elephant.price>
Pythons are cheaper than elephants today.
<#elseif animals.elephant.price < animals.python.price>
Elephants are cheaper than pythons today.
<#else>
Elephants and pythons cost the same today.
</#if>

List指令

List指令的一般形式是<#list sequence as loopVariable>repeatThis</#list>

1
2
3
4
5
<ul>
<#list misc.fruits as fruit>
<li>${fruit}
</#list>
</ul>

或者

1
2
3
4
5
6
7
<#list misc.fruits>
<ul>
<#items as fruit>
<li>${fruit}
</#items>
</ul>
</#list>

List还可以结合<#sep>和<#else>指令
<#sep></#sep>表示输出以其内容分割
<#else>表示当list输出为空的时候的输出

1
2
3
4
5
6
7
8
9
10
<#list misc.fruits>
<p>Fruits:
<ul>
<#items as fruit>
<li>${fruit}<#sep> and</#sep>
</#items>
</ul>
<#else>
<p>We have no fruits.
</#list>

Include指令

Include指令可以直接在模板中插入其他文件内容

1
2
3
4
5
6
7
8
9
10
<html>
<head>
<title>Test page</title>
</head>
<body>
<h1>Test page</h1>
<p>Blah blah...
<#include "/copyright_footer.html">
</body>
</html>

内嵌指令

例如:

user?upper_case 提供user的大写版本

animal.name?cap_first 提供animal.name的首字母大写版本

user?length 提供user的字符数目

animals?size 提供集合animals的元素个数

默认值

!后面为空缺时的默认值

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

结合??,当user不存在的时候,整个模板块都不会显示

1
<#if user??><h1>Welcome ${user}!</h1></#if>

输出格式

1
<#ftl output_format="HTML">

修改HTML为XML则输出XML文件

类型

整体结构

模板是用FTL语言写的。

一个模板由以下几部分组成:

  • Text:原样显示的文本。图示蓝色部分。

  • Interpolation:插入。这些地方会被计算再显示。图示橙色部分。

  • FTL tags:FreeMarker指令。不会显示。图示黄色部分。

  • Comments:注释。不会显示。图示绿色部分。

    template

提示:FTL严格区分大小写。

​ FTL指令不能嵌套,也不会在插入之间。

编程范例

ProjectStruct

主程序

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
public class App
{
public static void main(String[] args) throws Exception {
//获取项目根目录路径
String path=Class.class.getClass().getResource("/").getPath();
/* ------------------------------------------------------------------------ */
/* You should do this ONLY ONCE in the whole application life-cycle: */
/* Create and adjust the configuration singleton */
Configuration cfg = new Configuration();
cfg.setDirectoryForTemplateLoading(new File(path+"/ftl")); //需要文件夹绝对路径
cfg.setDefaultEncoding("UTF-8");
cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
/* ------------------------------------------------------------------------ */
/* You usually do these for MULTIPLE TIMES in the application life-cycle: */
/* Create a data-model */
Map root = new HashMap();
root.put("user", "Big Joe");
Product latest = new Product();
latest.setUrl("products/greenmouse.html");
latest.setName("green mouse");
root.put("latestProduct", latest);
/* Get the template (uses cache internally) */
Template temp = cfg.getTemplate("Product.ftl");
/* Merge data-model with template */
Writer out = new OutputStreamWriter(System.out);
temp.process(root, out);
// Note: Depending on what `out` is, you may need to call `out.close()`.
// This is usually the case for file output, but not for servlet output.
}
}

实体类

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
public class Product {
private String url;
private String name;
// As per the JavaBeans spec., this defines the "url" bean property
// It must be public!
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
// As per the JavaBean spec., this defines the "name" bean property
// It must be public!
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

模板文件

1
2
3
4
5
6
7
8
9
10
11
<html>
<head>
<title>Welcome!</title>
</head>
<body>
<h1>Welcome ${user}!</h1>
<p>Our latest product:
<a href="${latestProduct.url}">${latestProduct.name}</a>!
</body>
</html>

测试结果

1
2
3
4
5
6
7
8
9
10
11
<html>
<head>
<title>Welcome!</title>
</head>
<body>
<h1>Welcome Big Joe!</h1>
<p>Our latest product:
<a href="products/greenmouse.html">green mouse</a>!
</body>
</html>

变量类型

字符:java.lang.String

数字:java.lang.Number

逻辑值:java.lang.Boolean

日期/时间值:java.util.Date

数组:java.util.List

字符键哈希:java.util.Map

自定义哈希:自定义类

热评文章