處理不存在的變量
當 user 從資料模型中丢失時,模闆将會将
user 的值表示為字元串”Anonymous”。(若 user 并沒有丢失,那麼模闆就會表現
出”Anonymous”不存在一樣):
當然也可以在變量名後面通過放置??來詢問 FreeMarker 一個變量是否存在。将它和 if
指令合并,那麼如果 user 變量不存在的話将會忽略整個問候代碼段:
關于多級通路的變量,比如 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)??來看。
使用者自定義指令
假設現在有一個變量,box,它的值是使用者自定義的指令,用來列印一些特定的 HTML 資訊,
這個指令定義了一個标題和其中的資訊。
<@box title="Attention!">
Too much copy-pasting may leads to
maintenance headaches.
</@box>
注釋:
<#-- Greet the user with his/her name -->
換行:
[BR]
FTL 是區分大小寫的。list 是指令的名稱而 List 就不是,類似地${name}和
${Name}或者${NAME}它們也是不同的。
應該意識到非常重要的一點:插值僅僅可以在文本中間使用(也可以在字元串表達式
中,後續将會介紹) 。
FTL 标簽不可以在其他 FTL 标簽和插值中使用。下面這樣寫就是錯的:
<#if <#include 'foo'>='bar'>...</#if>
注釋可以放在 FTL 标簽和插值中間。
一些空格、制表符
和換行符從模闆輸出中都不見了,盡管我們之前已經說了文本是按照原樣輸出的。 現在不用
為此而計較,這是由于 FreeMarker 的“空格剝離”特性在起作用,它當然會自動去除一些
多餘的空格,制表符和換行符了。
使用 FTL 标簽來調用 directives 指令,比如調用 list 指令。在文法上我們使用了兩個标
簽:<#list animals as being>和</#list>
标簽分為兩種:
開始标簽:<#directivename parametes>
結束标簽:</#directivename>
指令有兩種類型:預定義指令和使用者自定義指令。對于使用者自定義的指令使用
@來代替#,比如<@mydirective parameters>...</@mydirective>。更深
的差別在于如果指令沒有嵌套内容,那麼必須這麼使用 <@mydirective
parameters />
快速浏覽(備忘單)
這裡是給已經了解 FreeMarker 的人或有經驗的程式員的一個提醒:
直接指定值
字元串:"Foo" 或者 'Foo' 或者 "It's \"quoted\"" 或者
r"C:\raw\string"
數字:123.45
<#list[BR]
animals as[BR]
being[BR]
>[BR]
${being.name} for ${being.price} Euros[BR]
</#list > 布爾值:true, false
序列:["foo", "bar", 123.45], 1..100
哈希表:{"name":"green mouse", "price":150}
檢索變量
頂層變量: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 * 1.5 + 10) / 2 - y % 100
比較 運算 : x == y, x != y, x < y, x > y, 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)??
參考:運算符的優先級
下面的表格是 FreeMarker 支援的所有轉義字元。在字元串使用反斜杠的其他所有情況
都是錯誤的,運作這樣的模闆都會失敗。
轉義序列 含義
\ 引号(u0022)
\’ 單引号(又稱為撇号)(u0027)
\\ 反斜杠(u005C)
\n 換行符(u000A)
\r 回車(u000D)
\t 水準制表符(又稱為标簽)(u0009)
\b 倒退(u0008)
\f 換頁(u000C)
\l 小于号:<
\g 大于号:>
\a 和号:&
\xCode 字元的 16 進制 Unicode 碼(UCS 碼)
一種特殊的字元串就是原生字元串。在原生字元串中,反斜杠和${沒有特殊的含義,
它們被視為普通的字元。為了表明字元串是原生字元串,在開始的引号或單引号之前放置字
母 r,例如:
${r"${foo}"}
${r"C:\foo\bar"}
将會列印:
${foo}
C:\foo\bar
從哈希表中檢索資料
如果有一個表達式的結果是哈希表,那麼我們可以使用點和子變量的名字得到它的值,
假設我們有如下的資料模型:
(root)
|
+- book
| |
| +- title = "Breeding green mouses"
| |
| +- author
| |
| +- name = "Julia Smith"
| |
| +- info = "Biologist, 1923-1985, Canada"
通常來說,FreeMarker 不會自動将字元串轉換為數字,反之會自動進行。
有時我們隻想擷取計算結果的整數部分,這可以使用内建函數 int 來解決。
仍然假設 x 的值是 5,那麼将會輸出:
${(x/2)?int}
${1.1?int}
${1.999?int}
${-1.1?int}
${-1.999?int}
2
1
1
-1
-1
比較運算
對數字和日期類型的比較,也可以使用<,<=,>=和>。不能把它們當作字元串來比
較。比如:
<#if x <= 12>
x is less or equivalent with 12
</#if>
使用>=和>的時候有一點小問題。FreeMarker 解釋>的時候可以把它當作 FTL 标簽的結
束符。為了避免這種問題,不得不将表達式放到括号内:<#if (x > y)>,或者可以在
比較關系處使用>和<:<#if x > y>。(通常在 FLT 标簽中不支援實體引
用(比如&...;這些),否則就會抛出算數比較異常) 。另外,可以使用 lt 代替<,lte
代替<=, gt 代替>, gte 代替>=, 由于曆史遺留的原因, FTL 也支援\lt, \lte, \gt 和
\gte,使用他們和使用不帶反斜杠的效果一樣。