模板一覽
符號 | 註釋 |
---|---|
${…} | 輸出真實的值來替換花括號內的表達式 |
開頭 | 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>