posts - 14, comments - 0, trackbacks - 0, articles - 0

          2007年1月10日

          1、快速入門

          (1)模板 + 數(shù)據(jù)模型 = 輸出
          FreeMarker基于設(shè)計(jì)者和程序員是具有不同專業(yè)技能的不同個(gè)體的觀念。他們是分工勞動(dòng)的:設(shè)計(jì)者專注于表示——?jiǎng)?chuàng)建HTML文件、圖片、Web頁面的其它可視化方面;程序員創(chuàng)建系統(tǒng),生成設(shè)計(jì)頁面要顯示的數(shù)據(jù)。經(jīng)常會(huì)遇到的問題是:在Web頁面(或其它類型的文檔)中顯示的信息在設(shè)計(jì)頁面時(shí)是無效的,是基于動(dòng)態(tài)數(shù)據(jù)的。在這里,你可以在HTML(或其它要輸出的文本)中加入一些特定指令,F(xiàn)reeMarker會(huì)在輸出頁面給最終用戶時(shí),用適當(dāng)?shù)臄?shù)據(jù)替代這些代碼。
          下面是一個(gè)例子:

          <html>
          <head>
          ?<title>Welcome!</title>
          </head>

          <body>
          ?<h1>Welcome ${user}!</h1>
          ?<p>Our latest product:
          ?<a href="${latestProduct.url}">${latestProduct.name}</a>!
          </body>

          </html>

          這個(gè)例子是在簡單的HTML中加入了一些由${…}包圍的特定代碼,這些特定代碼是FreeMarker的指令,而包含F(xiàn)reeMarker的指令的文件就稱為模板(Template)。至于user、latestProduct.url和latestProduct.name來自于數(shù)據(jù)模型(data model)。數(shù)據(jù)模型由程序員編程來創(chuàng)建,向模板提供變化的信息,這些信息來自于數(shù)據(jù)庫、文件,甚至于在程序中直接生成。模板設(shè)計(jì)者不關(guān)心數(shù)據(jù)從那兒來,只知道使用已經(jīng)建立的數(shù)據(jù)模型
          下面是一個(gè)可能的數(shù)據(jù)模型:

          (root)
          ?|
          ?+- user = "Big Joe"
          ?|
          ?+- latestProduct
          ???? |
          ???? +- url = "products/greenmouse.html"
          ???? |
          ???? +- name = "green mouse"
          數(shù)據(jù)模型類似于計(jì)算機(jī)的文件系統(tǒng),latestProduct可以看作是目錄,而user、url和name看作是文件,url和name文件位于latestProduct目錄中(這只是一個(gè)比喻,實(shí)際并不存在)。當(dāng)FreeMarker將上面的數(shù)據(jù)模型合并到模板中,就創(chuàng)建了下面的輸出:

          <html>
          <head>
          ?<title>Welcome!</title>
          </head>

          <body>
          ?<h1>Welcome Big Joe!</h1>
          ?<p>Our latest product:
          ?<a href="products/greenmouse.html">green mouse</a>!
          </body>

          </html>?

          (2)數(shù)據(jù)模型
          典型的數(shù)據(jù)模型是樹型結(jié)構(gòu),可以任意復(fù)雜和深層次,如下面的例子:

          (root)
          ?|
          ?+- animals
          ?|?? |
          ?|?? +- mouse
          ?|?? |?? |??
          ?|?? |?? +- size = "small"
          ?|?? |?? |??
          ?|?? |?? +- price = 50
          ?|?? |
          ?|?? +- elephant
          ?|?? |?? |??
          ?|?? |?? +- size = "large"
          ?|?? |?? |??
          ?|?? |?? +- price = 5000
          ?|?? |
          ?|?? +- python
          ?|?????? |??
          ?|?????? +- size = "medium"
          ?|?????? |??
          ?|?????? +- price = 4999
          ?|
          ?+- test = "It is a test"
          ?|
          ?+- whatnot
          ???? |
          ???? +- because = "don't know"
          類似于目錄的變量稱為hashes,包含保存下級(jí)變量的唯一的查詢名字。類似于文件的變量稱為scalars,保存單值scalars保存的值有兩種類型:字符串(用引號(hào)括起,可以是單引號(hào)或雙引號(hào))和數(shù)字(不要用引號(hào)將數(shù)字括起,這會(huì)作為字符串處理)。對(duì)scalars的訪問從root開始,各部分用“.”分隔,如animals.mouse.price。另外一種變量是sequences,和hashes類似,只是不使用變量名字,而使用數(shù)字索引,如下面的例子:

          (root)
          ?|
          ?+- animals
          ?|?? |
          ?|?? +- (1st)
          ?|?? |?? |
          ?|?? |?? +- name = "mouse"
          ?|?? |?? |
          ?|?? |?? +- size = "small"
          ?|?? |?? |
          ?|?? |?? +- price = 50
          ?|?? |
          ?|?? +- (2nd)
          ?|?? |?? |
          ?|?? |?? +- name = "elephant"
          ?|?? |?? |
          ?|?? |?? +- size = "large"
          ?|?? |?? |
          ?|?? |?? +- price = 5000
          ?|?? |
          ?|?? +- (3rd)
          ?|?????? |
          ?|?????? +- name = "python"
          ?|?????? |
          ?|?????? +- size = "medium"
          ?|?????? |
          ?|?????? +- price = 4999
          ?|
          ?+- whatnot
          ???? |
          ???? +- fruits
          ???????? |
          ???????? +- (1st) = "orange"
          ???????? |
          ???????? +- (2nd) = "banana"
          這種對(duì)scalars的訪問使用索引,如animals[0].name

          (3)模板
          在FreeMarker模板中可以包括下面三種特定部分:

          ${…}:稱為interpolations,F(xiàn)reeMarker會(huì)在輸出時(shí)用實(shí)際值進(jìn)行替代

          FTL標(biāo)記(FreeMarker模板語言標(biāo)記):類似于HTML標(biāo)記,為了與HTML標(biāo)記區(qū)分,用#開始(有些以@開始,在后面敘述)

          注釋:包含在<#--和-->(而不是<!--和-->)之間
          下面是一些使用指令的例子:

          if指令

          <#if animals.python.price < animals.elephant.price>
          ?Pythons are cheaper than elephants today.

          <#else>
          ?Pythons are not cheaper than elephants today.

          </#if>?

          list指令

          <p>We have these animals:

          <table border=1>
          ?<tr><th>Name<th>Price
          ?<#list animals as being>
          ?<tr><td>${being.name}<td>${being.price} Euros
          ?</#list>

          </table>?

          輸出為:

          <p>We have these animals:

          <table border=1>
          ?<tr><th>Name<th>Price
          ?<tr><td>mouse<td>50 Euros
          ?<tr><td>elephant<td>5000 Euros
          ?<tr><td>python<td>4999 Euros

          </table>?

          include指令

          <html>

          <head>
          ?<title>Test page</title>

          </head>

          <body>
          ?<h1>Test page</h1>
          ?<p>Blah blah...

          <#include "/copyright_footer.html">

          </body>

          </html>?

          一起使用指令

          <p>We have these animals:

          <table border=1>
          ?<tr><th>Name<th>Price
          ?<#list animals as being>
          ?<tr>
          ?? <td>
          ???? <#if being.size = "large"><b></#if>
          ???? ${being.name}
          ???? <#if being.size = "large"></b></#if>
          ?? <td>${being.price} Euros
          ?</#list>

          </table>

          2、數(shù)據(jù)模型

          (1)基礎(chǔ)
          在快速入門中介紹了在模板中使用的三種基本對(duì)象類型:scalars、hashes 和sequences,其實(shí)還可以有其它更多的能力:

          scalars:存儲(chǔ)單值

          hashes:充當(dāng)其它對(duì)象的容器,每個(gè)都關(guān)聯(lián)一個(gè)唯一的查詢名字

          sequences:充當(dāng)其它對(duì)象的容器,按次序訪問

          方法:通過傳遞的參數(shù)進(jìn)行計(jì)算,以新對(duì)象返回結(jié)果

          用戶自定義FTL標(biāo)記:宏和變換器
          通常每個(gè)變量只具有上述的一種能力,但一個(gè)變量可以具有多個(gè)上述能力,如下面的例子:

          (root)
          |
          +- mouse = "Yerri"
          ??? |
          ??? +- age = 12
          ??? |
          ??? +- color = "brown">?
          mouse既是scalars又是hashes,將上面的數(shù)據(jù)模型合并到下面的模板:

          ${mouse}?????? <#-- use mouse as scalar -->

          ${mouse.age}?? <#-- use mouse as hash -->

          ${mouse.color} <#-- use mouse as hash -->?
          輸出結(jié)果是:

          Yerri

          12

          brown?

          (2)Scalar變量
          Scalar變量存儲(chǔ)單值,可以是:

          字符串:簡單文本,在模板中使用引號(hào)(單引號(hào)或雙引號(hào))括起

          數(shù)字:在模板中直接使用數(shù)字值

          日期:存儲(chǔ)日期/時(shí)間相關(guān)的數(shù)據(jù),可以是日期、時(shí)間或日期-時(shí)間(Timestamp);通常情況,日期值由程序員加到數(shù)據(jù)模型中,設(shè)計(jì)者只需要顯示它們

          布爾值:true或false,通常在<#if …>標(biāo)記中使用

          (3)hashes 、sequences和集合
          有些變量不包含任何可顯示的內(nèi)容,而是作為容器包含其它變量,者有兩種類型:

          hashes:具有一個(gè)唯一的查詢名字和它包含的每個(gè)變量相關(guān)聯(lián)

          sequences:使用數(shù)字和它包含的每個(gè)變量相關(guān)聯(lián),索引值從0開始
          集合變量通常類似sequences,除非無法訪問它的大小和不能使用索引來獲得它的子變量;集合可以看作只能由<#list …>指令使用的受限sequences

          (4)方法
          方法變量通常是基于給出的參數(shù)計(jì)算值
          下面的例子假設(shè)程序員已經(jīng)將方法變量avg放到數(shù)據(jù)模型中,用來計(jì)算數(shù)字平均值:

          The average of 3 and 5 is: ${avg(3, 5)}

          The average of 6 and 10 and 20 is: ${avg(6, 10, 20)}

          The average of the price of python and elephant is: ${avg(animals.python.price, animals.elephant.price)}

          (5)宏和變換器
          宏和變換器變量是用戶自定義指令(自定義FTL標(biāo)記),會(huì)在后面講述這些高級(jí)特性

          (6)節(jié)點(diǎn)
          節(jié)點(diǎn)變量表示為樹型結(jié)構(gòu)中的一個(gè)節(jié)點(diǎn),通常在XML處理中使用,會(huì)在后面的專門章節(jié)中講述


          3、模板

          (1)整體結(jié)構(gòu)
          模板使用FTL(FreeMarker模板語言)編寫,是下面各部分的一個(gè)組合:

          文本:直接輸出

          Interpolation:由${和},或#{和}來限定,計(jì)算值替代輸出

          FTL標(biāo)記:FreeMarker指令,和HTML標(biāo)記類似,名字前加#予以區(qū)分,不會(huì)輸出

          注釋:由<#--和-->限定,不會(huì)輸出
          下面是以一個(gè)具體模板例子:

          <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>?
          [BR]是用于換行的特殊字符序列
          注意事項(xiàng):

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

          Interpolation只能在文本中使用

          FTL標(biāo)記不能位于另一個(gè)FTL標(biāo)記內(nèi)部,例如:

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

          注釋可以位于FTL標(biāo)記和Interpolation內(nèi)部,如下面的例子:

          <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]

          ...?

          多余的空白字符會(huì)在模板輸出時(shí)移除

          (2)指令
          在FreeMarker中,使用FTL標(biāo)記引用指令
          有三種FTL標(biāo)記,這和HTML標(biāo)記是類似的:

          開始標(biāo)記:<#directivename parameters>

          結(jié)束標(biāo)記:</#directivename>

          空內(nèi)容指令標(biāo)記:<#directivename parameters/>
          有兩種類型的指令:預(yù)定義指令和用戶定義指令
          用戶定義指令要使用@替換#,如<@mydirective>...</@mydirective>(會(huì)在后面講述)
          FTL標(biāo)記不能夠交叉,而應(yīng)該正確的嵌套,如下面的代碼是錯(cuò)誤的:

          <ul>

          <#list animals as being>
          ?<li>${being.name} for ${being.price} Euros
          ?<#if use = "Big Joe">
          ??? (except for you)

          </#list>

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

          </ul>?
          如果使用不存在的指令,F(xiàn)reeMarker不會(huì)使用模板輸出,而是產(chǎn)生一個(gè)錯(cuò)誤消息
          FreeMarker會(huì)忽略FTL標(biāo)記中的空白字符,如下面的例子:

          <#list[BR]
          ?animals?????? as[BR]
          ??? being[BR]

          >[BR]

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

          </#list??? >?
          但是,<、</和指令之間不允許有空白字符

          (3)表達(dá)式
          直接指定值

          字符串

          使用單引號(hào)或雙引號(hào)限定

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

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

          this is a backslash: \\"}


          ${'It\'s "quoted" and

          this is a backslash: \\'}

          輸出結(jié)果是:

          It's "quoted" and

          this is a backslash: \


          It's "quoted" and

          this is a backslash: \

          下面是支持的轉(zhuǎn)義序列:

          轉(zhuǎn)義序列
          ?

          含義

          \"
          ?

          雙引號(hào)(u0022)

          \'
          ?

          單引號(hào)(u0027)

          \\
          ?

          反斜杠(u005C)

          \n
          ?

          換行(u000A)

          \r
          ?

          Return (u000D)

          \t
          ?

          Tab (u0009)

          \b
          ?

          Backspace (u0008)

          \f
          ?

          Form feed (u000C)

          \l
          ?

          <

          \g
          ?

          >

          \a
          ?

          &

          \{
          ?

          {

          \xCode
          ?

          4位16進(jìn)制Unicode代碼

          有一類特殊的字符串稱為raw字符串,被認(rèn)為是純文本,其中的\和{等不具有特殊含義,該類字符串在引號(hào)前面加r,下面是一個(gè)例子:

          ${r"${foo}"}

          ${r"C:\foo\bar"}?

          輸出的結(jié)果是:

          ${foo}

          C:\foo\bar?

          數(shù)字

          直接輸入,不需要引號(hào)

          精度數(shù)字使用“.”分隔,不能使用分組符號(hào)

          目前版本不支持科學(xué)計(jì)數(shù)法,所以“1E3”是錯(cuò)誤的

          不能省略小數(shù)點(diǎn)前面的0,所以“.5”是錯(cuò)誤的

          數(shù)字8、+8、08和8.00都是相同的

          布爾值

          true和false,不使用引號(hào)

          序列

          由逗號(hào)分隔的子變量列表,由方括號(hào)限定,下面是一個(gè)例子:

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

          ${x}

          </#list>

          輸出的結(jié)果是:

          winter

          spring

          summer

          autumn

          列表的項(xiàng)目是表達(dá)式,所以可以有下面的例子:

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

          可以使用數(shù)字范圍定義數(shù)字序列,例如2..5等同于[2, 3, 4, 5],但是更有效率,注意數(shù)字范圍沒有方括號(hào)

          可以定義反遞增的數(shù)字范圍,如5..2

          散列(hash)

          由逗號(hào)分隔的鍵/值列表,由大括號(hào)限定,鍵和值之間用冒號(hào)分隔,下面是一個(gè)例子:

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

          鍵和值都是表達(dá)式,但是鍵必須是字符串
          獲取變量

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

          從散列中獲取數(shù)據(jù)

          可以使用點(diǎn)語法或方括號(hào)語法,假設(shè)有下面的數(shù)據(jù)模型:

          (root)
          |
          +- book
          |?? |
          |?? +- title = "Breeding green mouses"
          |?? |
          |?? +- author
          |?????? |
          |?????? +- name = "Julia Smith"
          |?????? |
          |?????? +- info = "Biologist, 1923-1985, Canada"
          |
          +- test = "title"

          下面都是等價(jià)的:

          book.author.name

          book["author"].name

          book.author.["name"]

          book["author"]["name"]

          使用點(diǎn)語法,變量名字有頂層變量一樣的限制,但方括號(hào)語法沒有該限制,因?yàn)槊质侨我獗磉_(dá)式的結(jié)果

          從序列獲得數(shù)據(jù):和散列的方括號(hào)語法語法一樣,只是方括號(hào)中的表達(dá)式值必須是數(shù)字;注意:第一個(gè)項(xiàng)目的索引是0

          序列片斷:使用[startIndex..endIndex]語法,從序列中獲得序列片斷(也是序列);startIndex和endIndex是結(jié)果為數(shù)字的表達(dá)式

          特殊變量:FreeMarker內(nèi)定義變量,使用.variablename語法訪問


          字符串操作

          Interpolation(或連接操作)

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

          ${"Hello ${user}!"}

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

          可以使用+操作符獲得同樣的結(jié)果

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

          ${user + user + user + user}

          ${..}只能用于文本部分,下面的代碼是錯(cuò)誤的:

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

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

          應(yīng)該寫成:

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

          子串

          例子(假設(shè)user的值為“Big Joe”):

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

          ${user[1..4]}

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

          BJ

          ig J
          序列操作

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

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

          - ${user}

          </#list>

          輸出結(jié)果是:

          - Joe

          - Fred

          - Julia

          - Kate
          散列操作

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

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

          - Joe is ${ages.Joe}

          - Fred is ${ages.Fred}

          - Julia is ${ages.Julia}?

          輸出結(jié)果是:

          - Joe is 30

          - Fred is 25

          - Julia is 18?
          算術(shù)運(yùn)算

          +、-、×、/、%,下面是一個(gè)例子:

          ${x * x - 100}

          ${x / 2}

          ${12 % 10}

          輸出結(jié)果是(假設(shè)x為5):

          -75

          2.5

          2?

          操作符兩邊必須是數(shù)字,因此下面的代碼是錯(cuò)誤的:

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

          使用+操作符時(shí),如果一邊是數(shù)字,一邊是字符串,就會(huì)自動(dòng)將數(shù)字轉(zhuǎn)換為字符串,例如:

          ${3 + "5"}?

          輸出結(jié)果是:

          35

          使用內(nèi)建的int(后面講述)獲得整數(shù)部分,例如:

          ${(x/2)?int}

          ${1.1?int}

          ${1.999?int}

          ${-1.1?int}

          ${-1.999?int}

          輸出結(jié)果是(假設(shè)x為5):

          2

          1

          1

          -1

          -1
          比較操作符

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

          =和!=兩邊必須是相同類型的值,否則會(huì)產(chǎn)生錯(cuò)誤,例如<#if 1 = "1">會(huì)引起錯(cuò)誤

          Freemarker是精確比較,所以對(duì)"x"、"x? "和"X"是不相等的

          對(duì)數(shù)字和日期可以使用<、<=、>和>=,但不能用于字符串

          由于Freemarker會(huì)將>解釋成FTL標(biāo)記的結(jié)束字符,所以對(duì)于>和>=可以使用括號(hào)來避免這種情況,例如<#if (x > y)>

          另一種替代的方法是,使用lt、lte、gt和gte來替代<、<=、>和>=
          邏輯操作符

          &&(and)、||(or)、!(not),只能用于布爾值,否則會(huì)產(chǎn)生錯(cuò)誤

          例子:

          <#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>?
          內(nèi)建函數(shù)

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

          字符串使用的:

          html:對(duì)字符串進(jìn)行HTML編碼

          cap_first:使字符串第一個(gè)字母大寫

          lower_case:將字符串轉(zhuǎn)換成小寫

          upper_case:將字符串轉(zhuǎn)換成大寫

          trim:去掉字符串前后的空白字符

          序列使用的:

          size:獲得序列中元素的數(shù)目

          數(shù)字使用的:

          int:取得數(shù)字的整數(shù)部分(如-1.9?int的結(jié)果是-1)

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

          ${test?html}

          ${test?upper_case?html}

          輸出結(jié)果是:

          Tom &amp; Jerry

          TOM &amp; JERRY?
          操作符優(yōu)先順序

          操作符組
          ?

          操作符

          后綴
          ?

          [subvarName] [subStringRange] . (methodParams)

          一元
          ?

          +expr、-expr、!

          內(nèi)建
          ?

          ?

          乘法
          ?

          *、 / 、%

          加法
          ?

          +、-

          關(guān)系
          ?

          <、>、<=、>=(lt、lte、gt、gte)

          相等
          ?

          ==(=)、!=

          邏輯and
          ?

          &&

          邏輯or
          ?

          ||

          數(shù)字范圍
          ?

          ..

          (4)Interpolation
          Interpolation有兩種類型:

          通用Interpolation:${expr}

          數(shù)字Interpolation:#{expr}或#{expr; format}
          注意:Interpolation只能用于文本部分
          通用Interpolation

          插入字符串值:直接輸出表達(dá)式結(jié)果

          插入數(shù)字值:根據(jù)缺省格式(由#setting指令設(shè)置)將表達(dá)式結(jié)果轉(zhuǎn)換成文本輸出;可以使用內(nèi)建函數(shù)string格式化單個(gè)Interpolation,下面是一個(gè)例子:

          <#setting number_format="currency"/>

          <#assign answer=42/>

          ${answer}

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

          ${answer?string.number}

          ${answer?string.currency}

          ${answer?string.percent}

          輸出結(jié)果是:

          $42.00

          $42.00

          42

          $42.00

          4,200%

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

          ${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')'")}?

          輸出的結(jié)果類似下面的格式:

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

          Tue, Apr 8, '03

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

          插入布爾值:根據(jù)缺省格式(由#setting指令設(shè)置)將表達(dá)式結(jié)果轉(zhuǎn)換成文本輸出;可以使用內(nèi)建函數(shù)string格式化單個(gè)Interpolation,下面是一個(gè)例子:

          <#assign foo=true/>

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

          輸出結(jié)果是:

          yes
          數(shù)字Interpolation的#{expr; format}形式可以用來格式化數(shù)字,format可以是:

          mX:小數(shù)部分最小X位

          MX:小數(shù)部分最大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? -->?


          4、雜項(xiàng)

          (1)用戶定義指令
          宏和變換器變量是兩種不同類型的用戶定義指令,它們之間的區(qū)別是宏是在模板中使用macro指令定義,而變換器是在模板外由程序定義,這里只介紹宏
          基本用法

          宏是和某個(gè)變量關(guān)聯(lián)的模板片斷,以便在模板中通過用戶定義指令使用該變量,下面是一個(gè)例子:

          <#macro greet>
          ?<font size="+2">Hello Joe!</font>

          </#macro>?

          作為用戶定義指令使用宏變量時(shí),使用@替代FTL標(biāo)記中的#

          <@greet></@greet>

          如果沒有體內(nèi)容,也可以使用:

          <@greet/>
          參數(shù)

          在macro指令中可以在宏變量之后定義參數(shù),如:

          <#macro greet person>
          ?<font size="+2">Hello ${person}!</font>

          </#macro>

          可以這樣使用這個(gè)宏變量:

          <@greet person="Fred"/> and <@greet person="Batman"/>

          輸出結(jié)果是:
          ?<font size="+2">Hello Fred!</font>
          and?? <font size="+2">Hello Batman!</font>
          ?

          宏的參數(shù)是FTL表達(dá)式,所以下面的代碼具有不同的意思:

          <@greet person=Fred/>

          這意味著將Fred變量的值傳給person參數(shù),該值不僅是字符串,還可以是其它類型,甚至是復(fù)雜的表達(dá)式

          宏可以有多參數(shù),下面是一個(gè)例子:

          <#macro greet person color>
          ?<font size="+2" color="${color}">Hello ${person}!</font>

          </#macro>

          可以這樣使用該宏變量:

          <@greet person="Fred" color="black"/>

          其中參數(shù)的次序是無關(guān)的,因此下面是等價(jià)的:

          <@greet color="black" person="Fred"/>

          只能使用在macro指令中定義的參數(shù),并且對(duì)所有參數(shù)賦值,所以下面的代碼是錯(cuò)誤的:

          <@greet person="Fred" color="black" background="green"/>

          <@greet person="Fred"/>

          可以在定義參數(shù)時(shí)指定缺省值,如:

          <#macro greet person color="black">
          ?<font size="+2" color="${color}">Hello ${person}!</font>

          </#macro>?

          這樣<@greet person="Fred"/>就正確了

          宏的參數(shù)是局部變量,只能在宏定義中有效
          嵌套內(nèi)容

          用戶定義指令可以有嵌套內(nèi)容,使用<#nested>指令執(zhí)行指令開始和結(jié)束標(biāo)記之間的模板片斷

          例子:

          <#macro border>
          ?<table border=4 cellspacing=0 cellpadding=4><tr><td>
          ?? <#nested>
          ?</tr></td></table>

          </#macro>?

          這樣使用該宏變量:

          <@border>The bordered text</@border>

          輸出結(jié)果:
          ?<table border=4 cellspacing=0 cellpadding=4><tr><td>
          ?? The bordered text
          ?</tr></td></table>
          ?

          <#nested>指令可以被多次調(diào)用,例如:

          <#macro do_thrice>
          ?<#nested>
          ?<#nested>
          ?<#nested>

          </#macro>

          <@do_thrice>
          ?Anything.

          </@do_thrice>?

          輸出結(jié)果:
          ?Anything.
          ?Anything.
          ?Anything.

          嵌套內(nèi)容可以是有效的FTL,下面是一個(gè)有些復(fù)雜的例子:

          <@border>
          ?<ul>
          ?<@do_thrice>
          ?? <li><@greet person="Joe"/>
          ?</@do_thrice>
          ?</ul>

          </@border>

          輸出結(jié)果:
          ?<table border=4 cellspacing=0 cellpadding=4><tr><td>
          ???? <ul>
          ?? <li><font size="+2">Hello Joe!</font>

          ?? <li><font size="+2">Hello Joe!</font>

          ?? <li><font size="+2">Hello Joe!</font>

          ?</ul>

          ?</tr></td></table>?

          宏定義中的局部變量對(duì)嵌套內(nèi)容是不可見的,例如:

          <#macro repeat count>
          ?<#local y = "test">
          ?<#list 1..count as x>
          ?? ${y} ${count}/${x}: <#nested>
          ?</#list>

          </#macro>

          <@repeat count=3>${y?default("?")} ${x?default("?")} ${count?default("?")}</@repeat>

          輸出結(jié)果:
          ?? test 3/1: ? ? ?
          ?? test 3/2: ? ? ?
          ?? test 3/3: ? ? ?

          在宏定義中使用循環(huán)變量

          用戶定義指令可以有循環(huán)變量,通常用于重復(fù)嵌套內(nèi)容,基本用法是:作為nested指令的參數(shù)傳遞循環(huán)變量的實(shí)際值,而在調(diào)用用戶定義指令時(shí),在<@…>開始標(biāo)記的參數(shù)后面指定循環(huán)變量的名字

          例子:

          <#macro repeat count>
          ?<#list 1..count as x>
          ?? <#nested x, x/2, x==count>
          ?</#list>

          </#macro>

          <@repeat count=4 ; c, halfc, last>
          ?${c}. ${halfc}<#if last> Last!</#if>

          </@repeat>?

          輸出結(jié)果:
          ?1. 0.5
          ?2. 1
          ?3. 1.5
          ?4. 2 Last!
          ?

          指定的循環(huán)變量的數(shù)目和用戶定義指令開始標(biāo)記指定的不同不會(huì)有問題

          調(diào)用時(shí)少指定循環(huán)變量,則多指定的值不可見

          調(diào)用時(shí)多指定循環(huán)變量,多余的循環(huán)變量不會(huì)被創(chuàng)建

          (2)在模板中定義變量
          在模板中定義的變量有三種類型:

          plain變量:可以在模板的任何地方訪問,包括使用include指令插入的模板,使用assign指令創(chuàng)建和替換

          局部變量:在宏定義體中有效,使用local指令創(chuàng)建和替換

          循環(huán)變量:只能存在于指令的嵌套內(nèi)容,由指令(如list)自動(dòng)創(chuàng)建;宏的參數(shù)是局部變量,而不是循環(huán)變量
          局部變量隱藏(而不是覆蓋)同名的plain變量;循環(huán)變量隱藏同名的局部變量和plain變量,下面是一個(gè)例子:

          <#assign x = "plain">

          1. ${x}? <#-- we see the plain var. here -->

          <@test/>

          6. ${x}? <#-- the value of plain var. was not changed -->

          <#list ["loop"] as x>
          ?? 7. ${x}? <#-- now the loop var. hides the plain var. -->
          ?? <#assign x = "plain2"> <#-- replace the plain var, hiding does not mater here -->
          ?? 8. ${x}? <#-- it still hides the plain var. -->

          </#list>

          9. ${x}? <#-- the new value of plain var. -->


          <#macro test>
          ?2. ${x}? <#-- we still see the plain var. here -->
          ?<#local x = "local">
          ?3. ${x}? <#-- now the local var. hides it -->
          ?<#list ["loop"] as x>
          ?? 4. ${x}? <#-- now the loop var. hides the local var. -->
          ?</#list>
          ?5. ${x}? <#-- now we see the local var. again -->

          </#macro>?

          輸出結(jié)果:

          1. plain
          ?2. plain
          ?3. local
          ?? 4. loop
          ?5. local

          6. plain
          ?? 7. loop
          ?? 8. loop

          9. plain2

          內(nèi)部循環(huán)變量隱藏同名的外部循環(huán)變量,如:

          <#list ["loop 1"] as x>
          ?${x}
          ?<#list ["loop 2"] as x>
          ?? ${x}
          ?? <#list ["loop 3"] as x>
          ???? ${x}
          ?? </#list>
          ?? ${x}
          ?</#list>
          ?${x}

          </#list>

          輸出結(jié)果:
          ?loop 1
          ?? loop 2
          ???? loop 3
          ?? loop 2
          ?loop 1
          模板中的變量會(huì)隱藏(而不是覆蓋)數(shù)據(jù)模型中同名變量,如果需要訪問數(shù)據(jù)模型中的同名變量,使用特殊變量global,下面的例子假設(shè)數(shù)據(jù)模型中的user的值是Big Joe:

          <#assign user = "Joe Hider">

          ${user}????????? <#-- prints: Joe Hider -->

          ${.globals.user} <#-- prints: Big Joe -->?

          (3)名字空間
          通常情況,只使用一個(gè)名字空間,稱為主名字空間
          為了創(chuàng)建可重用的宏、變換器或其它變量的集合(通常稱庫),必須使用多名字空間,其目的是防止同名沖突
          創(chuàng)建庫

          下面是一個(gè)創(chuàng)建庫的例子(假設(shè)保存在lib/my_test.ftl中):

          <#macro copyright date>
          ?<p>Copyright (C) ${date} Julia Smith. All rights reserved.
          ?<br>Email: ${mail}</p>

          </#macro>?

          <#assign mail = "jsmith@acme.com">

          使用import指令導(dǎo)入庫到模板中,F(xiàn)reemarker會(huì)為導(dǎo)入的庫創(chuàng)建新的名字空間,并可以通過import指令中指定的散列變量訪問庫中的變量:

          <#import "/lib/my_test.ftl" as my>

          <#assign mail="fred@acme.com">

          <@my.copyright date="1999-2002"/>

          ${my.mail}

          ${mail}?

          輸出結(jié)果:
          ?<p>Copyright (C) 1999-2002 Julia Smith. All rights reserved.
          ?<br>Email: jsmith@acme.com</p>

          jsmith@acme.com

          fred@acme.com?

          可以看到例子中使用的兩個(gè)同名變量并沒有沖突,因?yàn)樗鼈兾挥诓煌拿挚臻g
          可以使用assign指令在導(dǎo)入的名字空間中創(chuàng)建或替代變量,下面是一個(gè)例子:

          <#import "/lib/my_test.ftl" as my>

          ${my.mail}

          <#assign mail="jsmith@other.com" in my>

          ${my.mail}?
          輸出結(jié)果:

          jsmith@acme.com

          jsmith@other.com?
          數(shù)據(jù)模型中的變量任何地方都可見,也包括不同的名字空間,下面是修改的庫:

          <#macro copyright date>
          ?<p>Copyright (C) ${date} ${user}. All rights reserved.</p>

          </#macro>

          <#assign mail = "${user}@acme.com">??
          假設(shè)數(shù)據(jù)模型中的user變量的值是Fred,則下面的代碼:

          <#import "/lib/my_test.ftl" as my>

          <@my.copyright date="1999-2002"/>

          ${my.mail}??
          輸出結(jié)果:
          ?<p>Copyright (C) 1999-2002 Fred. All rights reserved.</p>

          posted @ 2007-01-11 00:33 憶了又憶| 編輯 收藏

          你想使用FreeMarker做的最后一件事是將表單域綁定到命令屬性中。在第8章中,你使用JSP的 <spring:bind> 標(biāo)簽,而在第9.1.6節(jié)中,你是使用#springBind Velocity宏來實(shí)現(xiàn)這一點(diǎn)的。類似地,Spring提供了一組FreeMarker宏來進(jìn)行這種綁定。

          等價(jià)的FreeMarker宏是< @spring.bind>和<@spring.bindEscaped>。例如,程序清單9.4節(jié)選了 registerStudent.ftl中的一段,演示了如何使用<@spring.bind>指令將status信息綁定到表單中。

           程序清單9.4? 在FreeMarker模板中使用<@spring.bind>
          <@spring.bind "command.phone" />

          ? phone: <input type="text"

          ????? name="${spring.status.expression}"

          ??? ??value="${spring.status.value}">

          ? <font color="#FF0000">${spring.status.errorMessage}</font><br>

          <@spring.bind "command.email" />

          ????? email: <input type="text"

          ????? name="${spring.status.expression}"

          ????? value="${spring.status.value}">

          ? <font color="#FF0000">${spring.status.errorMessage}</font><br>

          你可能已經(jīng)注意到程序清單9.4和程序清單9.2非常相像。但這里有兩個(gè)不同。首先,F(xiàn)reeMarker版中不是使用Velocity的#springBind宏,而是使用< @spring.bind>指令。其次,<@spring.bind>將狀態(tài)信息綁定到${spring.status}而不是$ {status}。

          正如Sping的Velocity宏,為了使用這些宏,必須設(shè)置FreeMarkerViewResolver的exposeMacroHelpers屬性為true:

          ?

          ? <bean id="viewResolver" class="org.springframework.

          ????????? ?web.servlet.view.freemarker.FreeMarkerViewResolver">

          ? …

          ??? <property name="exposeSpringMacroHelpers">

          ????? <value>true</value>

          ??? </property>

          ? </bean>

          ?

          最后,你還需要做一件事才能使用FreeMarker宏。在所有需要使用<@spring.bind>和<@spring.bindEscaped>的FreeMarker模板的頂部增加以下一行:

          ?

          ? <#import "/spring.ftl" as spring />

          ?

          這一行會(huì)在模板中導(dǎo)入Spring的FreeMarker宏。

          posted @ 2007-01-11 00:04 憶了又憶| 編輯 收藏

          This is an attempt to put together a comprehensive reference for using Cascading Style Sheets with the Google Web Toolkit. I’ve assembled this document by first starting with the official documentation and then reviewing the source code. Where the source disagreed with the documentation I’ve sided with the source. I then did a runtime analysis of the sample applications that ship with the SDK to verify the results.

          I feel there is a need for this because the documentation that comes with the SDK is rather unhelpful. The SDK says, basically, that widget styles are conventionally named [project]-[widget], e.g., gwt-Button, and style names correspond to CSS class names, so in order to style your button you would include something like

          .gwt-Button { font-size: 150%; }
          				

          in your stylesheet. And that’s all it says. Really.

          I believe this documentation to be inadequate for a number of reasons.

          1. The style is almost never as simple as the button example. Many GWT widgets correspond to messy nested tables, divs, and spans so it can be hard to know what it is you’re actually styling and what options are available to you in that context.
          2. The naming rule is not applied consistently within the SDK. The DialogBox class, for one, does not follow the rule.
          3. In some situations similarly named styles (*-selected*) are used in different or even contradictory manners making it hard to generalize your experience from one widget to another.
          4. In many cases the documentation is incorrect; the documented style simply is not implemented. The ListBox class should, according to both the general rule above and the specific class documentation, implement a style named gwt-ListBox. Nope, not there. Grep the source directory if you don’t believe me.

          If I’ve left out a class below, it’s probably because it doesn’t participate in styling in any way. (I hope.) If you’re trying to read this straight through instead of just jumping to an item of interest, more power to you. If you find yourself yawning you might want to skip around a bit.

          With that said…

          AbsolutePanel

          Implemented as a DIV and by default sets overflow to hidden. Contents are positioned absolutely according to given x, y values unless x == -1 and y == -1 in which case the widget is positioned statically.

          <div style="overflow: hidden;"></div>
          				

          Button

          Implemented as HTML BUTTON. Default style name is gwt-Button and is used. No default attributes. Can contain text or HTML.

          <button class="gwt-Button" />
          				

          CellPanel

          Implemented as a TABLE. No default styles. Can set border and cell-spacing attributes.

          <table>
          </table>
          				

          CheckBox

          Implemented as HTML CHECKBOX. Default style name is gwt-CheckBox and is used. Automatically generates unique id of the form checkN where N is an integer. Uses checked, defaultChecked, and disabled attributes. No default styles.

          <checkbox class="gwt-CheckBox" />
          				

          DeckPanel

          Implemented using a DIV containing any number of children. The visibility of the individual children are controlled using the display attribute. The DeckPanel sets display to 'none' or '' as appropriate.

          <div style="width: 100%; height: 100%"></div>
          				

          DialogBox

          Default style names are gwt-DialogBox and Caption and are both used. Implemented as a DIV and the caption is also a DIV. (Technically, the caption is an HTML, which is a Label, which is implemented using a DIV.)

          <div class="gwt-DialogBox">
            <table cell-spacing="0" cell-padding="0">
              <tbody>
                <tr>
          ??????<td><div class="Caption">caption</div></td> </tr> <tr> <td> content </td> </tr> </tbody> </table> </div>

          DockPanel

          Implemented using TABLE. cell-spacing and cell-padding attributes both default to 0. Nesting of TR and TD elements can get quite complicated in order to achieve desired layout.

          <table cell-spacing="0" cell-padding="0">
            <tbody>
            </tbody>
          </table>
          				

          FlexTable

          Just a TABLE, there’s nothing funky going on here.

          <table>
            <tbody>
            </tbody>
          </table>
          				

          FlowPanel

          Implemented as a DIV with display set to inline.

          <div style="display: inline;">content</div>
          				

          FocusPanel

          A DIV. FocusPanel is only important in that it publishes a number of events (FOCUSEVENTS, KEYEVENTS, ONCLICK, and MOUSEEVENTS) and is very useful for containing widgets that don’t publish their own events. See Drag-and-Drop with the Google Web Toolkit.

          <div>
            content
          </div>
          				

          FocusWidget

          Can be anything because it is implemented using whatever element is passed to it in the constructor. Interesting because it generates FOCUSEVENTS and KEYEVENTS.

          Frame

          Implemented as an IFRAME. Documented style name of gwt-Frame is not implemented.

          <iframe>
          </iframe>
          				

          Grid

          Is just a table.

          <table>
            <tbody>
            </tbody>
          </table>
          				

          HTML

          Implemented as a DIV with default style name of gwt-HTML. Can also set attribute white-space to normal or nowrap.

          <div class="gwt-HTML">html</div>
          				

          HTMLPanel

          Is a DIV that can either contain HTML exactly as HTMLor a collection of widgets. Does not use the gwt-HTML style. The most useful attribute of an HTMLPanel is that it contains the method createUniqueId that returns an id of the form HTMLPanel_N that can be used to apply styles to specific elements, as opposed to classes.

          Contrast this with CheckBox which generates ids of the form checkN without either the capitalization or the underscore. Not a bug, just another minor inconsistency.

          <div>
            content
          </div>
          				

          HTMLTable

          Unsurprisingly this class is implemented as a TABLE. The most important things to know about HTMLTable are (a) that it is the superclass for both FlexTable and Grid and (b) that it provides methods for setting the styles of individual rows or cells.

          It is also worth noting that HTMLTable does not include a THEAD. The 0th row therefore must be used as something of a pseudo-header by applying any necessary styles.

          <table>
            <tbody>
              <tr>Row 0 -- if you want a header you have to fake it here.</tr>
            </tbody>
          </table>
          				
          // Style the first row to fake a header.
          table.getRowFormatter(0).setStyleName("something-interesting");
          				

          HorizontalPanel

          Implemented using a TABLE with all elements laid out as TDs in a single TR.

          <table cell-spacing="0" cell-padding="0">
            <tbody>
              <tr>
                <td style="display: static; vertical-align: top;" align="left">Item 1</td>
                <td style="display: static; vertical-align: top;" align="left">Item 2</td>
              </tr>
            </tbody>
          </table>
          				

          HyperLink

          A DIV containing an anchor. Documented style name gwt-HyperLink is not implemented.

          <div></div>
          				

          Image

          Implemented as IMG. Documented style of gwt-Image is not implemented.

          <img src="..." />
          				

          Label

          Label is implemented as a DIV with a default style name of gwt-Label. Labels do not interpret their content as HTML and by default allow word-wrap. If you want to use HTML content in your label then you should use an instance of HTML. Both classes provide MOUSEEVENTS.

          You can change the default word-wrap by calling the setWordWrap method.

          <div class="gwt-Label">your text here</div>
          				

          ListBox

          Implemented using SELECT with OPTION for elements. Documented style name gwt-ListBox is not implemented. Uses attributes selected, size, and multiple as part of implementation.

          MenuBar

          Implemented as a DIV containing a TABLE with menu items contained in TD elements. A horizontal MenuBar contains all menu items as children of a single TR and a vertical MenuBar uses a separate TR for each item. Simple enough. The documented style name of gwt-MenuBar is used and applied to the outer DIV.

          <div class="gwt-MenuBar">
            <table>
              <tbody>
                
                <tr>
                  <td class="gwt-MenuItem">text or html</td>
                  <td class="gwt-MenuItem">text or html</td>
                </tr>
                <!-- example of a vertical menu
                  <tr><td class="gwt-MenuItem">text or html</td></tr>
                  <tr><td class="gwt-MenuItem">text or html</td></tr>
                -->
              </tbody>
            </table>
          </div>
          				

          MenuItem

          A MenuItem is a TD that can be inserted into a MenuBar. The default style name is gwt-MenuItem. A selected MenuItem has the additional style name of gwt-MenuItem-selected. I want to emphasize that the selected style is added to the default style, so that class="gwt-MenuItem" becomes class="gwt-MenuItem gwt-MenuItem-selected". This is not the case with all widgets and is another minor inconsistency in the GWT style design. See StackPanel for an example of the opposite behavior.

          PasswordTextBox

          Implemented as PASSWORD. Uses gwt-PasswordTextBox.

          PopupPanel

          Just a DIV.

          RadioButton

          Implemented as an instance of INPUT. Uses gwt-RadioButton.

          RootPanel

          A RootPanel can be attached to any element, but it will discard all children previously belonging to that element. If you stop to think about it, this can be useful in contexts outside of your application init.

          ScrollPanel

          A DIV with overflow set to scroll or auto. Defaults to auto.

          <div style="overflow: auto;">
            content
          </div>
          				

          SimplePanel

          Just a DIV.

          StackPanel

          Implemented as a TABLE with 2 rows per item. In each pair of rows the first contains the caption and the second contains the corresponding widget. By default the TABLE is styled with gwt-StackPanel. The captions are styled with gwt-StackPanelItem and gwt-StackPanelItem-selected. When an item is selected the caption’s unselected style gwt-StackPanelItem is replaced with gwt-StackPanelItem-selected. Not all widgets behave this way. See MenuItem for an example of the opposite behavior.

          <table class="gwt-StackPanel" cell-spacing="0" cell-padding="0">
            <tbody>
              
              <tr>
                <td class="gwt-StackPanelItem" height="1px">text/html</td>
              </tr>
              <tr>
                <td height="100%" valign="top">
                  content -- a widget
                </td>
              </tr>
            </tbody>
          </table>
          				

          TabBar

          A TabBar is implemented using a HorizontalPanel so it is effectively a TABLE. The style name gwt-TabBar applies to the TABLE — that is, to the actual tabs. The style gwt-TabBarFirst applies to the first (effectively empty) HTML widget and is only useful for creating some sort of left border effect. The style gwt-TabBarRest applies to that part of the TabBar following the tabs.

          When a tab is selected the style gwt-TabBarItem-selected gets added to the existing style. This behavior is like that of MenuItem but opposite that of StackPanel.

          <table class="gwt-TabBar" cell-spacing="0" cell-padding="0">
            <tbody>
              <tr>
                <td class="gwt-TabBarFirst" style="height: 100%;"><div class="gwt-HTML" style="height: 100%;">&amp;nbsp;</div></td>
                <td>Tab #1</td>
                <td>Tab #2</td>
                <td class="gwt-TabBarRest" style="width: 100%;"><div class="gwt-HTML" style="height: 100%;">&amp;nbsp;</div></td>
              </tr>
            </tbody>
          </table>
          				

          TabPanel

          Implemented as a VerticalPanel containing a TabBar and a DeckPanel. In other words, it’s a bunch of nested tables. The style gwt-TabPanel applies to the top-level TABLE, gwt-TabBar still applies to the contained TABLE implementing the TabBar, and gwt-TabPanelBottom styles the DIV containing the actual content.

          Note that the TabBar gets the added default style of width: 100%. This ensures that the TabBar is as wide as the content panel and is the reason the gwt-TabBarRest style is important. It’s all about how you want that empty space to look.

          <table class="gwt-TabPanel" cell-spacing="0" cell-padding="0">
            <tbody>
              <tr>
                <td>
                  
                  <table class="gwt-TabBar" style="width: 100%;" cell-spacing="0" cell-padding="0">
                    <tbody>
                      <tr>
                        <td class="gwt-TabBarFirst" style="height: 100%;"><div class="gwt-HTML" style="height: 100%;">&amp;nbsp;</div></td>
          	      
                        <td class="gwt-TabBarRest" style="width: 100%;"><div class="gwt-HTML" style="height: 100%;">&amp;nbsp;</div></td>
                      </tr>
                    </tbody>
                  </table>
                </td>
              </tr>
              <tr>
                <td>
                  <div class="gwt-TabPanelBottom">
          	  
          	</div>
                </td>
              </tr>
            </tbody>
          </table>
          				

          TextArea

          Implemented as a TEXTAREA with a default style of gwt-TextArea.

          TextBox

          <input type="text" class="gwt-TextBox" />
          				

          Tree

          Implemented as a DIV containing nested TreeItems. The style name gwt-Tree applies to the DIV and the style overflow defaults to auto.

          <div class="gwt-Tree" style="overflow: auto;">
            
            <div style="position: relative; margin-left: 16;" (handle)>
              <table>
                <tr>
                  <td></td>
                  <td></td>
                </tr>
              </table>
              
            </div>
          </div>
          				

          TreeItem

          Implemented as a TABLE nested within a DIV. The styles gwt-TreeItem and gwt-TreeItem-selected apply to the nested content element, a SPAN. The selected state gwt-TreeItem-selectedreplaces the unselected state gwt-TreeItem, like StackPanel but unlike MenuItem or TabBar.

          <div style="position: relative; margin-left: 16; white-space: nowrap" (handle)>
            <table style="white-space: nowrap;">
              <tr>
                <td style="vertical-align: middle;"><img src="tree_white.gif" /></td>
                <td style="vertical-align: middle;">content</td>
              </tr>
            </table>
            children
          </div>
          				

          VerticalPanel

          Implemented using a TABLE with all elements laid out as TRs.

          <table cell-spacing="0" cell-padding="0">
            <tbody>
              <tr><td style="display: static; vertical-align: top;" align="left">Item 1</td></tr>
              <tr><td style="display: static; vertical-align: top;" align="left">Item 2</td></tr>
            </tbody>
          </table>
          				

          posted @ 2007-01-10 17:08 憶了又憶| 編輯 收藏

          在Oracle9i Rlease2中,Oracle的全文檢索技術(shù)被稱為:Oracle Text,功能十分強(qiáng)大。Oracle Text是Oracle9i采用的新名稱,在Oracle8/8i中它被稱作Oracle interMedia Text,在Oracle8以前它的名稱是Oracle ConText Cartridge。
          Oracle Text組件可以在安裝數(shù)據(jù)庫的時(shí)候選擇,缺省是安裝的,如果沒有安裝,那么可以按照以下方式手動(dòng)安裝Oracle Text。
          1.創(chuàng)建存儲(chǔ)表空間

          $ sqlplus "/ as sysdba"

          SQL*Plus: Release 9.2.0.4.0 - Production on Sun May 15 19:54:48 2005

          Copyright (c) 1982, 2002, Oracle Corporation.? All rights reserved.


          Connected to:
          Oracle9i Enterprise Edition Release 9.2.0.4.0 - 64bit Production
          With the Partitioning, OLAP and Oracle Data Mining options
          JServer Release 9.2.0.4.0 - Production

          SQL> select name from v$datafile;

          NAME
          --------------------------------------------------------------------------------
          /h2love/oracle/system01.dbf
          /h2love/oracle/undotbs01.dbf
          /h2love/oracle/users01.dbf
          ...

          9 rows selected.

          SQL> create tablespace oratext
          ? 2? datafile '/h2love/oracle/oratext01.dbf' size 100m
          ? 3? extent management local uniform size 128k
          ? 4? ;?????

          Tablespace created.


          2.創(chuàng)建相關(guān)對(duì)象
          SQL> spool text.log
          SQL> connect sys/oracleHURRAY as sysdba
          Connected.
          SQL> start ?/ctx/admin/dr0csys password oratext temp
          ...creating user CTXSYS
          ...creating role CTXAPP
          SQL> connect ctxsys/password
          Connected.
          SQL> start ?/ctx/admin/dr0inst ?/ctx/lib/libctxx9.so
          ==============? ConText Database Objects Installation ==============

          This script must be run as CTXSYS.? This script will exit
          below if run as any other user.

          User is CTXSYS
          ... creating tables and Oracle object types
          ... creating table dr$parameter
          ... creating table dr$class
          ... creating table dr$object
          ... creating table dr$object_attribute
          ... creating table dr$object_attribute_lov
          ... creating table dr$preference
          ... creating table dr$preference_value
          ... creating table dr$index
          ... creating table dr$index_partition
          ... creating table dr$index_value
          ... creating table dr$policy_tab
          ... creating table dr$sqe
          ... creating table dr$ths
          ... creating table dr$ths_phrase
          ... creating table dr$ths_fphrase
          ... creating table dr$ths_bt
          ... creating table dr$section_group
          ... creating table dr$section
          ... creating table dr$stoplist
          ... creating table dr$stopword
          ... creating table dr$sub_lexer
          ... creating table dr$index_set
          ... creating table dr$index_set_index
          ... creating table dr$server
          ... creating table dr$pending
          ... creating table dr$waiting
          ... creating table dr$online_pending
          ... creating table dr$delete
          ... creating table dr$unindexed
          ... creating table dr$index_error
          ... creating table dr$parallel
          ... creating table dr$stats
          ... creating table dr$part_stats
          ... creating named data type ctx_feedback_item_type
          ... creating named data type ctx_feedback_type
          ... creating safe callout library
          ... creating CONTEXT interface
          drop public synonym contains


          這樣就完成了手工安裝全文檢索工具。

          posted @ 2007-01-10 13:54 憶了又憶| 編輯 收藏

          查詢文本不同于查詢數(shù)據(jù),因?yàn)橛型x詞、近義詞和反義詞。你可能希望搜索互相接近的詞或搜索相關(guān)聯(lián)的詞。如果僅使用標(biāo)準(zhǔn)的關(guān)系操作符,要進(jìn)行這些查詢是非常困難的。通過SQL進(jìn)行擴(kuò)充,使其包含文本索引,則ORACLE TEXT允許用戶就文本提出非常復(fù)雜的問題。
          文本索引主要有兩種CONTEXT和CTXCAT

          用如下方式建立索引
          CREATE INDEX REVIEW_CONTEXT_INDEX ON BOOK_REVIEW_CONTEXT(REVIEW_TEXT) INDEXTYPE IS CTXSYS.CONTEXT;

          CREATE INDEX REVIEW_CTXCAT_INDEX ON BOOK_REVIEW_CTXCAT(REVIEW_TEXT) INDEXTYPE IS CTXSYS.CTXCAT;

          建立好索引后就可以進(jìn)行文本查詢
          select title from book_review_context where contains(review_text,'property')>0
          CONTAINS函數(shù)有兩個(gè)參數(shù)即列名和搜索串,它檢查review_text列的文本索引。如果在review_text列的文本索引中找到單詞'property'則數(shù)據(jù)庫返回的得分大于0,并返回匹配的TITLE值。

          如果建立的是CTXCAT索引就用CATSEARCH函數(shù)
          select title from book_review_ctxcat where catsearch(review_text,'property',null)>0;

          可使用的文本查詢表達(dá)式有以下幾種:
          1。單詞的精確匹配搜索
          select title from book_review_context where contains(review_text,'property')>0
          2。多個(gè)單詞精確匹配的搜索
          可以使用AND連接多個(gè)單詞
          select title from book_review_context where contains(review_text,'property and harvests')>0
          還可以使用&但是在SQLPLUS里必須執(zhí)行set define off否則&將被視作變量
          set define off
          select title from book_review_context where contains(review_text,'property & harvests')>0
          對(duì)于CTXCAT索引AND完全可以省略
          select title from book_review_ctxcat where catsearch(review_text,'property harvests',null)>0;
          除AND外還可以使用OR運(yùn)算符在ORACLE TEXT中OR是一根豎線(|)
          因此下面的兩個(gè)查詢是等同的
          select title from book_review_context where contains(review_text,'property or harvests')>0

          select title from book_review_context where contains(review_text,'property | harvests')>0
          但是要注意CATSEARCH函數(shù)不支持OR只支持‘|’符號(hào);
          ACCUM(累加)提供了另一種組合搜索的方法。等價(jià)于逗號(hào),所以下面的兩個(gè)查詢是等價(jià)的
          select title from book_review_context where contains(review_text,'property accum harvests')>0
          select title from book_review_context where contains(review_text,'property , harvests')>0
          但是CATSEARCH函數(shù)調(diào)用支持ACCUM語法但不應(yīng)該使用,因?yàn)镃ATSEARCH不計(jì)算用來與閥值進(jìn)行比較的得分;
          MINUS運(yùn)算符從第一項(xiàng)搜索的得分中減去第二項(xiàng)搜索的得分等價(jià)于減號(hào),所以下面的兩個(gè)查詢是等價(jià)的
          select title from book_review_context where contains(review_text,'property minus harvests')>0
          select title from book_review_context where contains(review_text,'property - harvests')>0
          可以用圓括號(hào)來闡明搜索條件內(nèi)的邏輯
          select title from book_review_context where contains(review_text,'house or (workers and harvests')>0
          3。短語精確匹配的搜索
          在進(jìn)行短語搜索的時(shí)候應(yīng)將整個(gè)短語作為搜索串的一部分
          select title from book_review_context where contains(review_text,'doctor visits')>0
          若搜索的短語中包含ORACLE TEXT內(nèi)的保留字,則必須使用花括號(hào)括住相應(yīng)的保留字
          select title from book_review_context where contains(review_text,'taengdmg {and} dfdng)>0
          4。搜索互相接近的詞
          select title from book_review_context where contains(review_text,'property near harvests')>0
          可以使用關(guān)鍵詞NEAR也可以用;代替NEAR
          5。在搜索中使用通配符
          select title from book_review_context where contains(review_text,'worker%')>0
          select title from book_review_context where contains(review_text,'work___)>0
          6。搜索具有相同詞根的詞
          select title from book_review_context where contains(review_text,'$worker')>0
          7。模糊匹配搜索
          select title from book_review_context where contains(review_text,'?worker')>0
          8。搜索發(fā)音相似的詞
          select title from book_review_context where contains(review_text,'!worker')>0
          9。使用ABOUT運(yùn)算符
          在ORACLE TEXT中可以搜索文檔的主題
          select review_text from book_review_context where contains(review_text,'about(mdgd)')>0
          10。索引集
          為了建立一個(gè)名為reviews的索引集可使用CREATE_INDEX_SET過程
          execute ctx_ddl.create_index_set('reviews)
          可以通過add_index過程添加索引到索引集中了
          execute ctx_ddl.add_index('reviewers','reviewer');

          posted @ 2007-01-10 13:50 憶了又憶| 編輯 收藏

          Field Name Mandatory? Allowed Values Allowed Special Characters
          Seconds YES 0-59 , - * /
          Minutes YES 0-59 , - * /
          Hours YES 0-23 , - * /
          Day of month YES 1-31 , - * ? / L W C
          Month YES 1-12 or JAN-DEC , - * /
          Day of week YES 1-7 or SUN-SAT , - * ? / L C #
          Year NO empty, 1970-2099 , - * /
          ?
          項(xiàng)目實(shí)例:
          ????????????? second? minute? hours? dayOfMonth? month? dayOfWeek? year
          每月???????? 0??????????? 0?????????? 6????????????????????????????????? ?*??????????????? 6#3??????????? ?
          每周????????59???????????59?????????18??????????????????????????????? ?*????????????????1??????????????? ?
          自定義????28? ????????47??????????9?????????????30?????????????????7????????????? ??????????????? 2006
          ?
          每月:每個(gè)月的第三個(gè)星期五的上午6:00:00 觸發(fā)
          每周:每周的星期日的下午18:59:59 觸發(fā)
          自定義:2006年7月30日上午9:47:28 觸發(fā)
          ?

          所有星號(hào)對(duì)應(yīng)的段位置,都可以出現(xiàn)后面的符號(hào)(, - * /)
          (? / L C)這些符號(hào)可以出現(xiàn)在"一月哪天"和"星期"段位置
          (w)只能出現(xiàn)在"一月哪天"段位置
          (#)只能出現(xiàn)在"星期"段位置

          解釋符號(hào)代表的意思:
          * 代表任意合法的字段
          0 * 17 * * ? :表示在每天的5 PM 到 5:59之間的每一分鐘啟動(dòng)scheduler

          ? 表示沒值被指定
          如果同時(shí)指定"一月哪天"和"星期",可能兩者對(duì)應(yīng)不起來
          0 0,15,30,45 * * * ? :表示每刻鐘啟動(dòng)scheduler
          所以推薦用法是其中一個(gè)指定值,另一個(gè)用?指定

          / 表示時(shí)間的增量
          0 0/15 * * * ? :表示每刻鐘啟動(dòng)scheduler

          - 表示值的范圍
          0 45 3-8 ? * *

          L 如果用在"一月哪天"段上,表示一個(gè)月的最后一天;如果用在"星期"段上。表示一個(gè)星期的最后一天(星期六)
          0 0 8 L * ? :表示每個(gè)月最后一天的8點(diǎn)啟動(dòng)scheduler

          W 表示最靠近給定時(shí)間的一天,(必須是星期一到星期五)

          # 例如 6#3表示一個(gè)月的第三個(gè)星期五

          posted @ 2007-01-10 13:45 憶了又憶| 編輯 收藏

          主站蜘蛛池模板: 沁阳市| 呼和浩特市| 英德市| 拉孜县| 岳池县| 无极县| 正安县| 乌拉特后旗| 额敏县| 浮梁县| 岳池县| 康定县| 永福县| 呼图壁县| 旌德县| 屏南县| 罗山县| 福鼎市| 涟水县| 沿河| 台湾省| 格尔木市| 武功县| 麻城市| 瑞安市| 石柱| 报价| 个旧市| 大庆市| 永昌县| 黄冈市| 阿瓦提县| 钟山县| 延边| 桐城市| 蒙山县| 定边县| 孟连| 广灵县| 尤溪县| 苍山县|