變量定義html
<#assign name1="北京" name2="上海" name3="廣東"> 輸出結果:${name1}、${name2}、${name3} <#assign str="你好"> 輸出結果:${str} 輸出結果:北京、上海、廣東 輸出結果:你好
<#assign num = 100 /> 適用類型:定義變量,支持計算和賦值java
<#assign num = 101 /><br/> ${num * 10}<br/> ${num / 10}<br/> ${num + 10}<br/> ${num - 10}<br/> 輸出結果: 1,010 10.1 111 91
listnode
<#list strList as item>
${item}
</#list>
map程序員
<select id="selOrderStatus" name="orderStatus" class="form-control" > <option value="-1">所有</option> <#assign selected=''/> <#if orderStatusMap?exists> <#list orderStatusMap?keys as key> <#if (key == status?string)> <#assign selected='selected="selected"'/> <#else> <#assign selected=''/> </#if> <option ${selected} value="${key}">${orderStatusMap[key]}</option> </#list> </#if> </select>
switch正則表達式
<#switch "星期三"> <#case "星期一"> 油燜大蝦 <#break> <#case "星期二"> 炸醬麪 <#break> <#default> 肯德基 </#switch>
輸出結果:肯德基
${var!} 對 null 或者不存在的對象進行取值,能夠設置默認值,例:${var!'我是默認值'} 即,有值時顯示正常值,無值時顯示默認值數據庫
${封裝對象.屬性}對封裝對象進行取值,例:${User.name} 若是爲空,也能夠這麼寫:${order.orderId!"6666"};${order.getOrderCode()}json
${var?html} 轉義HTML內容 ${order.getOrderCode()?html}api
string轉數字瀏覽器
<#assign num="200.99"/> ${num?eval} <#if (num?eval >100)> 55557 </#if> 轉換結果:200.99
數字轉string安全
<#assign num=200.99/> ${num?string} <#if (num?string = "200.99")> true </#if>
字符串函數:
<#list "aa,bb,cc,dd"?split(",") as str> ${str} </#list> 輸出結果:aa bb cc dd <br/> ${"hello world"?index_of("o")} 輸出結果:4 <br/> ${"hello world"?last_index_of("l")} 輸出結果:9 <br/> -${" gg "?trim}- 刪除字符串首尾空格 輸出結果:-gg- <br/> ${"GROUP VALUE"?lower_case} 小寫 輸出結果:group value <br/> ${"group value"?upper_case} 大寫 輸出結果:GROUP VALUE <br/> ${"group value"?cap_first} 第一個單詞的首字母大寫 輸出結果:Group value <br/> ${"GROUP VALUE"?uncap_first} 第一個單詞的首字母小寫 輸出結果:gROUP VALUE <br/> ${"group value"?capitalize} 全部單詞的首字母大寫 輸出結果:Group Value <br/> ${"group value"?contains("val")?string} 判斷字符中是否包含某個子串。返回布爾值 輸出結果:true <br/> ${"group value"?starts_with("gro")?string} 判斷某個字符串是否由某個子串開頭,返回布爾值 輸出結果:true <br/> ${"group value"?ends_with("lue")?string} 判斷某個字符串是否由某個子串結尾,返回布爾值 輸出結果:true <br/> ${"group value"?length} 判斷字符中是否包含某個子串。返回布爾值 輸出結果:11 <br/> ${"strabttuabg"?replace("ab","--")} 所有替換 輸出結果: str--ttu--g <br/> ${"<font color = 'red'>我只是個菜單</font>"} ${order.getOrderCode()?html} 輸出結果: <br/> ${"group"?substring(0)} ${"group"?substring(1)} ${"group"?substring(2)} ${"group"?substring(3)} 輸出結果:group roup oup up <br/> ${"group"?substring(0,1)} ${"group"?substring(1,3)} ${"group"?substring(2,5)} 輸出結果: g ro oup
${"abcde"?left_pad(10,"--")} 若是不足10個字符,以--在左邊填充
輸出結果:-----abcde
${"abcde"?right_pad(10,"--")} 若是不足10個字符,以--在右邊填充
輸出結果:abcde-----
數字格式化:
<br/> <br/> <br/> <#assign num=898> ${num?string(",##0.00")} 輸出結果:898.00 <br/> <#assign num=0.1> ${num?string(",##0.00")} 輸出結果:0.10 <br/> <#assign num=1234136.123> ${num?string(",##0.00")} 輸出結果:1,234,136.12 <br/> <#assign num=1234136.775> ${num?string(",##0.00")} 輸出結果:1,234,136.78 <br/> <#assign num=1234136.777> ${num?string(",##0.00")} 輸出結果:1,234,136.78 <br/>------------------------------- <br/> <br/> <#assign num=898> ${num?string("0.00")} 輸出結果:898.00 <br/> <#assign num=0.1> ${num?string("0.00")} 輸出結果:0.10 <br/> <#assign num=1234136.123> ${num?string("0.00")} 輸出結果:1234136.12 <br/> <#assign num=1234136.775> ${num?string("0.00")} 輸出結果:1234136.78 <br/> <#assign num=1234136.777> ${num?string("0.00")} 輸出結果:1234136.78 <br/>------------------------------- <br/> <br/> <#assign num=898> ${num?string("#.##")} 輸出結果:898 <br/> <#assign num=0.1> ${num?string("#.##")} 輸出結果:0.1 <br/> <#assign num=1234136.123> ${num?string("#.##")} 輸出結果:1234136.12 <br/> <#assign num=1234136.775> ${num?string("#.##")} 輸出結果:1234136.78 <br/> <#assign num=1234136.777> ${num?string("#.##")} 輸出結果:1234136.78 <br/>------------------------------- <br/> <br/> ${1.2?string("0")} 輸出結果:1 <br/> ${1.8?string("0")} 輸出結果:2 <br/> ${1.5?string("0")} 輸出結果:2 <br/> ${2.5?string("0")} 輸出結果:2 <br/> ${1?string("000.00")} 輸出結果:001.00 <br/> ${12.1?string("000.00")} 輸出結果:012.10 <br/> ${123.456?string("000.00")} 輸出結果:123.456 <br/>------------------------------- <br/> <br/> 捨去小數點後面的 ${1.8?int} ${1.5?int} ${1.4?int} 輸出結果:1 1 1 <br/>------------------------------- <br/> <br/> <#assign num=1234136.777> ${num?string.number} 輸出結果:1,234,136.777 <br/> ${num?string.currency} 輸出結果:¥1,234,136.78 <br/> ${num?string.percent} 輸出結果:123,413,678% <br/> <br/> <#setting number_format="currency"> <#assign x=5642.785> ${x} ${x?string} ${x?string.number} ${x?string.currency} ${x?string.percent} 輸出結果:¥5,642.78 ¥5,642.78 5,642.785 ¥5,642.78 564,278% <br/>------------------------------- <br/> <br/> <#assign numList = [12,0.236,89,12.032,69.56,45.67,-0.561,-8.057,-89.56,4.69]/> <#list numList as num> ${num} ?round=${num?round} ?floor=${num?floor} ?ceiling=${num?ceiling}<br/> </#list> 輸出結果: 12 ?round=12 ?floor=12 ?ceiling=12 0.236 ?round=0 ?floor=0 ?ceiling=1 89 ?round=89 ?floor=89 ?ceiling=89 12.032 ?round=12 ?floor=12 ?ceiling=13 69.56 ?round=70 ?floor=69 ?ceiling=70 45.67 ?round=46 ?floor=45 ?ceiling=46 -0.561 ?round=-1 ?floor=-1 ?ceiling=0 -8.057 ?round=-8 ?floor=-9 ?ceiling=-8 -89.56 ?round=-90 ?floor=-90 ?ceiling=-89 4.69 ?round=5 ?floor=4 ?ceiling=5
日期格式化
LocalDateTime 格式化 ${strDate?date}<br/> ${strDate?date("yyyy-MM-dd")}<br/> 輸出結果: 2018-7-10 2018-7-10 <br/> LocalDateTime 格式化 ${(strDate?string)?replace("T"," ")?datetime("yyyy-MM-dd HH:mm:ss")}<br/> ${(strDate?string)?replace("T"," ")?date("yyyy-MM-dd")}<br/> ${(strDate?string)?replace("T"," ")?time("yyyy-MM-dd HH:mm:ss")}<br/> 輸出結果: 2018-7-10 14:22:17 2018-7-10 14:22:17 <br/> <br/> 字符串格式化 ${"2012-06-17 01:08:18"?datetime("yyyy-MM-dd HH:mm:ss")}<br/> ${"2012-06-17 01:08:18"?date("yyyy-MM-dd")}<br/> ${"2012-06-17 01:08:18"?time("yyyy-MM-dd HH:mm:ss")}<br/> 輸出結果: 2012-6-17 1:08:18 2012-6-17 1:08:18
long newDateLong=new Date().getTime();
<br/>
${newDateLong?number_to_datetime}
輸出結果:2018-7-10 14:46:53
<br>
${newDateLong?number_to_date}
輸出結果:2018-7-10
<br>
<br/>-------------------------------
<br/>
LocalDateTime localDateTime = LocalDateTime.now();
Objects.requireNonNull(localDateTime, "arg dt");
long localDateTimeLong = localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
<br/>
${localDateTimeLong?number_to_datetime}
輸出結果:2018-7-10 14:46:53
<br>
${localDateTimeLong?number_to_date}
輸出結果:2018-7-10
<br/>
<br/>-------------------------------
<br/>
Objects.requireNonNull(localDate, "arg dt");
long localDateLong = localDate.atStartOfDay(ZoneId.systemDefault()).toInstant().toEpochMilli();
<br/>
${localDateLong?number_to_datetime}
輸出結果:2018-7-10 0:00:00
<br>
${localDateLong?number_to_date}
輸出結果:2018-7-10
布爾值
<#assign foo=true> ${foo?string} ${foo?string("yes","no")} 輸出結果: true yes
substring
${"group"?substring(0)} ${"group"?substring(1)} ${"group"?substring(2)} ${"group"?substring(3)} 輸出結果: group roup oup up ${"group"?substring(0,1)} ${"group"?substring(1,3)} ${"group"?substring(2,5)} 輸出結果: g ro oup
lower_case將字符串轉爲小寫
${"STRING"?lower_case}
輸出結果:string
upper_case將字符串轉爲大寫
${"string"?upper_case}
輸出結果: STRING
cap_first 將字符串中的第一個單詞的首字母變爲大寫。
${"group"?cap_first}
輸出結果:Group
uncap_first將字符串中的第一個單詞的首字母變爲小寫。
${"GROUP"?uncap_first}
輸出結果:gROUP
capitalize 將字符串中的全部單詞的首字母變爲大寫
${"group value"?capitalize}
輸出結果:
Group Value
contains 判斷字符中是否包含某個子串。返回布爾值
${"string"?contains("ing")?string} 輸出結果:true
ends_with 判斷某個字符串是否由某個子串結尾,返回布爾值。
${"string"?ends_with("ing")?string} 輸出結果:true
index_of(substring,start)在字符串中查找某個子串,返回找到子串的第一個字符的索引,若是沒有找到子串,則返回-1。
Start參數用於指定從字符串的那個索引處開始搜索,start爲數字值。
若是start大於字符串長度,則start取值等於字符串長度,若是start小於0, 則start取值爲0。
${"string"?index_of("in")} ${"string"?index_of("ab")} 輸出結果: 3 -1
length返回字符串的長度
${"string"?length}
輸出結果:6
number將字符串轉換爲數字
${"111.11"?number}
輸出結果:111.11
replace 所有替換
${"strabttuabg"?replace("ab","--")}
輸出結果: str--ttu--g
split使用指定的分隔符將一個字符串拆分爲一組字符串
<#list "aa,bb,cc,dd"?split(",") as str> ${str}<br/> </#list> 輸出結果: aa bb cc dd
轉載:
Freemarker內建函數 1.1 處理字符串的內建函數 1.1.1 substring 取子串 注意: 這個內建函數從 FreeMarker 2.3.7 開始可用。 概要 :exp?substring(from, toExclusive) ,也 可 以 做 爲 exp?substring(from) 調用 一個字符串的子串。 from 是第一個字符開始的索引。它必須是一個數字並且至少是0, 並且要小於或等於 toExclusive ,不然錯誤就會中斷模板的處理。 toExclusive 是 子串中最後一個字符以後的位置索引,換句話說,它比最後一個字符的索引大 1。它必須是 數字,至少是 0,要小於或等於字符串的長度,不然錯誤就會停止模板的處理。若是 toExclusive 被忽略了,那麼它默認就是字符串的長度。若是參數不是整型的數字,那 麼數值中只有整型的部分會被使用。 例如: 輸出爲: - ${'abc'?substring(0)} - ${'abc'?substring(1)} - ${'abc'?substring(2)} - ${'abc'?substring(3)} - ${'abc'?substring(0, 0)} - ${'abc'?substring(0, 1)} - ${'abc'?substring(0, 2)} - ${'abc'?substring(0, 3)} - ${'abc'?substring(0, 1)} - ${'abc'?substring(1, 2)} - ${'abc'?substring(2, 3)} 輸出爲: - abc - bc - c - - - a - ab - abc - a - b - c 1.1.2 cap_first 首字母大寫 字符串中的第一個單詞的首字母大寫。更精確的「單詞」的意思能夠查看內建函數 word_list。 好比: ${" green mouse"?cap_first} ${"GreEN mouse"?cap_first} ${"- green mouse"?cap_first} 輸出爲: 在 "- green mouse" 的情形下,第一個單詞是 - 。 1.1.3 uncap_first 首字母小寫 這和 cap_first 是相反的。字符串第一個單詞的首字母小寫。 1.1.4 capitalize 首字母 大寫 字符串的全部單詞都大寫。更精確的「單詞」的意思能夠查看內建函數 word_list。好比: 輸出爲: ${" green mouse"?cap_first} ${"GreEN mouse"?cap_first} 輸出爲: Green mouse GreEN mouse 1.1.5 chop_linebreak 切斷換行符 若是在末尾沒有換行符的字符串,那麼能夠換行,不然不改變字符串。 1.1.6 date ,time ,datetime 日期,時間,時間日期 字符串轉換成日期值。建議指定一個肯定格式個參數。好比: <#assign test1 ="10/25/1995"?date("MM/dd/yyyy")> <#assign test2 ="15:05:30"?time("HH:mm:ss")> <#assign test3 = "1995-10-25 03:05PM"?datetime("yyyy-MM-dd hh:mm a")> ${test1} ${test2} ${test3} 將會打印出(基於當地(語言)和其餘設置決定輸出)以下內容: Oct 25, 1995 3:05:30 PM Oct 25, 1995 3:05:00 PM 要注意日期根據 date_format , time_format 和 datetime_format 的設 置轉換回字符串(對於日期轉換成字符的更多內容請閱讀:日期內建函數,日期插值)。這 和你在轉換字符串到日期類型時使用什麼格式沒有關係。 若是你瞭解模板處理時默認的日期/時間/時間日期格式,你能夠不用格式化參數: <#assign test1 = "Oct 25,1995"?date> <#assign test2 = "3:05:30PM"?time> <#assign test3 = "Oct 25, 199503:05:00 PM"?datetime> ${test1} ${test2} ${test3} 若是字符串不在適當的格式,當你嘗試使用這些內建函數時,錯誤將會中斷模板執行。 1.1.7 ends_with 以… 結尾 返回是否這個字符串以指定的子串結尾。好比 "redhead"?ends_with("head") 返回布爾值 true。並且 "head"?ends_with("head") 也返回 true。 1.1.8 html HTML 格式的轉義文本 字符串按照 HTML 標記輸出。也就是說,下面字符串將會被替代: < 用 < 替換; > 用 > 替換; & 用 & 替換; " 用 " 替換; 注意若是你想安全地插入一個屬性,你必須在 HTML 模板中使用引號標記(是 " ,而不 是 ' )爲屬性值加引號: <input type=text name=uservalue="${user?html}"> 注意在 HTML 頁面中,一般你想對全部插值使用這個內建函數。因此你可使用 escape 指令來節約不少輸入,減小偶然錯誤的機會。 1.1.9 group 分組 這個函數只和內建函數 matches 的結果使用。請參考 matches 函數。 1.1.10 index_of 索引所在位置 返回第一次字符串中出現子串時的索引位置。例如 "abcabc"?index_of("bc") 將會返回 1(不要忘了第一個字符的索引是 0)。並且,你能夠指定開始搜索的索引位置:將 "abcabc"?index_of("bc",2) 會返回 4。這對第二個參數的數值沒有限制:若是 它是負數,那就和是 0 是 ige 效果了,若是它比字符串的長度還大,那麼就和它是字符串長 度那個數值是一個效果。小數會被切成整數。 若是第一個參數做爲子串沒有在該字符串中出現時(若是你使用了第二個參數,那麼就 從給定的序列開始。),那麼就返回-1. 1.1.11 j_string Java 語言規則的字符串轉義 根據 Java 語言字符串轉義規則來轉義字符串,因此它很安全的將值插入到字符串類型 中。要注意它不會 在被插入的值的兩側添加引號;你須要在這裏使用字符串值。 全部 UCS 編碼下指向 0x20 的字符會被轉義。當它們在 Java 語言中(好比 \n , \t 等) 沒有專門的轉義序列時,將會被用 UNICODE 進行轉義替換( \uXXXX )。 例如: <#assign beanName = 'The "foo"bean.'> String BEAN_NAME ="${beanName?j_string}"; 將會打印: String BEAN_NAME = "The\"foo\" bean."; 1.1.12 js_string JavaScript 語言規則的字符串轉義 根據 JavaScript 語言字符串轉義規則來轉義字符串,因此它很安全的將值插入到字符串 類型中。要注意,它不會 在被插入的值兩側添加引號;而是在字符串中間使用。 引號( " )和單引號( ' )要被轉義。從 FreeMarker 2.3.1 開始,也要將 > 轉義爲 \> (爲 了避免 </script> )。 全部在 UCS 編碼下指向 0x20 的字符將會被轉義。當它們在 JavaScript 中沒有專用的轉 義序列時(好比 \n , \t 等),它們會被 UNICODE 字符代替( \uXXXX )。 例如: <#assign user = "Big Joe's\"right hand\""> <script> alert("Welcome${user?js_string}!"); </script> 將會打印: <script> alert("Welcome Big Joe\'s \"righthand\"!"); </script> 1.1.13 json_string JSON 規則的字符串轉義 根據 JSON 語言的字符串規則來轉義字符串,因此在字符串中插入值是安全的。要注意 它不會 在被插入的值兩側添加引號;而是在字符串中間使用。 這不會轉義 ' 字符,由於 JSON 字符串必須使用 " 來括起來。它會在 < 以後直接出現的 / (斜槓)字符轉義爲 \/ ,來避免 </script> 等。它也會在]]以後轉義 > 字符爲 \u003E , 來避免退出 XML 的 CDATA 段。 全部在 UCS 編碼下指向0x20 的字符會被轉義。當在 JSON 中沒有專用的轉義序列時(比 如 \n , \t 等),它們會被 UNICODE 字符代替( \uXXXX )。 1.1.14 last_index_of 最後的索引所在位置 返回最後一次(最右邊)字符串中出現子串時的索引位置。它返回子串第一個(最左邊) 字符所在位置的索引。例如 "abcabc"?last_index_of("ab") :將會返回 3。並且 你能夠指定開始搜索的索引。例如: "abcabc"?last_index_of("ab", 2) ,將 會返回 0。要注意第二個參數暗示了子串開始的最大索引。對第二個參數的數值沒有限制: 若是它是負數,那麼效果和是零的同樣,若是它比字符串的長度還大,那麼就和它是字符串 長度那個數值是一個效果。小數會被切成整數。 若是第一個參數做爲子串沒有在該字符串中出現時(若是你使用了第二個參數,那麼就 從給定的序列開始。),那麼就返回-1. <#assign user = "Big Joe's\"right hand\""> <script> alert("Welcome${user?js_string}!"); </script> <script> alert("Welcome Big Joe\'s \"righthand\"!"); </script> 1.1.15 length 字符串長度 字符串中字符的數量 1.1.16 lower_case 小寫形式 字符 串的 小 寫形 式 。比 如 "GrEeNMoUsE?lower_case" 將會是 "green mouse" 。 1.1.17 left_pad 距左邊 注意: 這個內建函數從 FreeMarker 2.3.1 版本開始可用。在 2.3 版本中是沒有的。 若是它僅僅用 1 個參數,那麼它將在字符串的開始插入空白,直到整個串的長度達到參 數指定的值。若是字符串的長度達到指定數值或者比指定的長度還長,那麼就什麼都不作了。 好比這樣: 將會打印: 若是使用了兩個參數,那麼第一個參數表示的含義和你使用一個參數時的相同,第二個 參數指定用什麼東西來代替空白字符。好比: [${""?left_pad(5)}] [${"a"?left_pad(5)}] [${"ab"?left_pad(5)}] [${"abc"?left_pad(5)}] [${"abcd"?left_pad(5)}] [${"abcde"?left_pad(5)}] [${"abcdef"?left_pad(5)}] [${"abcdefg"?left_pad(5)}] [${"abcdefgh"?left_pad(5)}] [ ] [ a] [ ab] [ abc] [ abcd] [abcde] [abcdef] [abcdefg] [abcdefgh] 將會打印: 第二個參數也能夠是個長度比 1 大的字符串。那麼這個字符串會週期性的插入,好比: 將會打印: 第二個參數必須是個字符串值,並且至少有一個字符。 1.1.18 right_pad 距右邊 注意: 這個內建函數從 FreeMarker 2.3.1 版本開始可用。在 2.3 版本中是沒有的。 這個和 left_pad 相同,可是它從末尾開始插入字符而不是從開頭。 好比: [${""?left_pad(5,"-")}] [${"a"?left_pad(5,"-")}] [${"ab"?left_pad(5,"-")}] [${"abc"?left_pad(5,"-")}] [${"abcd"?left_pad(5,"-")}] [${"abcde"?left_pad(5,"-")}] 將會打印: [-----] [----a] [---ab] [--abc] [-abcd] [abcde] 第二個參數也能夠是個長度比 1 大的字符串。那麼這個字符串會週期性的插入,好比: [${""?left_pad(8,".oO")}] [${"a"?left_pad(8,".oO")}] [${"ab"?left_pad(8,".oO")}] [${"abc"?left_pad(8,".oO")}] [${"abcd"?left_pad(8,".oO")}] 將會打印: [.oO.oO.o] [.oO.oO.a] [.oO.oOab] [.oO.oabc] [.oO.abcd] 第二個參數必須是個字符串值,並且至少有一個字符。 1.1.19 contains 包含 注意: 這個內建函數從 FreeMarker 2.3.1 版本開始可用。在 2.3 版本中是沒有的。 若是函數中的參數能夠做爲源字符串的子串,那麼返回 true。 好比: <#if"piceous"?contains("ice")>It contains"ice"</#if> 將會輸出: It contains "ice" 1.1.20 matches 匹配 這是一個「超級用戶」函數。無論你是否懂正則表達式。 注意: 這個函數僅僅對使用 Java2 平臺的 1.4 版本以後起做用。不然它會發生錯誤並停止模板 的處理。 這個函數決定了字符串是否精確匹配上模式。並且,它返回匹配的子串列表。返回值是 一個多類型的值: 布爾值:若是字符串精確匹配上模式返回true ,不然返回 false 。例如, "fooo"?matches('fo*') 是 true , 但 是 "fooo bar"?matches('fo*') 是 false 。 序列:字符串匹配子串的列表。多是一個長度爲 0 的序列。 好比: <#if"fxo"?matches("f.?o")>Matches.<#else>Does not match.</#if> <#assign res = "foo barfyo"?matches("f.?o")> <#if res>Matches.<#else>Doesnot match.</#if> Matching sub-strings: <#list res as m> - ${m} </#list> 將會打印: 若是正則表達式包含分組(括號),那麼你可使用內建函數 groups 來訪問它們: 這會打印: matches 接受兩個可選的標記參數,要注意它不支持標記fr ,並且也會忽略標記 r 。 <#if"fxo"?matches("f.?o")>Matches.<#else>Does not match.</#if> <#assign res = "foo bar fyo"?matches("f.?o")> <#if res>Matches.<#else>Doesnot match.</#if> Matching sub-strings: <#list res as m> - ${m} </#list> Matches. Does not match. Matching sub-strings: - foo - fyo <#assign res = "aa/rx;ab/r;"?matches("(\\w[^/]+)/([^;]+);")> <#list res as m> - ${m} is ${m?groups[1]} per ${m?groups[2]} </#list> - aa/rx; is aa per rx - ab/r; is ab per r matches 接受兩個可選的標記參數,要注意它不支持標記fr ,並且也會忽略標記 r 。 1.1.21 number 數字格式 字符串轉化爲數字格式。這個數字必須是你在 FTL 中直接指定數值的格式。也就是說, 它必須以本地獨立的形式出現,小數的分隔符就是一個點。此外這個函數認識科學記數法。 (好比 "1.23E6" , "1.5e-8" )。 若是這惡搞字符串不在恰當的格式,那麼在你嘗試訪問這個函數時,錯誤會拋出並停止 模板的處理。 已知的問題:若是你使用比 Java2 平臺 1.3 版本還早的版本,這個函數將不會被識別, 前綴和科學記數法都不會起做用。 1.1.22 replace 替換 在源字符串中,用另一個字符穿來替換原字符串中出現它的部分。它不處理詞的邊界。 好比: ${"this is a caracarus"?replace("car", "bulldozer")} 將會打印: this is a bulldozer abulldozerus 替換是從左向右執行的。這就意味着: ${"aaaaa"?replace("aaa","X")} 將會打印: Xaa 若是 第 一 個 參 數 是 空 字 符 串 , 那 麼 所 有 的 空 字 符 串 將 會 被 替 換 , 比 如 "foo"?replace("","|"),就會獲得 "|f|o|o|" 。 replace 接受一個可選的標記參數,做爲第三個參數。 1.1.23 rtf 富文本 字符串做爲富文本(RTF 文本),也就是說,下列字符串: \ 替換爲 \\ { 替換爲 \{ } 替換爲 \} 1.1.24 url URL 轉義 注意: 這個內建函數從 FreeMarker 2.3.1 版本開始可用。在 2.3 版本中是沒有的。 在 URL 以後的字符串進行轉義。這意味着,全部非 US-ASCII 的字符和保留的 URL 字符 將會被 %XX 形式來轉義。例如: <#assign x = 'a/b c'> ${x?url} 輸出將是(假設用來轉義的字符集是 US-ASCII 兼容的字符集): a%2Fb%20c 注意它會轉義全部保留的 URL 字符( / , = , & 等),因此編碼能夠被用來對查詢參數的 值進行,好比: <ahref="foo.cgi?x=${x?url}&y=${y?url}">Click here...</a> 注意: 上面的沒有 HTML 編碼( ?htm )是必要的,由於 URL 轉義全部保留的 HTML 編碼。但 是要當心:一般引用的屬性值,用普通引號( " )包括,而不是單引號( ' ),由於單引號是 不被 URL 轉義的。 爲了進行 URL 轉義,必需要選擇字符集,它被用來計算被轉義的部分( %XX )。若是你 是 HTML 頁面設計者,並且你不懂這個,不要擔憂:程序員應該配置 FreeMarker,則它默認 使用恰當的字符集(程序員應該多看看下面的內容)。若是你是一個比較熱衷於技術的人, 那麼你也許想知道被 url_escaping_charset 設置的指定字符集,它能夠在模板的 執行時間設置(或者,更好的是,由程序員以前設置好)。例如: <#-- This will use the charset specified by theprogrammers before the template execution has started. --> <ahref="foo.cgi?x=${x?url}">foo</a> <#-- Use UTF-8 charset for URL escapingfrom now: --> <#settingurl_escaping_charset="UTF-8"> <#-- This will surely use UTF-8 charset--> <ahref="bar.cgi?x=${x?url}">bar</a> 此外,你能夠明確地指定一個爲單獨 URL 轉義的字符集,做爲內建函數的參數: <ahref="foo.cgi?x=${x?url('ISO-8895-2')}">foo</a> 若是內建函數 url 沒有參數,那麼它會使用由 url_escaping_charset 設置的 字符集。這個設置應該被軟件設置,包括 FreeMarker (好比一個 Web 應用框架),由於它不 會被 默 認 設 置 爲 null 。 如 果 它 沒 有 被 設 置 , 那 麼 FreeMarker 退 回 使 用 output_encoding 的設置,這個也會被默認設置,因此它也是又軟件設置的。若是 output_encoding 也沒有被設置,那麼沒有參數的內建函數 url 將不會被執行,二 期它會引發運行時錯誤。固然,有參數的 url 函數將會執行。 用 setting 指令在模板中設置 url_escaping_charset 是可能的。至少在真 實的 MVC 應用中,這是一個很差的實踐行爲。 output_encoding 不能由 setting 指令來設置,因此它應該是軟件的工做。你能夠閱讀程序開發指南 / 其它 / 字符集問題來獲取更多信息。 1.1.25 split 分割 它被用來根據另一個字符串的出現將原字符串分割成字符串序列。好比: <#list"someMOOtestMOOtext"?split("MOO") as x> - ${x} </#list> 將會打印: - some - test - text 既然已經假設全部分隔符的出現是在新項以前,所以: <#list"some,,test,text,"?split(",") as x> - "${x}" </#list> 將會打印: - "some" - "" - "test" - "text" - "" split 函數接受一個可選的標記參數做爲第二個參數。 1.1.26 starts_with 以… 開頭 若是 字 符 串 以 指 定 的 子 字 符 串 開 頭 , 那 麼 返 回 true 。 比 如 "redhead"?starts_with("red")返 回 布 爾 值 true , 而 且 "red"?starts_with("red")也返回 true。 1.1.27 string (當被用做是字符串值時) 什麼也不作,僅僅返回和其內容一致的字符串。例外的是,若是值是一個多類型的值(比 如同時有字符串和序列兩種),那麼結果就只是一個簡單的字符串,而不是多類型的值。這 能夠被用來防止多種人爲輸入。 1.1.28 trim 修整字符串 去掉字符串首尾的空格。例如: 輸出是: 1.1.29 upper_case 大寫形式 字符串的大寫形式。好比 "GrEeN MoUsE" 將會是 "GREENMOUSE" 。 1.1.30 word_list 詞列表 包含字符串詞的列表,並按它們在字符串中的順序出現。詞是連續的字符序列,包含任 意字符,可是不包括空格。好比: <#assign words = " a bcd, .1-2-3"?word_list> <#list words asword>[${word}]</#list> 將會輸出: [a][bcd,][.][1-2-3] 1.1.31 xhtml XHTML 格式 字符串做爲 XHTML 格式文本輸出,下面這些: < 替換爲 < > 替換爲 > & 替換爲 & " 替換爲 " ' 替換爲 ' 這個函數和 xml 函數的惟一不一樣是 xhtml 函數轉義 ' 爲 ' ,而不是 ' , 可是一些老版本的瀏覽器不正確解釋 ' 。 1.1.32 xml XML 格式 字符串做爲 XML 格式文本輸出,下面這些: < 替換爲 < > 替換爲 > (${" green mouse "?trim}) (green mouse) <#assign words = " a bcd, .1-2-3"?word_list> <#list words asword>[${word}]</#list> [a][bcd,][.][1-2-3] & 替換爲 & " 替換爲 " ' 替換爲 ' 1.1.33 通用標記 不少字符串函數接受一個可選的被稱爲「標記」的字符串參數。在這些字符串中,每一 個字符都影響着內建函數行爲的一個特定方面。好比,字母 i 表示內建函數不該該在同一 個字母的大小寫上有差別。標記中字母的順序並不重要。 下面是標記字母的完整列表: i :大小寫不敏感:不區分同一個字母大小寫之間的差別。 f :僅僅是第一。也就是說,替換/查找等,只是第一次出現的東西。 r :查 找的 子串 是正 則表 達式 。FreeMarker 使用 變化 的正 則表 達式 ,在 http://java.sun.com/j2se/1.4.1/docs/api/java/util/regex/Pattern.html中描述。 只有 你使用 Java2 平臺的 1.4 版本之後,標記纔會起做用。不然它會發生錯誤致使模板 處理中止。 m :正則表達式多行模式。在多行模式下,表達式^ 和 $ 僅僅匹配先後,分別是一 行結尾或者是字符串的結束。默認這些表達式僅僅匹配整個字符串的開頭和結尾。 注意 ^ 和 $ 不會匹配換行符自己。 s :啓用正則表達式的 do-tall 模式(和 Perl 的單行模式同樣)。在do-tall 模式下, 表達式 . 匹配任意字符串,包括行結束符。默認這個表達式不匹配行結束符。 c :在正則表達式中許可空白和註釋。 示例: <#assign s = 'foo bAr baar'> ${s?replace('ba', 'XY')} i: ${s?replace('ba', 'XY', 'i')} if: ${s?replace('ba', 'XY', 'if')} r: ${s?replace('ba*', 'XY', 'r')} ri: ${s?replace('ba*', 'XY', 'ri')} rif: ${s?replace('ba*', 'XY', 'rif')} 這會輸出: foo bAr XYar i: foo XYr XYar if: foo XYr baar r: foo XYAr XYr ri: foo XYr XYr rif: foo XYr baar 這是內建函數使用通用標記的表格,哪些支持什麼樣的標記。 內建函數 i (忽略大小寫) r (正則表達式) m (多行模式) s(dot-all模式) c (whitesp和註釋) f (僅第一個) replace 是 是 只和 r 只和 r 只和 r 是 split 是 是 只和 r 只和 r 只和 r 否 match 是 忽略 是 是 是 否 1.2 處理數字的內建函數 相關的 FAQs:若是你有和 1,000,000 或 1 000 000 而不是 1000000 相似的東西,或者是 3.14 而不是 3,14 的東西,反之亦然,請參考FAQ 中相關內容,也要注意內建函數 c 的全部 內容。 1.2.1 c 數字轉字符 注意: 這個內建函數從 FreeMarker 2.3.3 之後開始存在。 這個函數將數字轉換成字符串,這都是對計算機來講的,而不是對用戶。也就是說,它 根據程序語言的用法來進行格式化,這對於 FreeMarker 的全部本地數字格式化設置來講是 獨立的。它一般使用點來做爲小數分隔符,並且它歷來不用分組分隔符(像 3,000,000),指 數形式(好比 5E20),多餘的在開頭或結尾的 0(好比 03 或 1.0),還有+號(好比+1)。它最 多在小數點後打印 16 位,所以數值的絕對值小於 1E-16 將會顯示爲 0。這個函數很是嚴格, 由於做爲默認(像 ${x} 這樣)數字被本地(語言,國家)特定的數字格式轉換爲字符串, 這是讓用戶來看的(好比 3000000 可能會被打印爲 3,000,000)。當數字不對用戶打印時(比 如,對於一個數據庫記錄 ID,用做是 URL 的一部分,或者是 HTML 表單中的隱藏域,或者 打印 CSS/JavaScript 的數值文本),這個函數必須被用來打印數字(也就是使用 ${x?c} 來代 替 ${x} ),不然輸出可能因爲當前數字格式設置,本地化(好比在一些國家中,小數點不 是點,而是逗號)和數值(像大數可能被分組分隔符「損壞」)而損壞。 1.2.2 string (當用做是數值類型時) 數字轉字符串 將一個數字轉換成字符串。它使用程序員已經指定的默認格式。你也能夠明確地用這個 函數再指定一個數字格式,這在後面會展現。 有四種預約義的數字格式: computer , currency , number 和 percent 。這 些格式的明確含義是本地化(國家)指定的,受Java 平臺安裝環境所控制,而不是 FreeMarker, 除了 computer ,用做和函數 c 是相同的格式。你能夠這樣來使用預約義的格式: <#assign x=42> ${x} ${x?string} <#-- the same as ${x} --> ${x?string.number} ${x?string.currency} ${x?string.percent} ${x?string.computer} 若是你本地是 US English,那麼就會生成: 42 42 42 $42.00 4,200% 42 前三個表達式的輸出是相同的,由於前兩個表達式是默認格式,這裏是數字。你可使 用一個設置來改變默認設置: <#settingnumber_format="currency"> <#assign x=42> ${x} ${x?string} <#-- the same as ${x} --> ${x?string.number} ${x?string.currency} ${x?string.percent} 如今會輸出: $42.00 $42.00 42 $42.00 4,200% 由於默認的數字格式被設置成了「貨幣」。 除了這三種預約義格式,你可使用 Java 中數字格式語法寫的任意的數字格式 (http://java.sun.com/j2se/1.4/docs/api/java/text/DecimalFormat.html): <#assign x = 1.234> ${x?string("0")} ${x?string("0.#")} ${x?string("0.##")} ${x?string("0.###")} ${x?string("0.####")} ${1?string("000.00")} ${12.1?string("000.00")} ${123.456?string("000.00")} ${1.2?string("0")} ${1.8?string("0")} ${1.5?string("0")} <-- 1.5,rounded towards even neighbor ${2.5?string("0")} <-- 2.5,rounded towards even neighbor ${12345?string("0.##E0")} 輸出這些: 1 1.2 1.23 1.234 1.234 001.00 012.10 123.46 1 2 2 <-- 1.5, rounded towards even neighbor 2 <-- 2.5, rounded towards even neighbor 1.23E4 在金融和統計學中,四捨五入都是根據所謂的一半原則,這就意味着對最近的「鄰居」 進行四捨五入,除非離兩個鄰居距離相等,這種狀況下,它四捨五入到偶數的鄰居。若是你 注意看 1.5 和 2.5 的四捨五入的話,這在上面的示例中是能夠看到的,兩個都被四捨五入到 2,由於 2 是偶數,但 1 和 3 是奇數。 除了 Java 小數 語 法 模 式 之 外 , 你 可 以 編 寫 如 ${aNumber?string("currency")} 這 樣 的 代 碼 , 它 會 作 和 ${aNumber?string.currency} 同樣的事情。 正如以前展現的預約義格式,默認的數字格式也能夠在模板中進行設置: <#settingnumber_format="0.##"> ${1.234} 輸出這個: 1.23 要注意數字格式是本地化敏感的: <#setting locale="en_US"> US people write:${12345678?string(",##0.00")} <#setting locale="hu"> Hungarian people write:${12345678?string(",##0.00")} 輸出這個: US people write: 12,345,678.00 Hungarian people write: 12 345 678,00 1.2.3 round,floor,ceiling 數字的舍入 處理 注意: 內建函數 round 從 FreeMarker 2.3.13 版本以後才存在。 使用肯定的舍入法則,轉換一個數字到整數: round :返回最近的整數。若是數字以.5 結尾,那麼它將進位(也就是說向正無 窮方向進位) floor :返回數字的舍掉小數後的整數(也就是說向服務窮捨棄) ceiling :返回數字小數進位後的整數(也就是說向正無窮進位) 示例: <#assign testlist=[ 0, 1, -1, 0.5, 1.5, -0.5, -1.5, 0.25, -0.25, 1.75, -1.75]> <#list testlist as result> ${result} ?floor=${result?floor} ?ceiling=${result?ceiling} ?round=${result?round} </#list> 打印: 0 ?floor=0 ?ceiling=0 ?round=0 1 ?floor=1 ?ceiling=1 ?round=1 -1 ?floor=-1 ?ceiling=-1 ?round=-1 0.5 ?floor=0 ?ceiling=1 ?round=1 1.5 ?floor=1 ?ceiling=2 ?round=2 -0.5 ?floor=-1 ?ceiling=0 ?round=0 -1.5 ?floor=-2 ?ceiling=-1 ?round=-1 0.25 ?floor=0 ?ceiling=1 ?round=0 -0.25 ?floor=-1 ?ceiling=0 ?round=0 1.75 ?floor=1 ?ceiling=2 ?round=2 -1.75 ?floor=-2 ?ceiling=-1 ?round=-2 這些內建函數在分頁處理時也許有用。若是你僅僅想展現數字的舍入形式,那麼你應該 使用內建函數 string 和 numer_format 設置。 1.3 處理日期的內建函數 1.3.1 string (當用做日期值時)日期轉字符串 這個內建函數以指定的格式轉換日期類型到字符串類型。(當默認格式由 FreeMarker 的 date_format , time_format 和datetime_format 設置來支配時是很好的選 擇,那麼你就不須要使用這個內建函數了。) 格式能夠是預約義格式中的一種,或者你能夠指定明確的格式化模式。 預約義的格式是 short , medium , long 和 full ,它們定義了冗長的結果文本輸 出。例如,若是輸出的本地化是 U.S. English,並且時區是 U.S. Pacific,那麼下面的代碼: ${openingTime?string.short} ${openingTime?string.medium} ${openingTime?string.long} ${openingTime?string.full} ${nextDiscountDay?string.short} ${nextDiscountDay?string.medium} ${nextDiscountDay?string.long} ${nextDiscountDay?string.full} ${lastUpdated?string.short} ${lastUpdated?string.medium} ${lastUpdated?string.long} ${lastUpdated?string.full} 將會打印這樣的內容: 12:45 PM 12:45:09 PM 12:45:09 PM CEST 12:45:09 PM CEST 4/20/07 Apr 20, 2007 April 20, 2007 Friday, April 20, 2007 4/20/07 12:45 PM Apr 20, 2007 12:45:09 PM April 20, 2007 12:45:09 PM CEST Friday, April 20, 2007 12:45:09 PM CEST short , medium , long 和 full 的精確含義是以當前本地(語言)設置爲主的。 此外,它不是由 FreeMarker 肯定的,而是由你運行 FreeMarker 的 Java 平臺實現的。 對於包含日期和時間兩部分的日期類型,你能夠分別指定日期和時間部分的長度: ${lastUpdated?string.short_long} <#--short date, long time --> ${lastUpdated?string.medium_short} <#--medium date, short time --> 將會輸出: 4/8/03 9:24:44 PM PDT Apr 8, 2003 9:24 PM 注意 ?string.short 和 ?string.short_short 是相 同 的, ?string.medium 和 ?string.medium_medium 是相同的,等等。 警告! 不幸的是,因爲 Java 平臺的限制,你能夠在數據模型中保存日期變量,那裏 FreeMarker 不能決定變量是否存儲的是日期部分(年,月,日),仍是時間部分(時,分,秒,毫秒), 仍是二者都有。這種狀況下,當你編寫如 ${lastUpdated?string.short} ,或簡 單的 ${lastUpdated} 時 FreeMarker 不知道如何來顯示日期,所以模板會停止執行並拋 出錯誤。要阻止這些發生,你可使用內建函數 ?date , ?time 和 ?datetime 來幫助 FreeMarker。好比${lastUpdated?datetime?string.short} 。要詢問程序員 數據模型中肯定的變 量是否 有這個問 題,或通 常使用 內建函數 ?date , ?time 和 ?datetime 來處理。 要代替使用預約義的格式,你可使用 ?string(pattern_string) 來精確指定 格式的模式。這個模式使用 Java 日期格式的語法。好比: ${lastUpdated?string("yyyy-MM-ddHH: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) 注意: 不像預約義 格式 ,你不 能和 精確 的給 定模式 使用 內建 函數 ?date , ?time 和 ?datetime ,由於使用這個模式你就告訴 FreeMarker 來顯示哪部分的日期。然而, FreeMarker 將盲目地信任你,若是你顯示的部分不存在於變量中,因此你能夠顯示「干擾」。 好比 ${openingTime?string("yyyy-MM-dd hh:mm:ss a")} , 而 openingTime 中只存儲了時間,將會顯示1970-01-01 09:24:44 PM 。 定義模式的字符串也能夠是 "short" , "medium" , "short_medium" 等。這和 你使 用 預 定 義 格 式 語 法 :someDate?string("short") 和 someDate?string.short 是相同的。 也能夠參考:模板開發指南/模板/插值中的日期部分。 1.3.2 date ,time ,datetime (當使用日期值時) 這些內建函數用來指定日期變量中的哪些部分被使用: date :僅僅年,月和日的部分被使用。 ime :僅僅時,分,秒和毫秒的部分被使用。 datetime :日期和時間量部分都使用。 在最佳狀況下,你不須要使用這些內建函數。不幸的是,因爲 Java 平臺上的技術限制, FreeMarker 有時不能發現日期中的哪一部分在使用(也就是說,僅僅年+月+日在使用,或僅 僅時+分+秒+毫秒在使用,或兩種都用);詢問程序員哪些變量會有這個問題。若是 FreeMarker 不得不執行須要這些信息的操做-好比用文本顯示日期-可是它不知道哪一部分在使用,它會 以錯誤來停止運行。這就是你不得不使用內建函數的時候了。好比,假設 openingTime 是一個有這樣問題的變量: <#assign x = openingTime> <#-- noproblem can occur here --> ${openingTime?time} <#-- without ?timeit would fail --> <#-- For the sake of betterunderstanding, consider this: --> <#assign openingTime = openingTime?time> ${openingTime} <#-- this will work now--> 這些函數的另一種用法:來截短日期。好比: Last updated: ${lastUpdated} <#-- assumethat lastUpdated is a date-time value --> Last updated date: ${lastUpdated?date} Last updated time: ${lastUpdated?time} 將會輸出這樣的東西: Last updated: 04/25/2003 08:00:54 PM Last updated date: 04/25/2003 Last updated time: 08:00:54 PM 若是 ? 的左邊是字符串,那麼這些內建函數會將字符串轉換爲日期變量。(參考處理字 符串的內建函數 date) 1.3.3 iso_... 內建函數族 這些內建函數轉換日期,時間或時間日期值到字符串,並遵循 ISO 8601 的擴展格式。 這些 內 建 函 數 有 很 多 表 形 式 : iso_utc , iso_local , iso_utc_nz , iso_local_nz , iso_utc_m ,iso_utc_m_nz 等。名稱的構成由下列單詞順序組 成,每部分由一個_(下劃線)分隔開: 1. iso (必須的) 2. 是 utc 或 local 的兩者之一(必須的(除了給定一個參數,這個後面再來講)):來 指定你想根據 UTC 來打印日期或根據當前時區來打印。當前時區是根據 FreeMarker 的 設置項 time_zone 來肯定的,它一般是由程序員在模板外配置的(固然它也能夠在 模板內設置,好比使用 <#setting time_zone="America/New_York"> )。 3. h, m 或 ms (可選的):時間部分的精度。當忽略的時候,就默認設置到秒的精度(比 如 12:30:18 )。 h 表示小時的精度(好比 12 ), m 表示分鐘的精度(好比 12:30 ), ms 就表示毫秒的精度( 12:30:18.25,這裏表示 250 毫秒)。要注意當使用 ms 時, 毫秒會顯示爲百分制的形式(遵循標準)並且不會去尾到 0 秒。所以,若是毫秒的部分 變成 0 的話,整個的毫秒的部分就會被忽略掉了。同時也要注意毫秒的部分是由一個點 來分隔的,而不是逗號(遵循 Web 約定和 XML Schema 的日期/時間格式)。 4. nz (可選的):若是有的話,時區偏移(好比 +02:00 或 -04:30 或 Z )就不會顯示 出來了。不然是會顯示出來的,僅僅對日期值有效(由於有時區偏移的日期在 ISO 8601:2004 中沒有出現)。從 FreeMarker2.3.19 版開始,出於遵照 XML Schema 的日期/ 時間格式的考慮,偏移一般包含分鐘。 示例: <#assign x = openingTime> <#-- noproblem can occur here --> ${openingTime?time} <#-- without ?timeit would fail --> <#-- For the sake of betterunderstanding, consider this: --> <#assign openingTime =openingTime?time> ${openingTime} <#-- this will work now--> Last updated: ${lastUpdated} <#-- assumethat lastUpdated is a date-time value --> Last updated date: ${lastUpdated?date} Last updated time: ${lastUpdated?time} Last updated: 04/25/2003 08:00:54 PM Last updated date: 04/25/2003 Last updated time: 08:00:54 PM 可能輸出爲(基於當前的時間和時區): <#assign aDateTime = .now> <#assign aDate = aDateTime?date> <#assign aTime = aDateTime?time> Basic formats: ${aDate?iso_utc} ${aTime?iso_utc} ${aDateTime?iso_utc} Different accuracies: ${aTime?iso_utc_ms} ${aDateTime?iso_utc_m} Local time zone: ${aDateTime?iso_local} 可能輸出爲(基於當前的時間和時區): Basic formats: 2011-05-16 21:32:13Z 2011-05-16T21:32:13Z Different accuracies: 21:32:13.868Z 2011-05-16T21:32Z Local time zone: 2011-05-16T23:32:13+02:00 還有另一組 iso_... 內建函數形式,你可從名稱中以忽略掉 local 或 utc ,但 是要指定時區做爲內建函數的參數。好比 <#assign aDateTime = .now> ${aDateTime?iso("UTC")} ${aDateTime?iso("GMT-02:30")} ${aDateTime?iso("Europe/Rome")} The usual variations are supported: ${aDateTime?iso_m("GMT+02")} ${aDateTime?iso_m_nz("GMT+02")} ${aDateTime?iso_nz("GMT+02")} 可能輸出爲(基於當前的時間和時區) 2011-05-16T21:43:58Z 2011-05-16T19:13:58-02:30 2011-05-16T23:43:58+02:00 The usual variations are supported: 2011-05-16T23:43+02:00 2011-05-16T23:43 2011-05-16T23:43:58 若是該時區參數不能被解釋,那麼模板處理就會出錯而且終止。 參數也能夠是 java.util.TimeZone 對象類型(會返回 Java 中方法或在數據模 型中的值),而不只僅是字符串。 1.4 處理布爾值的內建函數 1.4.1 string (當被用做是布爾值時) 轉換布爾值爲字符串 轉換布爾值到字符串。你也以兩種方式來使用: 以 foo?string :這樣會使用表明 true 和 false 值的默認字符串來轉換布爾值爲字符 串。默認狀況,true 被翻譯爲 "true" ,而 false 被翻譯爲 "false" 。若是你用 FreeMarker 來生成源代碼,這是頗有用的,由於這個值不是對本地化(語言,國家)敏感的。爲了改變 這些默認的字符串,你可使用 boolean_format 設置。注意,若是變量是多類型的 變量,也就是有布爾值和字符串,那麼變量的字符串值會被返回。 以 foo?string("yes", "no") :若是布爾值是 true,這會返回第一個參數(這 裏是: "yes" ),不然就返回第二個參數(這裏是: "no" )。注意返回的的值是一個字符 串;若是參數是數字類型,首先它會被轉換成字符串。 1.5 處理序列的內建函 數 1.5.1 first 第一個子變量 序列的第一個子變量。若是序列爲空,那麼模板處理將會停止。 1.5.2 last 最後一個子變量 序列的最後一個子變量。若是序列爲空,那麼模板處理將會停止。 2011-05-16T21:43:58Z 2011-05-16T19:13:58-02:30 2011-05-16T23:43:58+02:00 The usual variations are supported: 2011-05-16T23:43+02:00 2011-05-16T23:43 2011-05-16T23:43:58 1.5.3 seq_contanis 序列包含… 注意: 這個內建函數從 FreeMarker 2.3.1 版本開始可用。而在 2.3 版本中不存在。 注意: seq_ 前綴在這個內建函數中是須要的,用來和contains 區分開。 contains 函 數用來在字符串中查找子串(由於變量能夠同時看成字符串和序列)。 辨別序列中是否包含指定值。它包含一個參數,就是來查找的值。好比: <#assign x = ["red", 16,"blue", "cyan"]> "blue":${x?seq_contains("blue")?string("yes", "no")} "yellow":${x?seq_contains("yellow")?string("yes", "no")} 16:${x?seq_contains(16)?string("yes", "no")} "16":${x?seq_contains("16")?string("yes", "no")} 輸出是: "blue": yes "yellow": no 16: yes "16": no 爲了查找值,這個函數使用了 FreeMarker 的比較規則(就像你使用的 == 運算符),除 了比較兩個不一樣類型的值,或 FreeMarker 不支持的類型來比較,其餘都不會引發錯誤,只 是爲認爲兩個值不相等。所以,你可使用它來查找標量值(也就是字符串,數字,布爾值, 或日期/時間類型)。對於其餘類型結果一般都是 false 。 對於容錯性,這個函數還對 collections 起做用。 1.5.4 seq_index_of 第一次出現… 時的位置 注意: 這個內建函數從 FreeMarker 2.3.1 版本開始可用。而在 2.3 版本中不存在。 注意: seq_ 前綴在這個內建函數中是須要的,用來和index_of 區分開。 index_of 函 數用來在字符串中查找子串(由於變量能夠同時看成字符串和序列)。 返回序列中第一次出現該值時的索引位置,若是序列不包含指定的值時返回 -1 。要查 找的值做爲第一個參數。好比這個模板: <#assign colors = ["red","green", "blue"]> ${colors?seq_index_of("blue")} ${colors?seq_index_of("red")} ${colors?seq_index_of("purple")} 將會輸出: 2 0 -1 爲了查找值,這個函數使用了 FreeMarker 的比較規則(就像你使用的 == 運算符),除 了比較兩個不一樣類型的值,或 FreeMarker 不支持的類型來比較,其餘都不會引發錯誤,只 是爲認爲兩個值不相等。所以,你可使用它來查找標量值(也就是字符串,數字,布爾值, 或日期/時間類型)。對於其餘類型結果一般是 -1 。 搜索開始的地方能夠由第二個可選的參數來肯定。若是在同一個序列中相同的項能夠多 次出現時,這是頗有用的。第二個參數的數值沒有什麼限制:若是它是負數,那麼就和它是 零的效果同樣,而若是它是比序列長度還大的數,那麼就和它是序列長度值的效果同樣。小 數值會被切成整數。好比: <#assign names = ["Joe","Fred", "Joe", "Susan"]> No 2nd param:${names?seq_index_of("Joe")} -2: ${names?seq_index_of("Joe",-2)} -1: ${names?seq_index_of("Joe",-1)} 0: ${names?seq_index_of("Joe",0)} 1: ${names?seq_index_of("Joe",1)} 2: ${names?seq_index_of("Joe",2)} 3: ${names?seq_index_of("Joe",3)} 4: ${names?seq_index_of("Joe",4)} 將會輸出: No 2nd param: 0 -2: 0 -1: 0 0: 0 1: 2 2: 2 3: -1 4: -1 1.5.5 seq_last_index_of 最後一次出現.. 的位置 注意: 這個內建函數從 FreeMarker 2.3.1 版本開始可用。而在 2.3 版本中不存在。 注意: seq_ 前綴在這個內建函數中是須要的,用來和last_index_of 區分開。 last_index_of 用於在字符串中搜索子串(由於一個變量能夠同時是字符串和序列)。 返回序列中最後一次出現值的索引位置,,若是序列不包含指定的值時返回 -1 。也就是 說,和 seq_index_of 相同,只是在序列中從最後一項開始向前搜索。它也支持可選的 第二個參數來肯定從哪裏開始搜索的索引位置。好比: <#assign names = ["Joe","Fred", "Joe", "Susan"]> No 2nd param:${names?seq_index_of("Joe")} -2: ${names?seq_index_of("Joe",-2)} -1: ${names?seq_index_of("Joe",-1)} 0: ${names?seq_index_of("Joe",0)} 1: ${names?seq_index_of("Joe",1)} 2: ${names?seq_index_of("Joe",2)} 3: ${names?seq_index_of("Joe",3)} 4: ${names?seq_index_of("Joe",4)} 將會輸出這個: No 2nd param: 2 -2: -1 -1: -1 0: 0 1: 0 2: 2 3: 2 4: 2 1.5.6 reverse 反轉序列 序列的反序形式。 1.5.7 size 序列大小 序列中子變量的數量(做爲一個數值)。假設序列中至少有一個子變量,那麼序列 s 中 最大的索引是 s?size - 1 (由於第一個子變量的序列是 0)。 1.5.8 sort 排序 以升序方式返回。(要使用降序排列時,使用它以後還要使用 reverse 內建函數)這 僅在子變量都是字符串時有效,或者子變量都是數字,或者子變量都是日期值(日期,時間, 或日期+時間),或者全部子變量都是布爾值時(從 2.3.17 版本開始)。若是子變量是字符串, 它使用本地化(語言)的具體單詞排序(一般是大小寫不敏感的)。好比: <#assign ls = ["whale","Barbara", "zeppelin", "aardvark", "beetroot"]?sort> <#list ls as i>${i} </#list> 將會打印(至少是 US 區域設置): aardvark Barbara beetroot whale zeppelin 1.5.9 sort_by 以… 來排序 返回由給定的哈希表子變量來升序排序的哈希表序列。(要降序排列使用這個內建函數 後還要使用 reverse 內建函數)這個規則和內建函數 sort 是同樣的,除了序列中的子 變量必須是哈希表類型,並且你不得不給哈希變量的命名,那會用來決定排序順序。好比: <#assign ls = [ {"name":"whale","weight":2000}, {"name":"Barbara","weight":53}, {"name":"zeppelin","weight":-200}, {"name":"aardvark","weight":30}, {"name":"beetroot","weight":0.3} ]> Order by name: <#list ls?sort_by("name") asi> - ${i.name}: ${i.weight} </#list> Order by weight: <#list ls?sort_by("weight") asi> - ${i.name}: ${i.weight} </#list> 將會打印(至少是 US 區域設置): Order by name: - aardvark: 30 - Barbara: 53 - beetroot: 0.3 - whale: 2000 - zeppelin: -200 Order by weight: - zeppelin: -200 - beetroot: 0.3 - aardvark: 30 - Barbara: 53 - whale: 2000 若是你用來排序的子變量的層次很深(也就是說,它是子變量的子變量的子變量,以此 類推),那麼你可使用序列來做爲參數,它指定了子變量的名字,來向下引導所需的子變 量。好比: <#assign members = [ {"name": {"first":"Joe", "last": "Smith"}, "age": 40}, {"name": {"first":"Fred", "last": "Crooger"}, "age": 35}, {"name": {"first":"Amanda", "last": "Fox"}, "age":25}]> Sorted by name.last: <#list members?sort_by(['name', 'last'])as m> - ${m.name.last}, ${m.name.first}: ${m.age}years old </#list> 將會打印(至少是 US 區域設置): Sorted by name.last: - Crooger, Fred: 35 years old - Fox, Amanda: 25 years old - Smith, Joe: 40 years old 1.5.10 chunk 區塊 注意: 這個內建函數從 FreeMarker 2.3.3 版本之後可用。 這個 內建 函數 分割 序列 到多 個大 小爲 函數 的第 一個 參數 給定 的序 列( 就 像 mySeq?chunk(3) )。結果是包含這些序列的一個序列。最後一個序列可能比給定的大 小要小,處分第二個參數也給定了(好比 mySeq?chunk(3, '-') ),那個就是用來填 充最後一個序列,以達到給定的大小。好比: <#assign seq = ['a', 'b', 'c', 'd', 'e','f', 'g', 'h', 'i', 'j']> <#list seq?chunk(4) as row> <#list row as cell>${cell}</#list> </#list> <#list seq?chunk(4, '-') as row> <#list row as cell>${cell}</#list> </#list> 這會輸出: a b c d e f g h i j a b c d e f g h i j - - 這個函數一般在輸出的序列中使用表格/柱狀的格式。當被用於 HTML 表格時,第二個 參數一般是 "\xA0" (也就是不換行的空格代碼,也就是咱們所知的「nbsp」),因此空 TD 的邊界就不會不顯示。 第一個參數必須是一個數字,並且至少是 1.若是這個數字不是整數,那麼它會被靜默地 去掉小數部分(也就是說 3.1 和 3.9 都會被規整爲 3)。第二個參數能夠是任意類型的值。 1.6 處理哈希表的內建函數 1.6.1 keys 鍵的集合 一個包含哈希表中查找到的鍵的序列。注意並非全部的哈希表都支持這個(詢問程序 員一個指定的哈希表是否容許這麼操做)。 <#assign h ={"name":"mouse", "price":50}> <#assign keys = h?keys> <#list keys as key>${key} = ${h[key]};</#list> 輸出: name = mouse; price = 50; 由於哈希表一般沒有定義子變量的順序,那麼鍵名稱的返回順序就是任意的。然而,一 些哈希表維持一個有意義的順序(詢問程序員指定的哈希表是不是這樣)。好比,由上述 {...} 語法建立的哈希表保存了和你指定子變量相同的順序。 1.6.2 值的集合 一個包含哈希表中子變量的序列。注意並非全部的哈希表都支持這個(詢問程序員一 個指定的哈希表是否容許這麼操做)。 至於返回的值的順序,和函數 keys 的應用是同樣的;看看上面的敘述就好了。 1.7 處理節點(XML )的內建函數 注意由這些內建函數返回的變量是由用於節點變量的實現生成的。意思就是返回的變量 能夠有更多的特性,附加於它這裏的狀態。好比,由內建函數 children 返回的序列和 XML DOM 節點也能夠被用做是哈希表或字符串,這在第三部分 XML 處理指南中有解釋。 1.7.1 children 子節點序列 一個包含該節點全部子節點(也就是直接後繼節點)的序列。 XML:這和特殊的哈希表的鍵 * 幾乎是同樣的。除了它返回全部節點,而不可是元素。 因此可能的子節點是元素節點,文本節點,註釋節點,處理指令節點等,並且還多是屬性 節點。屬性節點排除在序列以外。 1.7.2 parent 父節點 在節點樹中,返回該節點的直接父節點。根節點沒有父節點,因此對於根節點,表達式 node?parent?? 的值就是 false 。 XML:注意經過這個函數返回的值也是一個序列(當你編寫 someNode[".."] 時, 和 XPath 表達式 .. 的結果是同樣的)。也要注意屬性節點,它返回屬性所屬的元素節點,盡 管屬性節點不被算做是元素的子節點。 1.7.3 root 根節點 該節點所屬節點樹的根節點。 XML:根據 W3C,XML 文檔的根節點不是最頂層的元素節點,而是文檔自己,是最高元 素的父節點。例如,若是你想獲得被稱爲是 foo 的 XML(所謂的「文檔元素」,不要和「文 檔」搞混了)的最高元素,那麼你不得不編寫 someNode?root.foo 。若是你僅僅寫了 someNode?root ,那麼你獲得的是文檔自己,而不是文檔元素。 1.7.4 ancestors 祖先節點 一個包含全部節點祖先節點的序列,以直接父節點開始,以根節點結束。這個函數的結 果也是一個方法,你能夠用它和元素的徹底限定名來過濾結果。好比以名稱 section 用 node?ancestors("section") 來得到全部祖先節點的序列, 1.7.5 node_name 節點名稱 當被「訪問」時,返回用來決定哪一個用戶自定義指令來調用控制這個節點的字符串。可 以參見 visit 和 recurse 指令。 XML:若是節點是元素或屬性,那麼字符串就會是元素或屬性的本地(沒有前綴)名字。 不然,名稱一般在節點類型以後以 @ 開始。能夠參見 XML 處理指南中 2.2 節的形式化描述。 要注意這個節點名稱與在 DOM API 中返回的節點名稱不一樣;FreeMarker 節點名稱的目標是 給要處理節點的用戶自定義指令命名。 1.7.6 node_type 節點類型 描述節點類型的字符串。FreeMarker 沒有對節點類型定義準確的含義;它依賴於變量是 怎麼建模的。也可能節點並不支持節點類型。在這種情形下,該函數就返回未定義值,因此 你就不能使用返回值。(你能夠用 node?node_type?? 繼續檢查一個節點是不是支持類 型屬性) XML : 可 能 的 值 是"attribute" , "text" , "comment" , "document_fragment" ,"document" , "document_type" , "element", "entity" ,"entity_reference" , "notation" , "pi" 。注意沒有 "cdata" 類型,由於 CDATA 被認爲是普通文本元素。 1.7.7 node_namespace 節點命名空間 返回節點命名空間的字符串。FreeMarker 沒有爲節點命名空間定義準確的含義;它依賴 於變量是怎麼建模的。也可能節點沒有定義任何節點命名空間。這種情形下,該函數應該返 回未定義的變量(也就是 node?node_namespace?? 的值是 false ),因此你不能使 用這個返回值。 XML : 這 種 情 況 下 的 XML , 就 是 XML 命 名 空 間 的 URI ( 比 如 "http://www.w3.org/1999/xhtml" )。若是一個元素或屬性節點沒有使用 XML 命名空間,那麼這個函數就返回一個空字符串。對於其餘 XML 節點這個函數返回未定義的 變量。 1.8 不多使用的和專家級的內建函數 這些是你一般狀況下不該該使用的內建函數,可是在特殊狀況下(調試,高級宏)它們 會有用。若是你須要在普通頁面模板中使用這些函數,你可能會從新訪問數據模型,因此你 不要使用它們。 1.8.1 byte ,double ,float ,int ,long ,short 返回一個包含原變量中相同值的 SimpleNumber ,可是在內部表示值中使用了 java.lang.Type 。若是方法被重載了,這是有用的,或者一個 TemplateModel 解包器在自動選擇適合的 java.lang.* 類型有問題時。注意從 2.3.9 版本開始,解包器 有本質上改進,因此你將基本不會使用到這些內建函數來轉換數字類型了,除非在重載方法 調用中來解決一些含糊的東西。 內建函數 long 也能夠用於日期, 時間和時 間日期 類型的 值來獲取 返回爲 java.util.Date.getTime() 的值。若是你不得不調用使用long 類型時間戳的 Java 方法時,這是很是有用的。這個轉換不是自動進行的。 1.8.2 number_date ,number_to_time ,number_to_datetime 它們被用來轉換數字(一般是 Java 的 long 類型)到日期,時間或時間日期類型。這 就使得它們和 Java 中的 new java.util.Date(long) 是一致的。那也就是說,如今 數字能夠被解釋成毫秒數進行參數傳遞。數字能夠是任意內容和任意類型,只要它的值能夠 認爲是 long 就行。若是數字不是完整的,那麼它就會根據「五入」原則進行進位。這個 轉換不是自動進行的。 示例: ${1305575275540?number_to_datetime} ${1305575275540?number_to_date} ${1305575275540?number_to_time} 輸出就會是像這樣的(基於當前的本地化設置和時區): May 16, 2011 3:47:55 PM May 16, 2011 3:47:55 PM 1.8.3 eval 求值 這個函數求一個做爲 FTL 表達式的字符串的值。好比 "1+2"?eval 返回數字 3。 1.8.4 has_content 是否有內容 若是變量(不是 Java 的 null )存在並且不是「空」就返回 true ,不然返回 false 。 「空」的含義靠具體的情形來決定。它是直觀的常識性概念。下面這些都是空:長度爲 0 的字符串,沒有子變量的序列或哈希表,一個已經超過最後一項元素的集合。若是值不是字 符串,序列,哈希表或集合,若是它是數字,日期或布爾值(好比 0 和 false 是非空的), 那麼它被認爲是非空的,不然就是空的。注意當你的數據模型實現了多個模板模型接口,你 可能會獲得不是預期的結果。然而,當你有疑問時你一般可使用 expr!?size > 0 或 expr!?length > 0 來代替 expr?has_content 。 這個函數是個特殊的函數,你可使用像默認值操做符那樣的圓括號手法。也就是說, 你可 以 編 寫product.color?has_content 和 (product.color)?has_content 樣的代碼。第一個沒有控制當product 爲空 的情形,而第二個控制了。 1.8.5 interpret 將字符串解釋爲 FTL 模板 這個函數解釋字符串做爲 FTL 模板,並且返回一個用戶自定義指令,也就是當應用於任 意代碼塊中時,執行模板就像它當時被包含同樣。例如: <#assign x=["a","b", "c"]> <#assign templateSource =r"<#list x as y>${y}</#list>"> <#-- Note: That r was needed so that the${y} is not interpreted above --> <#assign inlineTemplate = templateSource?interpret> <@inlineTemplate /> 輸出爲: abc 正如你看到的, inlineTemplate 是用戶自定義指令,也就是當被執行時,運行當 時使用 interpret 函數生成的模板。 你也能夠在兩個元素的序列中應用這個函數。這種狀況下序列的第一個元素是模板源代 碼,第二個元素是內聯模板的名字。在調試時它能夠給內聯模板一個肯定的名字,這是頗有 用的。因此你能夠這麼來寫代碼: <#assign inlineTemplate = [templateSource, "myInlineTemplate"]?interpret> 在上述的模板中,要注意給內聯模板一個名字沒有及時的效果,它僅僅在你獲得錯誤報 告時能夠獲得額外的信息。 1.8.6 is_... 判斷函數族 這些內建函數用來檢查變量的類型,而後根據類型返回或。下面是 is_... 判斷函數 族的列表: 內建函數 若是值是… 時返回 true is_string 字符串 is_number 數字 is_boolean 布爾值 is_date 日期(全部類型:僅日期,僅時間和時間日期) is_method 方法 is_transform 變換 is_macro 宏 is_hash 哈希表 is_hash_ex 擴展的哈希表(也就是支持 ?keys 和 ?values ) is_sequence 序列 is_collection 集合 is_enumerable 序列或集合 is_indexable 序列 is_directive 指令的類型(好比宏,或 TemplateDirectiveModel , TemplateTransformModel 等) is_node 節點 1.8.7 namespace 命名空間 這個函數返回和宏變量關聯的命名空間(也就是命名空間的入口哈希表)。你只能和宏 一塊兒來用它。 1.8.8 new 建立TemplateModel 實現 這是用來建立一個肯定 TemplateModel 實現的變量的內建函數。 在 ? 的左邊你能夠指定一個字符串,是 TemplateModel 實現類的徹底限定名。結 果是調用構造方法生成一個方法變量,而後將新變量返回。 好比: 對於更多的關於構造方法參數被包裝和如何選擇重載的構造方法信息,請閱讀:程序開 髮指南/其它/Bean 包裝器部份內容。 這個內建函數能夠是出於安全考慮的,由於模板做者能夠建立任意的 Java 對象,只要 它們實現了 TemplateModel 接口,而後來使用這些對象。並且模板做者能夠觸發沒有 實現 TemplateModel 接口的類的靜態初始化塊。你能夠(從 FreeMarker 2.3.17 版開始) 限制 這 個 內 建 函 數 對 類 的 訪 問 , 通 過 使 用 Configuration.setNewBuiltinClassResolver(TemplateClassRes olver) 或設置new_builtin_class_resolver 。參考 Java API 文檔來獲取詳細信 息。若是您容許並非很可靠的用戶上傳模板,那麼你必定要關注這個問題。 <#-- Creates an user-defined directivebe calling the parameterless constructor of the class--> <#assign word_wrapp = "com.acmee.freemarker.WordWrapperDirective"?new()> <#-- Creates an user-defined directivebe calling the constructor with one numerical argument--> <#assign word_wrapp_narrow = "com.acmee.freemarker.WordWrapperDirective"?new(40)> 對於更多的關於構造方法參數被包裝和如何選擇重載的構造方法信息,請閱讀:程序開 髮指南/其它/Bean 包裝器部份內容。 這個內建函數能夠是出於安全考慮的,由於模板做者能夠建立任意的 Java 對象,只要 它們實現了 TemplateModel 接口,而後來使用這些對象。並且模板做者能夠觸發沒有 實現 TemplateModel 接口的類的靜態初始化塊。你能夠(從 FreeMarker 2.3.17 版開始) 限制 這 個 內 建 函 數 對 類 的 訪 問 , 通 過 使 用 Configuration.setNewBuiltinClassResolver(TemplateClassRes olver) 或設置new_builtin_class_resolver 。參考 Java API 文檔來獲取詳細信 息。若是您容許並非很可靠的用戶上傳模板,那麼你必定要關注這個問題。 --------------------- 做者:R鮮森 來源:CSDN 原文:https://blog.csdn.net/sinat_32366329/article/details/78888222 版權聲明:本文爲博主原創文章,轉載請附上博文連接!