FreeMaker入门笔记(仅模板开发指南)

一、freemarker介绍

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

这种方式通常被称为 MVC (模型 视图 控制器) 模式

模板 + 数据模型 = 输出

二、数据模型

1、数据模型基本是树状结构,类似数组对象

  • 标量用于存储单一的值。这种类型的值可以是字符串,数字,日期/时间或者是布尔值。
  • 哈希表是一种存储变量及其相关且有唯一标识名称的容器。
  • 序列是存储有序变量的容器。存储的变量可以通过数字索引来检索,索引通常从0开始。

2、访问方式:(.)

子变量:如animals.mouse.price

序列:如要得到 misc.fruits 中的第二项(字符串"banana")可以这么来写 misc.fruits[1]

三、模板一览

最简单的模板通常是普通的HTML文件(或其他文本文件)。当客户端访问某个页面时, FreeMarker要发送HTML代码至客户端浏览器中去显示。如果想要页面动起来 (这里指动态网页技术),那么就要在HTML中放置能被FreeMarker所解析的特殊代码片段:

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

四、常用指令(FTL标签)

1、if指令(相当于vue中的v-if) 条件显示内容

<#if condition> ... <#else>

... </#if>

举例:

2、list指令(类似于vue中的v-for) 列表显示内容

(和v-for的差别是item of Map 换成了 Map as item)

(1)格式: <#list sequence as loopVariable>repeatThis</#list>。 

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

(2)举例:

(3)优化

上面这个例子的问题,如果frutes为空,也会输出一个<ul></ul>标签,要避免的话,可以这样使用

(4)拓展 <#sep>

另一个列表相关的常见任务是:使用一些分隔符来列出水果,比如逗号:

<p>Fruits: <#list misc.fruits as fruit>${fruit}<#sep>, </#list>

<p>Fruits: orange, banana

被 sep 覆盖的部分(我们也可以这么来写: ...<#sep>, </#sep></#list>) 只有当还有下一项时才会被执行。 因此最后一个水果后面不会有逗号。

3、include指令(类似vue中的子模板) 插入文件

<#include "/copyright_footer.html">

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

4、联合使用指令

在页面上也可以多次使用指令,而且指令间也可以很容易地相互嵌套。 比如,在 list 指令中嵌套 if 指令:

<#list animals as animal> <div<#if animal.protected> class="protected"</#if>> ${animal.name} for ${animal.price} Euros </div> </#list>

5、使用内建函数(类似各种API,?代替.)

内建函数很像子变量(如果了解Java术语的话,也可以说像方法), 它们并不是数据模型中的东西,是 FreeMarker 在数值上添加的。

  • 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 序列中 项目 的个数(我们示例数据模型中是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转义。(这就像可以链式使用 .(点)一样)

全部对应的网站链接:全部内建函数参考

6、处理不存在的变量( !或者??)

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

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

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

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

(3)括号区别

书写代码:animals.python.price!0 当且仅当 animals.python 永远存在, 而仅仅最后一个子变量 price 可能不存在时是正确的 (这种情况下我们假设价格是 0)。 如果 animals 或 python 不存在, 那么模板处理过程将会以"未定义的变量"错误而停止。为了防止这种情况的发生, 可以如下这样来编写代码 (animals.python.price)!0。 这种情况就是说 animals 或 python 不存在时, 表达式的结果是 0。对于 ?? 也是同样用来的处理这种逻辑的。

四、自定义指令标签)#macro

1、基本用法

创建一个宏变量

<#macro greet> <font size="+2">Hello Joe!</font> </#macro>

输入

<@greet></@greet> 或<@greet/>

会输出

<font size="+2">Hello Joe!</font>

2、带参数(有点类似prop)

这里我们仅在 greet 宏中定义一个参数,person:

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

那么就可以这样来使用这个宏:

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

这和HTML的语法是很相似的,将会输出:

<font size="+2">Hello Fred!</font> and <font size="+2">Hello Batman!</font>

即宏参数的真实值是可以作为变量 (person)放在宏定义体中,调用是也只能使用在macro指令中定义的参数,否则会发生错误

3、嵌套内容 <#nested>,可多次调用(类似于模板中的sort插值)

<#macro border> <table border=4 cellspacing=0 cellpadding=4><tr><td> <#nested> </tr></td></table> </#macro>

<#nested> 指令执行位于开始和结束标记指令之间的模板代码段。 如果这样写:

<@border>The bordered text</@border>

将会输出:

<table border=4 cellspacing=0 cellpadding=4><tr><td> The bordered text </td></tr></table>

更详细的请见中文官网

http://freemarker.foofun.cn/pgui.html

发布了41 篇原创文章 · 获赞 65 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/cindy647/article/details/87887353