freemarker文法帶demo版
1概念
2指令
if, else, elseif
switch, case, default, break
list, break
include
Import
compress
escape, noescape
assign
global
setting
macro, nested, return
t, lt, rt
3一些常用方法或注意事項
運算式轉換類
數字迴圈
對浮點取整數
給變數預設值
判斷對象是不是null
常用格式化日期
添加全域共用變數資料模型
直接調用java對象的方法
字串處理(內建方法)
在模板裡對sequences和hashes初始化
注釋標誌
sequences內建方法
hashes內建方法
4 freemarker在web開發中注意事項
web中常用的幾個對象
view中值的搜尋順序
在模板裡ftl裡使用標籤
如何初始化共用變數
與webwork整合配置
5進階方法
自訂方法
自訂 Transforms
目錄結束
1概念
最常用的3個概念
sequence 序列,對應java裡的list、數組等非索引值對的集合
hash 索引值對的集合
namespace 對一個ftl檔案的引用,利用這個名字可以訪問到該ftl檔案的資源
2指令
if, else, elseif
文法
<#if condition>
...
<#elseif condition2>
...
<#elseif condition3>
...
...
<#else>
...
</#if>
用例
<#if x = 1>
x is 1
</#if>
<#if x = 1>
x is 1
<#else>
x is not 1
</#if>
switch, case, default, break
文法
<#switch value>
<#case refValue1>
...
<#break>
<#case refValue2>
...
<#break>
...
<#case refValueN>
...
<#break>
<#default>
...
</#switch>
用例
字串
<#switch being.size>
<#case "small">
This will be processed if it is small
<#break>
<#case "medium">
This will be processed if it is medium
<#break>
<#case "large">
This will be processed if it is large
<#break>
<#default>
This will be processed if it is neither
</#switch>
數字
<#switch x>
<#case x = 1>
1
<#case x = 2>
2
<#default>
d
</#switch>
如果x=1 輸出 1 2, x=2輸出 2, x=3 輸出d
list, break
文法
<#list sequence as item>
...
<#if item = "spring"><#break></#if>
...
</#list>
關鍵字
item_index:是list當前值的下標
item_has_next:判斷list是否還有值
用例
<#assign seq = ["winter", "spring", "summer", "autumn"]>
<#list seq as x>
${x_index + 1}. ${x}<#if x_has_next>,</#if>
</#list>
輸出
1. winter,
2. spring,
3. summer,
4. autumn
include
文法
<#include filename>
or
<#include filename options>
options包含兩個屬性
encoding=”GBK” 編碼格式
parse=true 是否作為ftl文法解析,預設是true,false就是以文本方式引入.注意在ftl檔案裡布爾值都是直接賦值的如parse=true,而不是parse=”true”
用例
/common/copyright.ftl包含內容
Copyright 2001-2002 ${me}<br>
All rights reserved.
模板檔案
<#assign me = "Juila Smith">
<h1>Some test</h1>
<p>Yeah.
<hr>
<#include "/common/copyright.ftl" encoding=”GBK”>
輸出結果
<h1>Some test</h1>
<p>Yeah.
<hr>
Copyright 2001-2002 Juila Smith
All rights reserved.
Import
文法
<#import path as hash>
類似於java裡的import,它匯入檔案,然後就可以在當前檔案裡使用被匯入檔案裡的宏組件
用例
假設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安全的,這個時候就可以使用該運算式
<#escape x as x?html>
First name: ${firstName}
<#noescape>Last name: ${lastName}</#noescape>
Maiden name: ${maidenName}
</#escape>
相同運算式
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>
全域賦值文法,利用這個文法給變數賦值,那麼這個變數在所有的namespace中是可見的,如果這個變數被當前的assign文法覆蓋 如<#global x=2> <#assign x=1> 在當前頁面裡x=2將被隱藏,或者通過${.global.x}來訪問
setting
文法
<#setting name=value>
用來設定整個系統的一個環境
locale
number_format
boolean_format
date_format, time_format, datetime_format
time_zone
classic_compatible
用例
假如當前是匈牙利的設定,然後修改成美國
${1.2}
<#setting locale="en_US">
${1.2}
輸出
1,2
1.2
因為匈牙利是採用“,”作為十進位的分隔字元,美國是用“.”
macro, nested, return
文法
<#macro name param1 param2 ... paramN>
...
<#nested loopvar1, loopvar2, ..., loopvarN>
...
<#return>
...
</#macro>
用例
<#macro test foo bar="Bar" baaz=-1>
Test text, and the params: ${foo}, ${bar}, ${baaz}
</#macro>
<@test foo="a" bar="b" baaz=5*5-2/>
<@test foo="a" bar="b"/>
<@test foo="a" baaz=5*5-2/>
<@test foo="a"/>
輸出
Test text, and the params: a, b, 23
Test text, and the params: a, b, -1
Test text, and the params: a, Bar, 23
Test text, and the params: a, Bar, -1
定義迴圈輸出的宏
<#macro list title items>
<p>${title?cap_first}:
<ul>
<#list items as x>
<li>${x?cap_first}
</#list>
</ul>
</#macro>
<@list items=["mouse", "elephant", "python"] title="Animals"/>
輸出結果
<p>Animals:
<ul>
<li>Mouse
<li>Elephant
<li>Python
</ul>
包含body的宏
<#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>
<%@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. 初始化全域共用資料模型
freemark在web上使用的時候對共用資料的初始化支援的不夠,不能在配置初始化的時候實現,而必須通過ftl檔案來初始化全域變數。這是不能滿主需求的,我們需要在servlet init的時候留出一個介面來初始化系統的共用資料
具 體到和webwork整合,因為本身webwork提供了整合servlet,如果要增加全域共用變數,可以通過修改 com.opensymphony.webwork.views.freemarker.FreemarkerServlet來實現,我們可以在這個 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表示每次都更新,這個適合開發時候-->
<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><!—數字顯示格式-->
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>freemarker</servlet-name>
<url-pattern>*.ftl</url-pattern>
</servlet-mapping>
5進階方法
自訂方法
${timer("yyyy-MM-dd H:mm:ss", x)}
${timer("yyyy-MM-dd ", x)}
在模板中除了可以通過對象來調用方法外(${object.methed(args)})也可以直接調用java實現的方法,java類必須實現接 口TemplateMethodModel的方法exec(List args). 下面以把毫秒的時間轉換成按格式輸出的時間為例子
public class LongToDate implements TemplateMethodModel {
public Object 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對象放入到資料模型中
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
實現自訂的<@transform>文本或運算式</@transform>的功能,允許對中間的最終文本進行解析轉換
例子:實現<@upcase>str</@upcase> 將str轉換成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到資料模型中
root.put("upcase", new UpperCaseTransform());
在view(ftl)頁面中可以如下方式使用
<@upcase>
hello world
</@upcase>
列印輸出:
HELLO WORLD