FreeMarker設計指南(3)

3、模板

1)整體結構

l         模板使用FTLFreeMarker模板語言)編寫,是下面各部分的一個組合:

Ø         文本:直接輸出

Ø         Interpolation:由${},或#{}來限定,計算值替代輸出

Ø         FTL標記:FreeMarker指令,和HTML標記類似,名字前加#予以區分,不會輸出

Ø         註釋:由<#---->限定,不會輸出

l         下面是以一個具體模板例子:

<html>[BR]

<head>[BR]

  <title>Welcome!</title>[BR]

</head>[BR]

<body>[BR]

  <#-- Greet the user with his/her name -->[BR]

  <h1>Welcome ${user}!</h1>[BR]

  <p>We have these animals:[BR]

  <ul>[BR]

  <#list animals as being>[BR]

    <li>${being.name} for ${being.price} Euros[BR]

  </#list>[BR]

  </ul>[BR]

</body>[BR]

</html>  

l         [BR]是用於換行的特殊字符序列

l         注意事項:

Ø         FTL區分大小寫,所以list是正確的FTL指令,而List不是;${name}${NAME}是不同的

Ø         Interpolation只能在文本中使用

Ø         FTL標記不能位於另一個FTL標記內部,例如:

<#if <#include 'foo'>='bar'>...</if>

Ø         註釋可以位於FTL標記和Interpolation內部,如下面的例子:

<h1>Welcome ${user <#-- The name of user -->}!</h1>[BR]

<p>We have these animals:[BR]

<ul>[BR]

<#list <#-- some comment... --> animals as <#-- again... --> being>[BR]

...  

Ø         多餘的空白字符會在模板輸出時移除

2)指令

l         FreeMarker中,使用FTL標記引用指令

l         有三種FTL標記,這和HTML標記是類似的:

Ø         開始標記:<#directivename parameters>

Ø         結束標記:</#directivename>

Ø         空內容指令標記:<#directivename parameters/>

l         有兩種類型的指令:預定義指令和用戶定義指令

l         用戶定義指令要使用@替換#,如<@mydirective>...</@mydirective>(會在後面講述)

l         FTL標記不能夠交叉,而應該正確的嵌套,如下面的代碼是錯誤的:

<ul>

<#list animals as being>

  <li>${being.name} for ${being.price} Euros

  <#if use = "Big Joe">

     (except for you)

</#list>

</#if> <#-- WRONG! -->

</ul>  

l         如果使用不存在的指令,FreeMarker不會使用模板輸出,而是產生一個錯誤消息

l         FreeMarker會忽略FTL標記中的空白字符,如下面的例子:

<#list[BR]

  animals       as[BR]

     being[BR]

>[BR]

${being.name} for ${being.price} Euros[BR]

</#list    >  

l         但是,<</和指令之間不允許有空白字符

3)表達式

l         直接指定值

Ø         字符串

n         使用單引號或雙引號限定

n         如果包含特殊字符需要轉義,如下面的例子:

${"It's /"quoted/" and

this is a backslash: //"}

 

${'It/'s "quoted" and

this is a backslash: //'} 

輸出結果是:

It's "quoted" and

this is a backslash: /

 

It's "quoted" and

this is a backslash: / 

n         下面是支持的轉義序列:

轉義序列

含義

/"

雙引號(u0022)

/'

單引號(u0027)

//

反斜槓(u005C)

/n

換行(u000A)

/r

Return (u000D)

/t

Tab (u0009)

/b

Backspace (u0008)

/f

Form feed (u000C)

/l

<

/g

>

/a

&

/{

{

/xCode

4位16進制Unicode代碼

n         有一類特殊的字符串稱爲raw字符串,被認爲是純文本,其中的/{等不具有特殊含義,該類字符串在引號前面加r,下面是一個例子:

${r"${foo}"}

${r"C:/foo/bar"}  

輸出的結果是:

${foo}

C:/foo/bar  

Ø         數字

n         直接輸入,不需要引號

n         精度數字使用“.”分隔,不能使用分組符號

n         目前版本不支持科學計數法,所以“1E3”是錯誤的

n         不能省略小數點前面的0,所以“.5”是錯誤的

n         數字8+8088.00都是相同的

Ø         布爾值

n         truefalse,不使用引號

Ø         序列

n         由逗號分隔的子變量列表,由方括號限定,下面是一個例子:

<#list ["winter", "spring", "summer", "autumn"] as x>

${x}

</#list> 

輸出的結果是:

winter

spring

summer

autumn

n         列表的項目是表達式,所以可以有下面的例子:

[2 + 2, [1, 2, 3, 4], "whatnot"]

n         可以使用數字範圍定義數字序列,例如2..5等同於[2, 3, 4, 5],但是更有效率,注意數字範圍沒有方括號

n         可以定義反遞增的數字範圍,如5..2

Ø         散列(hash

n         由逗號分隔的鍵/值列表,由大括號限定,鍵和值之間用冒號分隔,下面是一個例子:

{"name":"green mouse", "price":150}

n         鍵和值都是表達式,但是鍵必須是字符串

l         獲取變量

Ø         頂層變量: ${variable},變量名只能是字母、數字、下劃線、$@#的組合,且不能以數字開頭

Ø         從散列中獲取數據

n         可以使用點語法或方括號語法,假設有下面的數據模型:

(root)

 |

 +- book

 |   |

 |   +- title = "Breeding green mouses"

 |   |

 |   +- author

 |       |

 |       +- name = "Julia Smith"

 |       |

 |       +- info = "Biologist, 1923-1985, Canada"

 |

 +- test = "title" 

下面都是等價的:

book.author.name

book["author"].name

book.author.["name"]

book["author"]["name"]

n         使用點語法,變量名字有頂層變量一樣的限制,但方括號語法沒有該限制,因爲名字是任意表達式的結果

Ø         從序列獲得數據:和散列的方括號語法語法一樣,只是方括號中的表達式值必須是數字;注意:第一個項目的索引是0

Ø         序列片斷:使用[startIndex..endIndex]語法,從序列中獲得序列片斷(也是序列);startIndexendIndex是結果爲數字的表達式

Ø         特殊變量:FreeMarker內定義變量,使用.variablename語法訪問

l         字符串操作

Ø         Interpolation(或連接操作)

n         可以使用${..}(或#{..})在文本部分插入表達式的值,例如:

${"Hello ${user}!"}

${"${user}${user}${user}${user}"}  

n         可以使用+操作符獲得同樣的結果

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

${user + user + user + user}

n         ${..}只能用於文本部分,下面的代碼是錯誤的:

<#if ${isBig}>Wow!</#if>

<#if "${isBig}">Wow!</#if>

應該寫成:

<#if isBig>Wow!</#if>

Ø         子串

n         例子(假設user的值爲“Big Joe”):

${user[0]}${user[4]}

${user[1..4]}

結果是(注意第一個字符的索引是0):

BJ

ig J 

l         序列操作

Ø         連接操作:和字符串一樣,使用+,下面是一個例子:

<#list ["Joe", "Fred"] + ["Julia", "Kate"] as user>

- ${user}

</#list>

輸出結果是:

- Joe

- Fred

- Julia

- Kate

l         散列操作

Ø         連接操作:和字符串一樣,使用+,如果具有相同的key,右邊的值替代左邊的值,例如:

<#assign ages = {"Joe":23, "Fred":25} + {"Joe":30, "Julia":18}>

- Joe is ${ages.Joe}

- Fred is ${ages.Fred}

- Julia is ${ages.Julia}  

輸出結果是:

- Joe is 30

- Fred is 25

- Julia is 18  

l         算術運算

Ø         +、-、×、/、%,下面是一個例子:

${x * x - 100}

${x / 2}

${12 % 10}

輸出結果是(假設x5):

-75

2.5

Ø         操作符兩邊必須是數字,因此下面的代碼是錯誤的:

${3 * "5"} <#-- WRONG! -->  

Ø         使用+操作符時,如果一邊是數字,一邊是字符串,就會自動將數字轉換爲字符串,例如:

${3 + "5"}  

輸出結果是:

35

Ø         使用內建的int(後面講述)獲得整數部分,例如:

${(x/2)?int}

${1.1?int}

${1.999?int}

${-1.1?int}

${-1.999?int}

輸出結果是(假設x5):

2

1

1

-1

-1

l         比較操作符

Ø         使用=(或==,完全相等)測試兩個值是否相等,使用!= 測試兩個值是否不相等

Ø         =!=兩邊必須是相同類型的值,否則會產生錯誤,例如<#if 1 = "1">會引起錯誤

Ø         Freemarker是精確比較,所以對"x""x  ""X"是不相等的

Ø         對數字和日期可以使用<<=>>=,但不能用於字符串

Ø         由於Freemarker會將>解釋成FTL標記的結束字符,所以對於>>=可以使用括號來避免這種情況,例如<#if (x > y)>

Ø         另一種替代的方法是,使用ltltegtgte來替代<<=>>=

l         邏輯操作符

Ø         &&and)、||or)、!not),只能用於布爾值,否則會產生錯誤

Ø         例子:

<#if x < 12 && color = "green">

  We have less than 12 things, and they are green.

</#if>

<#if !hot> <#-- here hot must be a boolean -->

  It's not hot.

</#if>  

l         內建函數

Ø         內建函數的用法類似訪問散列的子變量,只是使用“?”替代“.”,下面列出常用的一些函數

Ø         字符串使用的:

n         html:對字符串進行HTML編碼

n         cap_first:使字符串第一個字母大寫

n         lower_case:將字符串轉換成小寫

n         upper_case:將字符串轉換成大寫

n         trim:去掉字符串前後的空白字符

Ø         序列使用的:

n         size:獲得序列中元素的數目

Ø         數字使用的:

n         int:取得數字的整數部分(如-1.9?int的結果是-1

Ø         例子(假設test保存字符串"Tom & Jerry"):

${test?html}

${test?upper_case?html}

輸出結果是:

Tom &amp; Jerry

TOM &amp; JERRY  

l         操作符優先順序

操作符組

操作符

後綴

[subvarName] [subStringRange] . (methodParams)

一元

+expr-expr!

內建

?

乘法

* / %

加法

+-

關係

<><=>=ltltegtgte

相等

===)、!=

邏輯and

&&

邏輯or

||

數字範圍

..

4Interpolation

l         Interpolation有兩種類型:

Ø         通用Interpolation${expr}

Ø         數字Interpolation#{expr}#{expr; format}

l         注意:Interpolation只能用於文本部分

l         通用Interpolation

Ø         插入字符串值:直接輸出表達式結果

Ø         插入數字值:根據缺省格式(由#setting指令設置)將表達式結果轉換成文本輸出;可以使用內建函數string格式化單個Interpolation,下面是一個例子:

<#setting number_format="currency"/>

<#assign answer=42/>

${answer}

${answer?string}  <#-- the same as ${answer} -->

${answer?string.number}

${answer?string.currency}

${answer?string.percent} 

輸出結果是:

$42.00

$42.00

42

$42.00

4,200%

Ø         插入日期值:根據缺省格式(由#setting指令設置)將表達式結果轉換成文本輸出;可以使用內建函數string格式化單個Interpolation,下面是一個使用格式模式的例子:

${lastUpdated?string("yyyy-MM-dd HH:mm:ss zzzz")}

${lastUpdated?string("EEE, MMM d, ''yy")}

${lastUpdated?string("EEEE, MMMM dd, yyyy, hh:mm:ss a '('zzz')'")}  

輸出的結果類似下面的格式:

2003-04-08 21:24:44 Pacific Daylight Time

Tue, Apr 8, '03

Tuesday, April 08, 2003, 09:24:44 PM (PDT)

Ø         插入布爾值:根據缺省格式(由#setting指令設置)將表達式結果轉換成文本輸出;可以使用內建函數string格式化單個Interpolation,下面是一個例子:

<#assign foo=true/>

${foo?string("yes", "no")}

輸出結果是:

yes

l         數字Interpolation#{expr; format}形式可以用來格式化數字,format可以是:

Ø         mX:小數部分最小X

Ø         MX:小數部分最大X

Ø         例子:

           <#-- If the language is US English the output is: -->

<#assign x=2.582/>

<#assign y=4/>

#{x; M2}   <#-- 2.58 -->

#{y; M2}   <#-- 4    -->

#{x; m1}   <#-- 2.6 -->

#{y; m1}   <#-- 4.0 -->

#{x; m1M2} <#-- 2.58 -->

#{y; m1M2} <#-- 4.0  -->  


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章