原文传送门

1. Template + data-model = output

data-model是一个树状模型,通常是一个java对象。


2.data-model 入门

hashes(散列):目录变量(the root, misc)

scalars(标量):存储单个值的变量(size, price, name and foo)

sequences(序列):They store subvariables like hashes, but here subvariables doesn't have a name, they are just items in a list. (数组?)(animals)

(root)
  |
  +- animals
  |   |
  |   +- (1st)
  |   |   |
  |   |   +- name = "mouse"
  |   |   |
  |   |   +- size = "small"
  |   |   |
  |   |   +- price = 50
  |   |
  |   +- (2nd)
  |   |   |
  |   |   +- name = "elephant"
  |   |   |
  |   |   +- size = "large"
  |   |   |
  |   |   +- price = 5000
  |   |
  |   +- (3rd)
  |       |
  |       +- name = "python"
  |       |
  |       +- size = "medium"
  |       |
  |       +- price = 4999
  |
  +- misc
     |
      +- foo = "Something"

scalars的数据类型:

  • String
  • Number
  • Date-like: Either a date-time (stores a date with time of the day), or a date (no time of day), or a time (time of day, no date).
  • Boolean

Summary

  • data-model呈现树状结构;
  • Scalars store a single value. The value can be a string or a number or a date-time/date/time or a boolean.
  • Hashes are containers that store other variables and associate them with a unique lookup name.
  • Sequences are containers that store other variables in an ordered sequence. The stored variables can be retrieved via their numerical index, starting from 0.

3. template 入门

3.1 基本语法

  • 插值${...}:FreeMarker将在输出中将其替换为大括号内的表达式的实际值。
  • FTL标签(FTL=FreeMarker Template Language,FreeMarker模板语言):类似于HTML标签(but they are instructions to FreeMarker and will not be printed to the output)。标签名以#开头(用户定义的FTL标签使用@替代#)。
  • 注释:包含在<#---->之间。不会输出到最终的HTML文件中,因为FreeMarker在编译的时候会跳过这些注释。

    除了以上3中语法中的内容都会被视为静态文本,即FreeMarker编译时不会处理这些文本,而是直接输出到HTML文件中。

3.2 常用指令

使用FTL标签可以引用所谓的指令。

3.2.1 if指令

例子:

Welcome ${user}<#if user == "Big Joe">, our beloved leader</#if>!

如果条件为false,<#if condition><#if>之间的内容将会被跳过。

配合<#else>指令可以指定条件不成立时执行的内容。

使用<#elseif>进一步细化条件。

3.2.2 list指令

语法:

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

使用示例一:

<ul>
<#list misc.fruits as fruit>
  <li>${fruit}
</#list>
</ul>

使用示例二:

<#list misc.fruits>
  <ul>
    <#items as fruit>
      <li>${fruit}
    </#items>
  </ul>
</#list>

示例一的缺点:如果misc.fruits的length刚好为0,一对空的ul标签仍会输出到最终的HTML文件中。

示例二避免了这个问题。如果 misc.fruits的length为0,list中的所有内容都将被跳过,因此ul标签不会出现在最终的HTML文件中。

如果只是想使用某个符号将sequence 中的各项数据分隔开显示,可以使用<#sep>指令。

示例三:

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

可是!如果这里的 misc.fruits 的 length 又为0呢??

一个<#list>指令就像一个<#if>指令,可以有一个<#else>指令,当 sequence 的length为0时执行。

示例四:

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

事实上,示例四有个更简单的写法:

<p>Fruits: ${fruits?join(", ", "None")}

3.2.3 include指令

使用include指令,您可以将另一个文件的内容插入到模板中。

示例:

<#include "/copyright_footer.html">

3.3 指令的混合使用

各种指令可以混合使用

3.4 使用内置函数(bulit-ins)

所谓的内置函数就像子变量(或者说,类似Java中的方法)不是来自data-model,而是由FreeMarker添加到value。

为了区分一个子变量是来自FreeMarker而不是来自data-model,我们访问这个子变量时需要使用问号(?)来替代点(.)。

以下是一些使用例子:

  • user?upper_case:返回全部大写的user值
  • animal.name?cap_first:返回首字母大写的animal.name值
  • user?length:返回user值(一个字符串)中字符个数
  • animals?size:返回animals序列的长度
  • 如果你在<#list animals as animal>和相应的<#list>之间:
    • animal?index:返回当前animal的index值(从0开始)
    • animal?counter:类似于index值,但是下标从1开始
    • animal?item_parity:给出字符串“odd”或“even”,这取决于当前的计数器奇偶校验。这通常用于用交替颜色着色行,如:<td class="${animal?item_parity}Row">

      一些内置函数需要更多的参数来指定行为,如:
  • animal.protected?string("Y", "N") return the string "Y" or "N" depending on the boolean value of animal.protected.
  • animal?item_cycle('lightRow', 'darkRow') is the more generic variant of item_parity from earlier.
  • fruits?join(", "): converts the list to a string by concatenating items, and inserting the parameter separator between each items (like "orange, banana")
  • user?starts_with("J") gives boolean true of false depending on if user starts with the letter "J" or not.

    如果需要反复调用更多内置函数,可以使用链接语法。如:<p>${fruits?join(", ")?cap_first}</p>(fruits=["apple","banana"])的HTML输出为<p>Apple, banana</p>

3.5 处理缺失的变量

FreeMarker不允许引用缺少的变量,除非你明确指出如果变量丢失了该怎么办。

注意:在FreeMarker中,缺失的变量和值为null的变量是一样的。

两种典型的处理:

示例一:

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

紧跟在感叹号(!)后面的值为默认值,当且仅当user变量值为null或丢失时,将user变量值显示为"visitor"。

示例二:

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

配合if指令使用,当user变量值为null或丢失时跳过这部分内容。

注意:使用(animals.python.price)!0来替代animals.python.price!0,以防 animals 或 animals.python 的值为null或丢失。前者可以在 animals 或 animals.python 或 animals.python.price 为null或丢失时显示0,而后者只能在animals.python.price为null或丢失时显示0(animals 或 animals.python 为null或丢失时报错“undefined variable”)。同理地,使用(animals.python.price)??替代animals.python.price??

3.6 转义为HTML,XML和其他标记(特殊符号)

如果做了合适的配置(配置由programmers修改),FreeMarker可以将${...}中的值自动转义。

推荐的做法:使用ftlh文件来激活HTML的自动转义,使用ftlx来激活XML的自动转义。

如果ftl文档目前没有自动转义且不能修改配置,则可以在ftl文档首行加入下面这行代码来实现自动转义:

<#--生成HTML文件-->
<#ftl output_format="HTML">
<#--生成XML文件-->
<#ftl output_format="HTML">

如果要打印的字符串值是故意包含特殊符号,需要这样禁止自动转义:${value?no_esc}

最新文章

  1. 浅谈UI设计中妙用无穷的深色系背景
  2. iOS $299刀企业证书申请的过程以及细节补充
  3. JavaScript学习笔记-基础语法、类型、变量
  4. 关于Hibernate的关联映射
  5. ADF_Starting系列5_使用ADF开发富Web应用程序之维护User Interface(Part2)
  6. 值类型和引用类型(C#基础知识复习)
  7. 百度的TSDB——可针对tag查询,应该类似kairosDB
  8. javascript模式——Prototype模式
  9. MySQL ProxySQL读写分离实践
  10. JDK+Tomcat+Zookeeper+DubboAdmin安装教程
  11. 2017ACM/ICPC广西邀请赛-重现赛 1004.Covering
  12. SpringBoot | 第六章:常用注解介绍及简单使用
  13. [Swift]LeetCode348. 设计井字棋游戏 $ Design Tic-Tac-Toe
  14. 每天一点Linux系列之—vim
  15. 常识判断-科技-day123
  16. .Net中EF通用数据层小结
  17. java使用StringBuilder的方法反转字符串输出
  18. 『C++』基础知识点
  19. 【BZOJ】【3931】【CQOI2015】网络吞吐量
  20. 使用cors解决跨域遇到浏览器发出options嗅探

热门文章

  1. Office 365 开发概览系列文章和教程
  2. BootStrap入门教程 (三)
  3. cstring头文件函数解析
  4. webkit图片滤镜
  5. spring data jpa自定义bean字段映射
  6. 服务器证书安装配置指南(SLB)
  7. JS 数组及函数
  8. For循环及例题
  9. 模式识别与机器学习—bagging与boosting
  10. 转:js,jQuery 排序的实现,网页标签排序的实现,标签排序