天天看點

freemaker筆記

處理不存在的變量

當 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 &lt; 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} 

-1 

-1 

比較運算

  對數字和日期類型的比較,也可以使用<,<=,>=和>。不能把它們當作字元串來比

較。比如: 

 <#if x <= 12> 

  x is less or equivalent with 12 

</#if> 

  使用>=和>的時候有一點小問題。FreeMarker 解釋>的時候可以把它當作 FTL 标簽的結

束符。為了避免這種問題,不得不将表達式放到括号内:<#if (x > y)>,或者可以在

比較關系處使用&gt;和&lt;:<#if x &gt; y>。(通常在 FLT 标簽中不支援實體引

用(比如&...;這些),否則就會抛出算數比較異常) 。另外,可以使用 lt 代替<,lte

代替<=, gt 代替>, gte 代替>=,   由于曆史遺留的原因, FTL 也支援\lt, \lte, \gt 和 

\gte,使用他們和使用不帶反斜杠的效果一樣。