FreeMarker概述
FreeMarker概述
FreeMarker是一个用于Java平台的模板引擎,它允许开发者创建基于模板的文档,特别是用于生成HTML网页。它提供了一个简单、灵活的模板语言,使得可以轻松地将数据模型和模板文件结合,生成最终的输出。
一些 FreeMarker 的关键特点包括:
-
模板语言:FreeMarker拥有自己的模板语言,这种语言类似于HTML,并包括可以插入动态内容的标记和语法。这使得生成静态文档或网页更加灵活和动态化。
-
分离视图和业务逻辑:通过使用模板文件(通常是以
.ftl
为扩展名)与业务逻辑分离,开发者可以更清晰地管理页面结构和内容。 -
数据模型:FreeMarker使用一个数据模型作为输入,该模型中包含了模板需要填充的数据。这个数据模型可以是一个简单的对象、集合,或者是更复杂的数据结构。
-
多功能:它支持条件语句、迭代、自定义函数等,提供了一系列内建函数和指令,以便更好地控制模板中的逻辑。
-
跨平台性:作为Java模板引擎,FreeMarker可以在任何支持Java的平台上运行。
典型的使用场景包括在Web开发中,特别是在基于Java的Web应用中。它能够生成HTML页面,也可以用于构建电子邮件模板、文档生成、动态文本生成等,类似JSP文件。
在Java应用中,通过FreeMarker引擎,你可以将模板文件与数据模型结合,最终生成各种类型的文档或内容。常见的工作流程包括加载模板文件、填充数据模型,然后生成最终的输出,如HTML页面或其他格式的文档。
中文文档http://freemarker.foofun.cn/
模板 + 数据模型 = 输出
这里的数据加载使用EL表达式
数据模型
-
数据模型可以被看成是树形结构。
-
标量用于存储单一的值。这种类型的值可以是字符串,数字,日期/时间或者是布尔值。
-
哈希表是一种存储变量及其相关且有唯一标识名称的容器。
-
序列是存储有序变量的容器。存储的变量可以通过数字索引来检索,索引通常从0开始。
模板
如果想要页面动起来 (这里指动态网页技术,译者注),那么就要在HTML中放置能被FreeMarker所解析的特殊代码片段:
-
${...}
: FreeMarker将会输出真实的值来替换大括号内的表达式,这样的表达式被称为 interpolation(插值,译者注)。 -
FTL 标签 (FreeMarker模板的语言标签): FTL标签和HTML标签有一些相似之处,但是它们是FreeMarker的指令,是不会在输出中打印的。 这些标签的名字以
#
开头。(用户自定义的FTL标签则需要使用@
来代替#
,但这属于更高级的话题了。) -
注释: 注释和HTML的注释也很相似, 但是它们使用
<#--
and-->
来标识。 不像HTML注释那样,FTL注释不会出现在输出中(不出现在访问者的页面中), 因为 FreeMarker会跳过它们。
其他任何不是FTL标签,插值或注释的内容将被视为静态文本, 这些东西不会被FreeMarker所解析;会被按照原样输出出来。
基本指令
if 指令
<#-- 绿色标出的为条件 -->
<#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>
。 repeatThis
部分将会在给定的 sequence
遍历时在每一项中重复, 从第一项开始,一个接着一个。在所有的重复中, loopVariable
将持有当前遍历项的值。 这个变量仅存在于 <#list ...>
和 </#list>
标签内。
sequence
可以是任意表达式\
<p>We have these animals:
<table border=1>
<#list animals as animal>
<tr>
<td>${animal.name}</td>
${animal.price}
Euros
</tr>
</#list>
</table>
</p>
include 指令
使用 include
指令, 我们可以在模板中插入其他文件的内容。
<html>
<head>
<title>Test page</title>
</head> <body>
<h1>Test page</h1>
<p>Blah blah... <#include "/copyright_footer.html">
</body>
</html>
assign 指令
使用该指令你可以创建一个新的变量, 或者替换一个已经存在的变量。
比如:变量 seq
存储一个序列:
<#assign seq = ["foo", "bar", "baz"]>
比如:变量 x
中存储增长的数字:
<#assign x++>
作为一个方便的特性,你可以使用一个 assign
标记来进行多次定义。比如这个会做上面两个例子中相同的事情:
<#assign
seq = ["foo", "bar", "baz"]
x++
>
http://freemarker.foofun.cn/ref_directives.html
使用内建函数
内建函数很像子变量(如果了解Java术语的话,也可以说像方法), 它们并不是数据模型中的东西,是 FreeMarker 在数值上添加的。 为了清晰子变量是哪部分,使用 ?
(问号)代替 .
(点)来访问它们。常用内建函数的示例:
-
user?html
给出user
的HTML转义版本, 比如&
会由&
来代替。 -
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
序列中 项目 的个数(我们示例数据模型中是3个) -
如果在
<#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。
内建函数应用可以链式操作,比如user?upper_case?html
会先转换用户名到大写形式,之后再进行HTML转义。(这就像可以链式使用 .
(点)一样)
常见内建函数和其操作
字符串操作:
-
length:返回字符串的长度。
${"Hello, World!"?length} <!-- 输出:13 -->
-
substring:截取字符串的子串。
${"Hello, World!"?substring(0, 5)} <!-- 输出:Hello -->
-
replace:替换字符串中的部分内容。
${"Hello, World!"?replace("World", "Universe")} <!-- 输出:Hello, Universe! -->
集合操作:
-
size:返回集合的大小。
${myList?size} <!-- 输出:大小 -->
-
?reverse:反转列表元素的顺序。
<#list myList?reverse as item> ${item} </#list>
格式化操作:
-
?string:转换其他类型为字符串。
${123?string} <!-- 输出:123 -->
-
?number:将字符串转换为数字。
${"123"?number} <!-- 输出:123 -->
条件判断:
- if:条件判断。
<#if condition> <!-- 内容 --> <#else> <!-- 其他内容 --> </#if>
Math 相关函数:
- ?c:执行数学运算。
${2 + 3?c} <!-- 输出:5 -->
http://freemarker.foofun.cn/ref_builtins.html
内建函数和指令是freemarker的核心语法
处理不存在的变量
两种方式
当 user
不存在于数据模型时, 模板将会将 user
的值表示为字符串 "visitor"
。(当 user
存在时, 模板就会表现出 ${user}
的值):
<h1>Welcome ${user!"visitor"}!</h1>
也可以在变量名后面通过放置 ??
来询问一个变量是否存在。将它和 if
指令合并, 那么如果 user
变量不存在的话将会忽略整个问候的代码段:
<#if user??><h1>Welcome ${user}!</h1></#if>
关于多级访问的变量,比如 animals.python.price
, 书写代码:animals.python.price!0
当且仅当 animals.python
永远存在, 而仅仅最后一个子变量 price
可能不存在时是正确的 (这种情况下我们假设价格是 0
)。 如果 animals
或 python
不存在, 那么模板处理过程将会以"未定义的变量"错误而停止。为了防止这种情况的发生, 可以如下这样来编写代码 (animals.python.price)!0
。 这种情况就是说 animals
或 python
不存在时, 表达式的结果是 0
。对于 ??
也是同样用来的处理这种逻辑的; 将 animals.python.price??
对比 (animals.python.price)??
来看。
FreeMarker 中的数据类型和JAVA相差不大,布尔类型和日期类型的输出需要转换为字符串才能输出
支持的类型有:
页面静态化
FreeMarker 可以用于实现页面静态化,即生成静态的 HTML 页面。这种做法通常用于提高网页性能,减少服务器压力,以及在一些场景下加速页面加载速度。
下面是静态化页面的一般步骤:
-
创建模板文件:编写 FreeMarker 模板文件,包括页面的结构和需要动态填充的内容。通常,这些模板文件包括 HTML 结构和一些占位符用于填充数据。
-
生成数据模型:准备用于渲染模板的数据模型。这些数据可能是从数据库、API 或其他数据源中获取的。
-
填充数据并渲染:使用 FreeMarker 引擎,将数据模型中的数据填充到模板中,并进行渲染。这将生成一个动态生成的 HTML 页面。
-
保存静态页面:将渲染后的 HTML 页面保存为静态文件。这可以是在服务器端保存,也可以在生成后上传至指定位置。
-
服务静态页面:在需要的时候,将静态页面提供给用户。这些静态页面可以通过Web服务器直接提供,不需要动态生成。
这种静态化技术适用于内容相对固定或不经常变化的页面,比如新闻详情页面、产品详情页等。它可以减少服务器压力,提高页面加载速度,同时也可以有效地应对突发的访问量增加。
一些网站在静态化方面会使用缓存或者预先生成静态页面,提供更快的用户体验。然而,对于动态内容较多、变化频繁的页面,静态化可能并不是最佳的选择,因为它会失去动态页面所具有的实时性。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 记一次.NET内存居高不下排查解决与启示