Yeah.
<html>
<head>
<title>Test page</title>
</head>
<body>
<h1>Test page</h1>
<#include "/copyright_footer.html">
</body>
</html>
Import
語法
<#import path as hash>
類似于java里的import,它導(dǎo)入文件,然后就可以在當(dāng)前文件里使用被導(dǎo)入文件里的宏組件
用例
假設(shè)mylib.ftl里定義了宏copyright那么我們在其他模板頁面里可以這樣使用
<#import "/libs/mylib.ftl" as my>
<@my.copyright date="1999-2002"/>
"my"在freemarker里被稱作namespace
compress
語法
<#compress> ...
</#compress>
用來壓縮空白空間和空白的行
用例
<#assign x = " moo \n\n ">
(<#compress> 1 2 3 4 5 ${moo} test only I said, test only </#compress>)
輸出
(1 2 3 4 5
moo test only
I said, test only)
escape, noescape
語法
<#escape identifier as expression>
... <#noescape>...</#noescape> ... </#escape>
用例
主要使用在相似的字符串變量輸出,比如某一個模塊的所有字符串輸出都必須是html安全的,這個時候就可以使用該表達(dá)式 <#escape x as x?html> First name: ${firstName} <#noescape>Last name: ${lastName}</#noescape> Maiden name: ${maidenName} </#escape> 相同表達(dá)式 First name: ${firstName?html} Last name: ${lastName } Maiden name: ${maidenName?html}
assign
語法
<#assign name=value> or <#assign name1=value1 name2=value2 ... nameN=valueN> or <#assign same as above... in namespacehash> or <#assign name> capture this </#assign> or <#assign name in namespacehash> capture this </#assign>
用例
生成變量,并且給變量賦值 給seasons賦予序列值 <#assign seasons = ["winter", "spring", "summer", "autumn"]> 給變量test加1 <#assign test = test + 1> 給my namespage 賦予一個變量bgColor,下面可以通過my.bgColor來訪問這個變量 <#import "/mylib.ftl" as my> <#assign bgColor="red" in my> 將一段輸出的文本作為變量保存在x里 下面的陰影部分輸出的文本將被賦值給x <#assign x> <#list 1..3 as n> ${n} <@myMacro /> </#list> </#assign> Number of words: ${x?word_list?size} ${x} <#assign x>Hello ${user}!</#assign> error <#assign x=” Hello ${user}!”> true 同時也支持中文賦值,如: <#assign 語法> java </#assign> ${語法} 打印輸出: java
global
語法
<#global name=value> or <#global name1=value1 name2=value2 ... nameN=valueN> or <#global name> capture this </#global>
setting
語法
<#setting name=value>
用來設(shè)置整個系統(tǒng)的一個環(huán)境
locale
number_format
boolean_format
date_format, time_format, datetime_format
time_zone
classic_compatible
用例
假如當(dāng)前是匈牙利的設(shè)置,然后修改成美國
${1.2}
<#setting locale="en_US"> ${1.2}
輸出
1,2
1.2
因為匈牙利是采用“,”作為十進(jìn)制的分隔符,美國是用“.”
C一些常用方法或注意事項
表達(dá)式轉(zhuǎn)換類
${expression}計算expression并輸出
#{ expression }數(shù)字計算#{ expression ;format}安格式輸出數(shù)字format為M和m
M表示小數(shù)點后最多的位數(shù),m表示小數(shù)點后最少的位數(shù)如#{121.2322;m2M2}輸出121.23
數(shù)字循環(huán)
1..5 表示從1到5,原型number..number
對浮點取整數(shù)
${123.23?int} 輸出123
給變量默認(rèn)值
${var?default(“hello world<br>”)?html}如果var is null那么將會被hello world<br>替代
判斷對象是不是null
<#if mouse?exists>
Mouse found <#else> 也可以直接${mouse?if_exists})輸出布爾形
常用格式化日期
openingTime必須是Date型,詳細(xì)查看freemarker文檔 Reference->build-in referece->build-in for date ${openingTime?date} ${openingTime?date_time} ${openingTime?time}
添加全局共享變量數(shù)據(jù)模型
在代碼里的實現(xiàn) cfg = Configuration.getDefaultConfiguration(); cfg.setSharedVariable("global", "you good"); 頁面實現(xiàn)可以通過global指令,具體查看指令里的global部分
直接調(diào)用java對象的方法
${object.methed(args)}
字符串處理(內(nèi)置方法)
html安全輸出
“abc<table>sdfsf”?html
返回安全的html輸出,替換掉html代碼
xml安全輸出
var?xml
substring的用法
<#assign user=”hello jeen”>
${user[0]}${user[4]} ${user[1..4]} 輸出 : ho ello
類似String.split的用法
“abc;def;ghi”?split(“;”)返回sequence
將字符串按空格轉(zhuǎn)化成sequence,然后取sequence的長度
var?word_list 效果同 var?split(“ ”)
var?word_list?size
取得字符串長度
var?length
大寫輸出字符
var?upper_case
小寫輸出字符
var?lower_case
首字符大寫
var?cap_first
首字符小寫
var?uncap_first
去掉字符串前后空格
var?trim
每個單詞的首字符大寫
var?capitalize
類似String.indexof:
“babcdabcd”?index_of(“abc”) 返回1 “babcdabcd”?index_of(“abc”,2) 返回5
類似String.lastIndexOf
last_index_of和String.lastIndexOf類似,同上
下面兩個可能在代碼生成的時候使用(在引號前加”\”)
j_string: 在字符串引號前加”\” <#assign beanName = 'The "foo" bean.'> String BEAN_NAME = "${beanName?j_string}"; 打印輸出: String BEAN_NAME = "The \"foo\" bean."; js_string: <#assign user = "Big Joe's \"right hand\"."> <script> alert("Welcome ${user}!"); </script> 打印輸出 alert("Welcome Big Joe\'s \"right hand\"!");
替換字符串 replace
${s?replace(‘ba’, ‘XY’ )} ${s?replace(‘ba’, ‘XY’ , ‘規(guī)則參數(shù)’)}將s里的所有的ba替換成xy 規(guī)則參數(shù)包含:i r m s c f具體含義如下:
· i: 大小寫不區(qū)分.
· f: 只替換第一個出現(xiàn)被替換字符串的字符串
· r: XY是正則表達(dá)式
· m: Multi-line mode for regular expressions. In multi-line mode the expressions ^ and $ match just after or just before, respectively, a line terminator or the end of the string. By default these expressions only match at the beginning and the end of the entire string.
· s: Enables dotall mode for regular expressions (same as Perl singe-line mode). In dotall mode, the expression . matches any character, including a line terminator. By default this expression does not match line terminators.
· c: Permits whitespace and comments in regular expressions.
D freemarker在web開發(fā)中注意事項
freemarker與webwork整合
web中常用的幾個對象
Freemarker的ftl文件中直接使用內(nèi)部對象:
${Request ["a"]}
${RequestParameters["a"]}
${Session ["a"]}
${Application ["a"]}
${JspTaglibs ["a"]}
與webwork整合之后 通過配置的servlet 已經(jīng)把request,session等對象置入了數(shù)據(jù)模型中
在view中存在下面的對象
我們可以在ftl中${req}來打印req對象
- req - the current HttpServletRequest
- res - the current HttpServletResponse
- stack - the current OgnlValueStack
- ognl - the OgnlTool instance
- webwork - an instance of FreemarkerWebWorkUtil
- action - the current WebWork action
- exception - optional the Exception instance, if the view is a JSP exception or Servlet exception view
view中值的搜索順序
${name}將會以下面的順序查找name值
- freemarker variables
- value stack
- request attributes
- session attributes
- servlet context attributes
在模板里ftl里使用標(biāo)簽
注意,如果標(biāo)簽的屬性值是數(shù)字,那么必須采用nubmer=123方式給屬性賦值
JSP頁面
<%@page contentType="text/html;charset=ISO-8859-2" language="java"%>
<%@taglib uri="/WEB-INF/struts-html.tld" prefix="html"%> <%@taglib uri="/WEB-INF/struts-bean.tld" prefix="bean"%> <html> <body> <h1><bean:message key="welcome.title"/></h1> <html:errors/> <html:form action="/query"> Keyword: <html:text property="keyword"/><br> Exclude: <html:text property="exclude"/><br> <html:submit value="Send"/> </html:form> </body> </html>
模板ftl頁面
<#assign html=JspTaglibs["/WEB-INF/struts-html.tld"]>
<#assign bean=JspTaglibs["/WEB-INF/struts-bean.tld"]> <html> <body> <h1><@bean.message key="welcome.title"/></h1> <@html.errors/> <@html.form action="/query"> Keyword: <@html.text property="keyword"/><br> Exclude: <@html.text property="exclude"/><br> <@html.submit value="Send"/> </@html.form> </body> </html>
如何初始化共享變量
1. 初始化全局共享數(shù)據(jù)模型
freemark在web上使用的時候?qū)蚕頂?shù)據(jù)的初始化支持的不夠,不能在配置初始化的時候?qū)崿F(xiàn),而必須通過ftl文件來初始化全局變量。這是不能滿主需求的,我們需要在servlet init的時候留出一個接口來初始化系統(tǒng)的共享數(shù)據(jù)
具體到和webwork整合,因為本身webwork提供了整合servlet,如果要增加全局共享變量,可以通過修改com.opensymphony.webwork.views.freemarker.FreemarkerServlet來實現(xiàn),我們可以在這個servlet初始化的時候來初始化全局共享變量
與webwork整合配置
配置web.xml
<servlet>
<servlet-name>freemarker</servlet-name>
<servlet-class>com.opensymphony.webwork.views.freemarker.FreemarkerServlet</servlet-class>
<init-param>
<param-name>TemplatePath</param-name>
<param-value>/</param-value>
<!—模板載入文件夾,這里相對context root,遞歸獲取該文件夾下的所有模板-->
</init-param>
<init-param>
<param-name>NoCache</param-name> <!—是否對模板緩存-->
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>ContentType</param-name>
<param-value>text/html</param-value>
</init-param>
<init-param>
<param-name>template_update_delay</param-name>
<!—模板更新時間,0表示每次都更新,這個適合開發(fā)時候-->
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>default_encoding</param-name>
<param-value>GBK</param-value>
</init-param>
<init-param>
<param-name>number_format</param-name>
<param-value>0.##########</param-value><!—數(shù)字顯示格式-->
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>freemarker</servlet-name>
<url-pattern>*.ftl</url-pattern>
</servlet-mapping>
E高級方法
自定義方法
${timer("yyyy-MM-dd H:mm:ss", x)}
${timer("yyyy-MM-dd ", x)}
在模板中除了可以通過對象來調(diào)用方法外(${object.methed(args)})也可以直接調(diào)用java實現(xiàn)的方法,java類必須實現(xiàn)接口TemplateMethodModel的方法exec(List args). 下面以把毫秒的時間轉(zhuǎn)換成按格式輸出的時間為例子
public class LongToDate implements TemplateMethodModel {
public TemplateModel exec(List args) throws TemplateModelException { SimpleDateFormat mydate = new SimpleDateFormat((String) args.get(0))); return mydate.format(new Date(Long.parseLong((String)args.get(1))); } }
將LongToDate對象放入到數(shù)據(jù)模型中 root.put("timer", new IndexOfMethod()); ftl模板里使用 <#assign x = "123112455445"> ${timer("yyyy-MM-dd H:mm:ss", x)} ${timer("yyyy-MM-dd ", x)}
輸出
2001-10-12 5:21:12
2001-10-12
自定義 Transforms
實現(xiàn)自定義的<@transform>文本或表達(dá)式</@transform>的功能,允許對中間的最終文本進(jìn)行解析轉(zhuǎn)換
例子:實現(xiàn)<@upcase>str</@upcase> 將str轉(zhuǎn)換成STR 的功能
代碼如下:
import java.io.*;
import java.util.*; import freemarker.template.TemplateTransformModel; class UpperCaseTransform implements TemplateTransformModel { public Writer getWriter(Writer out, Map args) { return new UpperCaseWriter(out); } private class UpperCaseWriter extends Writer { private Writer out; UpperCaseWriter (Writer out) { this.out = out; } public void write(char[] cbuf, int off, int len) throws IOException { out.write(new String(cbuf, off, len).toUpperCase()); } public void flush() throws IOException { out.flush(); } public void close() { } } }
然后將此對象put到數(shù)據(jù)模型中
root.put("upcase", new UpperCaseTransform());
在view(ftl)頁面中可以如下方式使用
<@upcase>
hello world
</@upcase>
打印輸出:
HELLO WORLD
F.Built-ins
${x?upper_case} – 小寫變大寫
${test?html} - 轉(zhuǎn)換為HTML編碼格式
${repeat("A", B)} – 復(fù)制B次A
Example:
${test?html}
${test?upper_case?html}
Assuming that test stores the string ``Tom & Jerry'', the output will be:
Tom & Jerry
TOM & JERRY
---------
${repeat("What", 3)}
will print: :WhatWhatWhat
1. String內(nèi)置的JavaScript轉(zhuǎn)換: js_string
用途:用于JavaScript轉(zhuǎn)義,轉(zhuǎn)換',",換行等特殊字符
模板:
<script>
alert("${errorMessage?js_string}");
</script>
輸出:
<script>
alert("Readonly\'s pet name is \"Cross Bone\"");
</script>
2.內(nèi)置的默認(rèn)值處理:default
用途: 用于處理默認(rèn)值
模本:
User: ${userLogin.name?default("Anonymous")}
<td>${(employee.department.manager.name)?default(" ")}</td>
輸出:
User: Anonymous
<td> </td>
注,可以對整個對象樹加上(),再用內(nèi)置處理器這種方便的做法,偶也是最近剛學(xué)會的,以前一直用很傻的方法做.....
3. Sequence內(nèi)置的計數(shù)器: xxx_index
用途:顯示序號
模板:
<#list employees as e>
${e_index}. ${e.name}
</#list>
輸出:
1. Readonly
2. Robbin
4. Sequence內(nèi)置的分段器: chunk
用途:某些比較BT的排版需求
模板:
<#assign seq = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']>
<#list seq?chunk(4) as row>
<ul>
<li><#list row as cell>${cell} </#list>
</#list>
<#list seq?chunk(4, '-') as row>
<tr>
<td><#list row as cell>${cell} </#list></td>
</tr>
</#list>
輸出:
<ul>
<li>a
<li>b
<li>c
<li>d
<ul>
<li>e
<li>f
<li>g
<li>h
<ul>
<li>i
<li>j
<tr>
<td>a</td>
<td>b</td>
<td>c</td>
<td>d</td>
</tr>
<tr>
<td>e</td>
<td>f</td>
<td>g</td>
<td>h</td>
</tr>
<tr>
<td>i</td>
<td>j</td>
<td>-</td>
<td>-</td>
</tr>
String
${"It's \"quoted\" and
this is a backslash: \\"}
${'It\'s "quoted" and
this is a backslash: \\'}
${r"${foo}"}
raw字符串,原封不動地現(xiàn)實引號中的內(nèi)容
ps:前一種是用雙引號來引用字符串,后一種是用單引號來引用字符串。
分別需要對雙引號和單引號進(jìn)行轉(zhuǎn)義
${"${user}${user}${user}${user}"}
${user + user + user + user}
效果相同
★substring
${user[0]}${user[4]}
${user[1..4]}
${user[4..]}
★number
不支持科學(xué)計數(shù)法
小數(shù)點前面的零不能省略
★sequences
<#list ["winter", "spring", "summer", "autumn"] as x>
${x}
</#list>
<#list 2..5 as x> ${x} </#list>
<#list [2,3,4,5] as x> ${x} </#list>
數(shù)組的拼接
<#list ["Joe", "Fred"] + ["Julia", "Kate"] as user>
- ${user}
</#list>
★hash
<#assign ages = {"Joe":23, "Fred":25} + {"Joe":30, "Julia":18}>
- Joe is ${ages.Joe}
- Fred is ${ages.Fred}
- Julia is ${ages.Julia}
注意重復(fù)的鍵對應(yīng)的值取最后的一個
★運算
${5/2?int} 顯示2
cap_first : 首字母大寫
capitalize: 所有單詞首刺目大寫
html : 轉(zhuǎn)換為HTML格式
- < replaced with <
- > replaced with >
- & replaced with &
- " replaced with "
index_of : 顯示元素所在的位置
"abcabc"?index_of("bc")
返回值為1(下標(biāo)從0開始)
Contains:判斷是否存在字符
<#if "piceous"?contains("ice")>It contains "ice"</#if>
輸出: It contains "ice"
Replace :替換
split(“XX”):截取XX之后的字符
<#list "someMOOtestMOOtext"?split("MOO") as x>
- ${x}
</#list>
輸出:
- some
- test
- text
starts_with :字符串由什么開始返回布爾型
trim :去掉空格
seq_index_of 數(shù)組中元素的位置
<#assign colors = ["red", "green", "blue"]>
${colors?seq_index_of("blue")}
輸出: 2
Default : 設(shè)置變量的默認(rèn)值
Exists:放在if句 如果沒有…..
<#if mouse?exists>
Mouse found
<#else>
No mouse found
</#if>
Creating mouse...
<#assign mouse = "Jerry">
<#if mouse?exists>
Mouse found
<#else>
No mouse found
</#if>
輸出 :
No mouse found
Creating mouse...
Mouse found
if_exists 放在一般語句
(${mouse?if_exists})
Creating mouse...
<#assign mouse = "Jerry">
(${mouse?if_exists})
輸出:
()
Creating mouse...
(Jerry)
刪除空白行和空格
<#compress>
...
</#compress>
讓此標(biāo)記內(nèi)的代碼都執(zhí)行<#escape 后的?參數(shù)
<#escape>
</#escape>
<#escape x as x?html>
From: ${mailMessage.From}
Subject: ${mailMessage.Subject}
<#noescape>Message: ${mailMessage.htmlFormattedBody}</#noescape>
...
</#escape>
輸出:
From: ${mailMessage.From?html}
Subject: ${mailMessage.Subject?html}
Message: ${mailMessage.htmlFormattedBody}
...
[A2]<#import “lib/abc.ftl” as abc>這里的abc叫做namespace