freemarker 模板,freemarker
1 總體結構
模板(FTL 編程)是由如下部分混合而成的:
Text 文本:文本會照著原樣來輸出。
Interpolation 插值:這部分的輸出會被計算的值來替換。插值由${和}所分隔(或者#{和},這種風格已經不建議再使用了)。
FTL tags 標籤:FTL 標籤和 HTML 標籤很相似,但是它們卻是給 FreeMarker 的指示,而且不會列印在輸出內容中。
Comments 注釋:FTL 的注釋和 HTML 的注釋也很相似,但它們是由<#--和-->來分隔的。注釋會被 FreeMarker 所忽略,更不會在輸出內容中顯示。
2 指令
使用 FTL 標籤來調用 directives 指令,比如調用 list 指令。
指令有兩種類型:預定義指令和使用者自訂指令。對於使用者自訂的指令使用@來代替#
更深的區別在於如果指令沒有嵌套內容,那麼必須這麼使用 <@mydirective parameters />而預定義指定則為<#directive something>
FreeMarker 可以不需要#來理解預定義指令(比如<if user == "Big Joe">...</if>)。而我們不建議這樣來使用。
3 運算式
當需要給插值或者指令參數提供值時,可以使用變數或其他複雜的運算式。例如,我們設 x 為 8,y 為 5,那麼(x+y)/2 的值就會被處理成數字類型的值 6.5
當給插值提供值時:插值的使用方式為${expression}
當給指令參數提供值時:在入門章節我們已經看到 if 指令的使用了。這個指令的文法是:<#if expression>...</#if>。這裡的運算式計算結果必須是布爾類型的。
快速探索(備忘單)
直接確定值
_1 字串
如果文本本身包含用於字元引用的引號(雙引號”或單引號’)或反斜線時,應該在它們的前面再加一個反斜線,這就是轉義。轉義允許你直接在文本中輸入任何字元,也包括反斜線。
下面的表格是 FreeMarker 支援的所有逸出字元。
原生字串:在原生字串中,反斜線和${沒有特殊的含義,它們被視為普通的字元。為了表明字串是原生字串,在開始的引號或單引號之前放置字母 r,例如:
${r"${foo}"} ${r"C:\foo\bar"}
將會列印:
${foo} C:\foo\bar
_2 數字 輸入不帶引號的數字就可以直接指定一個數字,必須使用點作為小數的分隔字元而不能是
其他的分組分隔字元。
_3 布爾值 直接寫 true 或 false 就表徵一個布爾值了,不需使用引號。
_4 序列
指定一個文字的序列,使用逗號來分隔其中的每個子變數,然後把整個列表放到方括弧中。例如:
<#list ["winter", "spring", "summer", "autumn"] as x> ${x} </#list>
列表中的項目是運算式,那麼也可以這樣做:[2 + 2, [1, 2, 3, 4], "whatnot"],其中第一個子變數是數字 4,第二個子變數是一個序列,第三個子變數是字串”whatnot”。 也可以用 start..end 定義儲存數字範圍的序列,這裡的 start 和 end 是處理數
字值運算式,比如 2..5 和[2, 3, 4, 5]是相同的,但是使用前者會更有效率(記憶體佔用少而且速度快)。可以看出前者也沒有使用方括弧,這樣也可以用來定義遞減的數字範圍,比如 5..2。(此外,還可以省略 end,只需 5..即可,但這樣序列預設包含 5,6,7,8
等遞增量直到無窮大)
_5 雜湊表
在模板中指定一個雜湊表,就可以遍曆用逗號分隔開的“鍵/值”對,把列表放到花括弧內。鍵和值成對出現並以冒號分隔。看這個例子:{"name":"green mouse", "price":150}。注意到名字和值都是運算式,但是用來檢索的名字就必須是字串類型的。
4 檢索變數
_1 頂層變數
為了訪問頂層的變數,可以簡單地使用變數名。
_2 從雜湊表中檢索資料
如果有一個運算式的結果是雜湊表,那麼我們可以使用點和子變數的名字得到它的值.
下面這些樣本它們含義都是相等的:book.author.name, book["author"].name, book.author.["name"], book["author"]["name"]
如果我們想 指 定 同一個運算式 的 子變數,那麼還有另外一種文法格式 :在方括弧中可以給出任意長度字串的運算式。在上面這個資料模型樣本中你還可以這麼來擷取 title:book[test] :這裡的test是根項目test中的值.
_3 從序列中檢索資料
這和從雜湊表中檢索是相同的,但是你只能使用方括弧文法形式來進行,而且方括弧內的運算式最終必須是一個數字而不是字串。在第一章的資料模型樣本中,為了擷取第一個動物的名字(記住第一項數字索引是 0 而不是 1)可以這麼來寫:animals[0].name。
_4 特殊變數
特殊變數是由 FreeMarker 引擎本身定義的,為了使用它們,可以按照如下文法形式來
進行:.variable_name。
通常情況下是不需使用特殊變數,而對專業使用者來說可能用到。所有特殊變數的說明可
以參見參考手冊。
5 字串操作
_1 插值(或串連)
可以在字串的文字中使用${…}(#{…})。${...}的作用和在文本區的是相同的。
也可以使用+號來達到類似的效果,這是比較老的方法,也叫做字串串連。
_2 擷取一個字元
user[0]
擷取一定範圍內的字元,比如${user[1..4]}和${user[4..]}。然而現在這種使用方法已經被廢棄了,作為它的替代,可以使用內建
函數 substring,
6 序列操作
_1 串連
序列的串連可以使用+號來進行,例如:
<#list ["Joe", "Fred"] + ["Julia", "Kate"] as user> - ${user} </#list>
- Joe - Fred - Julia - Kate
_2 序列切分
使 用 [firstindex..lastindex] 可 以 獲 取 序 列 中的一部分 ,這裡的firstindex 和lastindex 運算式的結果是數字。如果seq 儲存序列"a", "b", "c", "d", "e", "f",那麼運算式 seq[1..4]將會是含有"b", "c", "d", "e"的序列(索引為 1 的項是"b",索引為 4 的項是"e")。 lastindex 可以被省略,那麼這樣將會讀取到序列的末尾。如果 seq 儲存序列"a", "b", "c", "d", "e", "f",那麼 seq[3..]將是含有"d", "e", "f"的序列。
7 雜湊表操作
_1 串連
像連接字串那樣,也可以使用+號的方式來串連雜湊表。如果兩個雜湊表含有鍵相同的項,那麼在+號右側的雜湊表中的項目優先。
<#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
8 算數運算
有時我們只想擷取計算結果的整數部分,這可以使用內建函數 int 來解決。
${(x/2)?int} ${1.1?int} ${1.999?int} ${-1.1?int} ${-1.999?int}
9 比較運算
測試兩個值相等使用=(或者採用 Java 和 C 語言中的==,二者是完全等同的。) 測試兩個值不等使用!=。
FreeMarker 解釋>的時候可以把它當作 FTL 標籤的結束符。為了避免這種問題,不得不將運算式放到括弧內:<#if (x > y)>,或者可以在比較關係處使用>和<:<#if x > y>。可以使用 lt 代替<,lte代替<=,gt 代替>,gte 代替>=, 由於曆史遺留的原因,FTL 也支援\lt, \lte, \gt 和 \gte,使用他們和使用不帶反斜線的效果一樣。
10 邏輯操作
11 內建函數
內建函數以?形式提供變數的不同形式或者其他資訊。使用內建函數的文法和訪問雜湊表子變數的文法很像,除了使用?號來代替
點,其他的都一樣。例如得到字串的大寫形式:user?upper_case。
樣本:
${test?html} ${test?upper_case?html}
假設字串 test 儲存”Tom & Jerry”,那麼輸出為:
Tom & Jerry TOM & JERRY
12 方法調用
${repeat("What", 3)}
將會列印出:
WhatWhatWhat
13 處理不存在的值
_1 預設值
使用形式 概 覽 : unsafe_expr!default_expr 或 unsafe_expr! 或(unsafe_expr)!default_expr 或(unsafe_expr)!
這個操作符允許你為可能不存在的變數指定一個預設值。
例如,假設下面展示的代碼中沒有名為 mouse 的變數:
${mouse!"No mouse."} <#assign mouse="Jerry"> ${mouse!"No mouse."}
將會輸出
No mouse. Jerry
預設值可以是任何類型的運算式,也可以不必是字串。你也可以這麼寫:hits!0或 colors!["red", "green", "blue"]。預設值運算式的複雜程度沒有嚴格限制,你還可以這麼來寫:cargo.weight!(item.weight * itemCount + 10) 。
_2 檢測不存在的值
使用形式概覽:unsafe_expr??或(unsafe_expr)?? 這個操作符告訴我們一個值是否存在。基於這種情況,結果是 true 或 false。
樣本如下,假設並沒有名為 mouse 的變數:
<#if mouse??> Mouse found <#else> No mouse found </#if> Creating mouse... <#assign mouse = "Jerry"> <#if mouse??> Mouse found <#else> No mouse found </#if>
No mouse found Creating mouse... Mouse found
14 括弧
括弧可以用來給運算式分組。樣本如下:
<#-- 輸出是: --> ${3 * 2 + 2} <#-- 8 --> ${3 * (2 + 2)} <#-- 12 --> ${3 * ((2 + 2) * (1 / 2))} <#-- 6 --> ${"green " + "mouse"?upper_case} <#-- green MOUSE --> ${("green " + "mouse")?upper_case} <#-- GREEN MOUSE --> <#if !( color = "red" || color = "green")> The color is nor red nor green </#if>
15 運算式中的空格
FTL 忽略運算式中的多餘空格
16 操作符的優先順序
插值
插值的使用文法是:${expression},expression 可以是所有種類的運算式(比如${100 + x})。
插值是用來給插入具體值然後轉換為文本(字串)。插值僅僅可以在兩種位置使用:
文本區(如<h1>Hello ${name}!</h1> )和字串運算式(如<#include "/footer/${company}.html">)中。
如果插值在文本區(也就是說,不再字串運算式中),如果 escapse 指令起作用了,即將被插入的字串會被自動轉義。
<#escape x as x?html> ... <p>Title: ${book.title}</p> <p>Description: <#noescape>${book.description}</#noescape></p> <h2>Comments:</h2> <#list comments as comment> <div class="comment"> ${comment} </div> </#list> ... </#escape>
freemarker的模板ftl檔案是不是直接將html檔案更改尾碼為ftl就行了?
肯定支援的。
只跟你web server上配置的freemarker有關,跟瀏覽器沒有關係。
另外,站長團上有產品團購,便宜有保證
怎當freemarker模板出現錯誤時屏蔽錯誤並跳轉
在日常的開發過程中,對錯誤資訊的合理處理都是很重要的一個環節,特別對於門戶系統,其重要性就不言而喻瞭然而我們在實際的開發過程中,要想錯誤提示明確、又要想客戶不至於太反感,看似矛盾的大多數系統都是採用一檢測到錯誤,統一跳轉到統一的錯誤頁面,然後統一去做處理,但是 那 種 錯 誤 檢 測 僅 僅 是 處 理 大 部 分 的 錯 誤 , 如 java.sql.SQLException 、java.lang.RuntimeException,但是對於使用freemarker 範本語言的系統來說,其支援不是很好(我嘗試把freemarker.template.TemplateException 等異常加入到其檢測機制中,發現沒有作用,只好改用其實現方法)。通過查詢freemarker、spring 的api 獲知,freemarker提供了一個支援其錯誤處理機制的介面 TemplateExceptionHandler,需要自己去擴充實現,構造自己的處理freemarker 模板錯誤的機制主要分為兩個部分 1、構造自己的錯誤處理機制2 、在 spring啟動的時候將自訂的錯誤機制加入到freemarker 配置中具體做法如下:1、建立一個類,讓其實現TemplateExceptionHandler 介面public class LenovoFreemarkerExceptionHandler implementsTemplateExceptionHandler{public void handleTemplateException(TemplateException arg0,Environment arg1, Writer out) throws TemplateException {//這裡構建你的錯誤機制,可以進行跳轉及錯誤記錄檔的列印等等}}