SpringBoot(十七) FreeMarker模板引擎 - 基本指令

如果想要页面动起来 (这里指动态网页技术,译者注),那么就要在HTML中放置能被FreeMarker所解析的特殊代码片段

  • ${…}: FreeMarker将会输出真实的值来替换大括号内的表达式,这样的表达式被称为 interpolation(插值,译者注)。
  • FTL 标签 (FreeMarker模板的语言标签): FTL标签和HTML标签有一些相似之处,但是它们是FreeMarker的指令,是不会在输出中打印的。 这些标签的名字以 # 开头。(用户自定义的FTL标签则需要使用 @ 来代替 #,但这属于更高级的话题了。)
  • 注释: 注释和HTML的注释也很相似, 但是它们使用 <#– and –> 来标识。 不像HTML注释那样,FTL注释不会出现在输出中(不出现在访问者的页面中), 因为 FreeMarker会跳过它们。

其他任何不是FTL标签,插值或注释的内容将被视为静态文本, 这些东西不会被FreeMarker所解析;会被按照原样输出出来。

更多指令 -> 请参考

if 指令

比如,假设在最初的示例中, 想向 FreeMarker 特别地问好,可其他不同:

1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html>
<html lang="en">
<body>
<#-- FreeMarker将会输出真实的值来替换大括号内的表达式 -->
<h1>Hello ${name}</h1>

<#--使用 if 指令可以有条件地跳过模板的一些片段-->
<h1><#if name == "FreeMarker">Welcome</#if></h1>
</body>
</html>

通常来讲,如果 condition 是false(布尔值),那么介于 <#if condition> 和 </#if> 标签中的内容会被略过。
详细说说 condition 的使用: == 是用来判断它两侧的值是否相等的操作符, 比较的结果是布尔值,也就是true或者false。
你也许就会猜测了, != 就是”不等于”

效果

else 指令

使用 <#else> 标签可以指定当条件为false时程序所要执行的内容。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!DOCTYPE html>
<html lang="en">
<body>
<#-- FreeMarker将会输出真实的值来替换大括号内的表达式 -->
<h1>Hello ${name}</h1>

<#--使用 if 指令可以有条件地跳过模板的一些片段-->
<h1>
<#if name == "FreeMarkerX"> <#-- 这里发生变化了 -->
Welcome
<#--使用 else 指定当条件为false时程序所要执行的内容-->
<#else>
Bye~
</#if>
</h1>
</body>
</html>

在这个示例中,如果不等于 FreeMarker 的话,将会打印出 “Bye~”。

效果

list 指令

当需要列表显示内容时,list指令是必须的。

User.java

1
2
3
4
5
6
7
8
9
10
11
/**
* @author Ray
* @date 2018/8/4 0004
*/
@Data
@AllArgsConstructor
public class User {

private String username;
private Integer age;
}

ListController.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
* @author Ray
* @date 2018/8/4 0004
*/
@Controller
public class ListController {

@GetMapping("/list")
public String list(Model model){
List<User> list = new ArrayList<>();
User user = new User("Ray", 18);
list.add(user);
model.addAttribute("list", list);
return "list";
}
}

list.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!DOCTYPE html>
<html lang="en">
<body>
<table>
<tr>
<td>name</td>
<td>age</td>
</tr>
<#list list as user>
<tr>
<td>${user.username}</td>
<td>${user.age}</td>
</tr>
</#list>
</table>
</body>
</html>

list 指令的一般格式为: <#list sequence as loopVariable>repeatThis</#list>
repeatThis 部分将会在给定的 sequence 遍历时在每一项中重复, 从第一项开始,一个接着一个。在所有的重复中, loopVariable 将持有当前遍历项的值。 这个变量仅存在于 <#list …> 和 </#list> 标签内。

效果

list 中使用内建函数

更多内建函数 -> 请参考

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE html>
<html lang="en">
<body>
<table border="1">
<tr>
<td>索引值-基于0</td>
<td>索引值-基于1</td>
<td>奇偶性</td>
</tr>
<#list list as user>
<tr>
<td>${user?index}</td>
<td>${user?counter}</td>
<td>${user?item_parity}</td>
</tr>
</#list>
</table>
</body>
</html>

效果

include 指令

使用 include 指令, 我们可以在模板中插入其他文件的内容。
假设要在一些页面中显示版权声明的信息。那么可以创建一个文件来单独包含这些版权声明, 之后在需要它的地方插入即可。比方说,我们可以将版权信息单独存放在页面文件

当修改了 copyright_footer.html 文件, 那么访问者在所有页面都会看到版权声明的新内容。
copyright_footer.html

1
2
3
4
5
6
<hr>
<i>
Copyright (c) 2018 <a href="https://qq343509740.gitee.io/">Ray blog</a>,
<br>
All Rights Reserved.
</i>

当需要用到这个文件时,可以使用 include 指令来插入:

test01.html

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

效果

处理不存在的变量

数据模型中经常会有可选的变量(也就是说有时并不存在)。 除了一些典型的人为原因导致失误外,FreeMarker 绝不能容忍引用不存在的变量, 除非明确地告诉它当变量不存在时如何处理。这里来介绍两种典型的处理方法。

这部分对程序员而言: 一个不存在的变量和一个是 null 值的变量, 对于FreeMarker来说是一样的,所以这里所指的”丢失”包含这两种情况。

方法一

不论在哪里引用变量,都可以指定一个默认值来避免变量丢失这种情况, 通过在变量名后面跟着一个 ! 和默认值。 就像下面的这个例子,当 user 不存在于数据模型时, 模板将会将 user 的值表示为字符串 “visitor”。(当 user 存在时, 模板就会表现出 ${user} 的值):

1
2
3
4
5
6
7
8
9
10
11
<html>
<head>
<title>include</title>
</head>
<body>
<h1>Test page</h1>
<p>...</p>
<#--方法一:此时 user 不存在-->
<h1>Welcome ${user!"visitor"}!</h1>
</body>
</html>

方法二

也可以在变量名后面通过放置 ?? 来询问一个变量是否存在。将它和 if 指令合并, 那么如果 user 变量不存在的话将会忽略整个问候的代码段:

1
2
3
4
5
6
7
8
9
10
<html>
<head>
<title>include</title>
</head>
<body>
<#--方法二:此时 user 还是不存在-->
<#if user??><h1>Welcome ${user}!</h1></#if>
<#include "/copyright_footer.html">
</body>
</html>

效果(user 为空)

效果(user 不为空)

-------------- 本文结束  感谢您的阅读 --------------