Freemarker基础知识

模板一览

符号 注释
${…} 输出真实的值来替换花括号内的表达式
开头 FTL标签,是指令,且不会直接输出来的东西,用户自定义为@
<#– –> FTL注释,其它任何不是FTL标签,插值或注释的内容将被视为静态文本

指令示例

if指令

<#if condition>

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

list指令

<#list sequence as loopVariable>repeatThis

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

include指令

使用include指令,我们可以在当前的模板中插入其它文件的内容。

<#include "/copyright_footer.html">

处理不存在的变量

Freemarker不能容忍引用不存在的变量,除非明确告诉它当变量不存在时如何处理,这里介绍
两种方案
+ 不论在哪里引用变量,都可以指定一个默认值来避免丢失这种情况,通过在变量名后面跟着
一个!和默认值,

<h1>Welcome ${user !"Anonymous"}!</h1>
  • 在变量名后面通过放置??来询问Freemarker一个变量是否存在,将它和if指令合并,那么如果
    变量不存在的话将会忽略整个问候代码段
<#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)??来看。

数据类型

简介

支持的类型有
+ 标量
- 字符串
- 数字
- 布尔值
- 日期
+ 容器
- 哈希表
- 序列
- 集
+ 子程序
- 方法和函数
- 用户自定义指令
+ 其它/很少使用
- 节点

模板

总体结构

  • 插值仅仅可以在文本中间使用(也可以在字符串表达式中)
  • FTL标签不可以在其它FTL标签和插值中使用
  • 注释可以放在FTL标签和插值中间
    预定义指令和用户自定义指令区别:
  • 用户自定义指令使用@来代替#
  • 如果指令没有嵌套内容,那么必须使用<@mydirective parameters/>

表达式

快速浏览(备忘单)

  • 直接指定值
    • 字符串 “Foo”, ‘Foo’, ” It’s \”quoted\” “
    • 数字 124.44
    • 布尔值 true,false
    • 序列 [“Foo”, “bar”, 2323], 1 .. 100
    • 哈希表 {“name”:”newcih”, “price”:233}
  • 检索变量
    • 顶层变量 user
    • 从哈希表中检索数据 user.name 或者 user[“name”]
    • 从序列中检索 products[5]
    • 特殊变量 .main
  • 字符串操作
    • 插值(或连接) “Hello ${user}!” 或者 (“Free”+”Marker”)
    • 获取一个字符 name[0]
  • 序列操作
    • 连接 users+[“guest”]
    • 序列切分 products[10 .. 19]products[5 ..]
  • 哈希表操作
    • 连接 passwords + {“joe”:”secret42”“}
  • 算数运算 (x*5.2+19)
  • 比较运算 x == y, x < y, x <= y
  • 逻辑操作 !registered && (firstVisit || fromEurope)
  • 内建函数 name?upper_case
  • 方法调用 repeat(“What”, 3)
  • 处理不存在的值
    • 默认值 name!”unknown” 或者 (user.name)!”unknown” 或者 name!(user.name)!
    • 检测不存在的值 name?? 或者 (user.name)??

字符串

在原生字符串中,反斜杠和${没有特殊的含义,它们被视为普通的字符。为了表明字符串是原生字符串,
在开始的引号或单引号之前放置字母r,例如

${r"${foo}"}

将会打印${foo}

数字

  • 不支持科学计数法
  • 小数点前要写0

布尔值

直接写true或false,不加引号

序列

使用逗号来分隔其中的每个子变量,然后把整个列表放到方括号中

<#list ["winter", "spring", "summer", "autumn"] as x>
    ${x}
</#list>

也可以使用start .. end定义存储数字范围的序列,比如 2 .. 5和[2,3,4,5]是相同的,但是前者更有效率

检索变量

为了访问顶层变量,可以简单的使用变量名

${user}

从序列中检索数据

animals[0].name

特殊变量

由Freemarker引擎本身自定义的,为了使用它们,可以按照如下语法形式来进行

.variable_name

通常情况下是不需使用特殊变量,而对专业用户来说可能用到

字符串操作

插值

如果要在字符串中插入表达式的值,可以在字符串的文字中使用${…}(#{…})

${"Hello ${user}!"}
或${"Hello"+user}

插值只能在文本区段和字符串文字中使用,不能在if标签使用,因为if标签需要布尔值

序列操作

连接

序列的连接可以使用+号来进行

比较操作

使用>=和>的时候有一点小问题,Freemarker解释>的时候会把它当做FTL标签的结束符。为了
避免这种问题,不得不将表达式放到括号里

<#if (x > y)></#if>

或者使用>和<(通常在FTL标签中不支持实体引用(比如&…;这些),否则就会抛出算数比较异常)
另外也可以用lt代替<,lte代替<=,gt代替>,gte代替>=。

内建函数

  • 字符串使用的内建函数
  • html 字符串中所有的特殊HTML字符都需要用实体引用来替代(比如<代替<)
  • cap_first 字符串的第一个字母变为大写形式
  • lower_case 字符串的小写形式
  • upper_case 字符串的大写形式
  • trim 去掉字符串首尾的空格
  • 序列使用的内建函数
  • size 序列中元素的个数
  • 数字使用的内建函数
  • int 数字的整数部分
${test?html}
${test?upper_case?html}

方法调用

可以使用方法调用操作来使用一个已经定义过的方法。方法调用的语法形式是使用逗号来分割在括号内
的表达式而形成的参数列表。假设程序员定义了一个可供调用的方法repeat。第一个参数字符串类型,
第二个参数是数字类型。

${repeat("what", 3)}

默认值

模板语言没有null这个概念,如果属性的值是null,和不存在这个属性的情况是一致的。调用方法的返回值
如果是null的话,Freemarker也会把它当做不存在的变量来处理。以下默认值的使用形式

unsafe_expr!default_expr
unsafe_expr!
(unsafe_expr)!default_expr
(unsafe_expr)!

例如

${mouse!"No mouse."}

默认值可以是任何类型的表达式,也可以不必是字符串。你也可以这么写

hits!0
colors!["red", "green"]

插值

插值表达式的结果必须是字符串,数字或日期类型的,因为只有数字和日期类型可以自动转换为字符串类型,
其他类型的值(如布尔,序列)只能手动转换为字符串类型,否则就会发生错误
字符串插入指南,不要忘了转义,如果插值在文本区(也就是说,不在字符串表达式中),如果escapse指令起作用了,
即将被插入的字符串会被自动转义。如果你要生成HTML,那么强烈建议你利用它来阻止跨站脚本攻击和非格式良好
的HTML页面

<#escape x as x?html>
    ...
    <p>Title:${book.title}</p>
    <#noescape>${book.description}</#noescape>
</#escape>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章