天天看點

Freemarker常用技巧

1,截取字元串

有的時候我們在頁面中不需要顯示那麼長的字元串,比如新聞标題,這樣用下面的例子就可以自定義顯示的長度

< lt. <= lte. > gt. >= gte

<#if jstbqkVO.gzdd?length lt 8>

           <a href>${jstbqkVO.gzdd?default("")}</a>

      <#else>

           <a href title="${jstbqkVO.gzdd}">${jstbqkVO.gzdd[0..3]?default("")}...</a>

</#if>

意思就是如果這個字元串的長度小于8,那麼就正常顯示,反之則取4位

2.連接配接字元串

                     ${"Hello," + user + "!"} //輸出結果為:hello,gs!

3,日期格式和boolean 類型,轉化為string類型

                     例子2:

                            ${lastUpdate?string("yyyy-MM-dd HH:mm:ss zzzz")}      

                            ${lastUpdate?string("EEE,MMM d, ''yy")}

                            ${.................("EEEE,MMM 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)

                     例子3:

                            <#assign foo=true/>

                            ${foo?string("yes","no")}     //輸出結果:yes

4,排序:

1.升序.sort_by()

<#list list?sort_by("字段") as x> 

</#list>

2.降序.sort_by()?reverse

<#list list?sort_by("字段")?reverse as x>

5去空格:

${xx?trim}

6數值精度控制

                     mX:小數部分最小X位。

                     MX:小數部分最大X位。

                     例子:

                            <#assign x=2.582/>

                            <#assign y=4/>

                            #{x; M2}             //2.58

                            #{y; M2}             //4

                            #{x; m1M2}        //2.58

                            #{y; m1M2}        //4.0

7特殊字元串的轉義

                     \":雙引号    \\:反斜杠     \r:回車         \b:倒退鍵

                     \':單引号     \n:換行        \t:Tab           \f:Form feed

                     \l:<         \g:>        \a:&              \{:{

           \xCode:直接通過4位的十六進制數來指定Unicode碼

,輸出改Unicode對應的字元。

                     * 所謂頂層變量就是直接放在資料模型中的值。

                            Map root = new HashMap();

                            root.put("name","yeeku");  //name是一個頂層對象

                     * 對于頂層變量,直接使用${variableName}來輸出變量值

* 集合連接配接運算是将兩個集合連接配接成一個新的集合,連接配接集合的運算符是'+'.

                            <#list ["一","二","三"] + ["四","五","六"] as x>

                                   ${x}

                            </#list>

                     //輸出結果如下:

                                   一二三四五六

                     * 取整運算

                            <#assign x=5>

                            ${(x/2)?>int}       //2

                            ${1.1?int}            //1

                            ${1.999?int} //1

                            ${-1.1?int}          //-1

                         =(==)     :判斷兩個值是否相等

                            !=           :............不相等

                            >(gt)      :判斷左邊是否大于右邊

                            >=(gte)  :.....

                            <(lt)       :.....

                            <=(lte)    :.....

12 邏輯運算符

                        * 邏輯運算符隻能作用于布爾值,否則将産生錯誤.

                            邏輯與:&&

                            邏輯或:||

                            邏輯非:!

13  内置函數

html:字元串中所有的特殊HTML字元都需要用實體引用來代替(比如<代替<)

 cap_first:字元串的第一個字母變為大寫形式

lower_case:字元串的小寫形式

upper_case:字元串的大寫形式

trim:去掉字元串首尾的空格

序列使用的内建函數:

size:序列中元素的個數

 數字使用的内建函數:

int:數字的整數部分(比如-1.9?int就是-1)9>.空值運算符

length:字元串的長度

string :把其他格式的資料,轉化為string類型

例:

${test?html}

${test?upper_case?html}

假設字元串test存儲”Tom & Jerry”,那麼輸出為:

Tom & Jerry

TOM & JERRY

${seasons?size}

${seasons[1]?cap_first}

${"horse"?cap_first}

假設seasons存儲了序列"winter", "spring", "summer", "autumn",那麼上面的輸出将會是:

4

Spring

Horse

14.運算符優先級

                     * 推薦使用括号來決定運算優先級.

                            1>.一進制運算符: !

                            2>.内建函數  : ?

                            3>.乘除法    : *,/,%

                            4>.加減法    : +,-

                            5>.比較              : <,>,<=,>=(lt,lte,gt,gte)

                            6>.相等              : ==(=),!=

                            7>.邏輯與   : &&

                            8>.邏輯或   : ||

                            9>.數字範圍      : ..

15,freemarker判斷傳回值是否為空,null的方法

對于null,或者miss value,freemarker會報錯

!:default value operator,文法結構為:unsafe_expr!default_expr,比如 ${mouse!"No mouse."} 當mouse不存在時,傳回default value;

(product.color)!"red"   這種方式,能夠處理product或者color為miss value的情況; 

而product.color!"red"将隻處理color為miss value的情況 

??: Missing value test operator ,測試是否為missing value 

unsafe_expr?? :product.color??将隻測試color是否為null 

(unsafe_expr)??:(product.color)??将測試product和color是否存在null 

?exists:舊版本的用法 

比如:<#if mouse??>

   Mouse found

<#else>

   No mouse found

Creating mouse...

<#assign mouse = "Jerry">

<#if mouse??>

FreeMarker的常用指令

                     <#if condifition>

                            ...

                     <#elseif condifition>

                     <#else>

                     </#if>

                     <#switch value>

                            <#case refValue1>

                                   ...

                            <#break>

                            <#case refValue2>

                            <#default>

                     </#switch>

                     <#list sequence as item>

                     </#list>

                     * item_index  :目前變量的索引值.

                     * item_has_next    :是否存在下一個對象.

                      <#list ["星期一","星期二","星期三","星期四","星期五","星期六"] as x>

                                   ${x_index + 1}.${x}

                                   <#if x_has_next>,</#if>

                                   <#if x="星期四"><#break></#if>

                            輸出結果:

                                   1.星期一,

                                   2.星期二,

                                   3.星期三,

                                   4.興趣四,

4>.include指令     

:用于指定包含指定頁面.

                     <#include filename [options]>

                     * filename:     該參數指定被包含的模闆檔案.

                     * options :      該參數可以被省略,指定包含時的選項,包含encoding和parase兩個選項.   

                     <#import path as mapObject>

                            * path            :指定要被導入的模闆檔案.

                            * mapObject   :是一個Map對象.

                            意思:将path路徑中的變量都放在mapObject中.

                            例子:<#import "/lib/common.ftl" as com>

                     noparse指令指定FreeMarker不處理該指令裡包含的内容.

                     <#noparse>...</#noparse>

                     * escape:該指令導緻body區的插值都會被自動加上escape表達式.

                     * escape指令解析模闆時起作用,而不是在運作時起作用.

                     * escape指令也嵌套使用,子escape繼承父escape的規則.

                     * 如果需要指定某些插值無需添加escape表達式,則應該使用noescape指令.

                     <#escape identifier as expression>

                            <#noescape>...</#noescape>

                     </#escape>

                     * 它用于為該模闆頁面建立或替換一個(頂層)或多個變量.

                     第一種用法:<#assign name="value" [in namespacehash]>

                            in子句用于将建立的name變量放入namespacehash命名空間中.

                     第二種用法:<#assign name1=value1 name2=value2 ... nameN=valueN [in namespacehash]>

                     第三種用法:   是指将assign指令的内容指派給name變量.

                                          <#assign name [in namespacehash]>

                                                 capture this

                                          </#assign>

                                   例子:

                                   <#assign x>

                                          <#list ["一","二","三"] as n>

                                                 ${n}

                                          </#list>

                                   </#assign>

                                   ${x}

              補充.global指令,全局變量指派

:該指令用于設定FreeMarker的運作環境.

                     <#setting name=value>

                     name的取值範圍如下:

                            locale:該指令指定該模闆所使用的國家語言/語言選項.

                            number_format:該指令指定格式化輸出數字的選項.

                            boolean_format:該指令指令兩個布爾值的文法格式,預設值是"false".

                            date_format、time_format、datetime_format:格式化輸出日期的格式.

                            time_zone: 設定格式化輸出日期時所使用的時區.

宏和變換器變量是兩種不同類型的使用者自定義指令,他們的差別是:

宏可以在模闆中用macro指令來定義

變換器是在模闆外由程式定義

1、宏:和某個變量關聯的模闆片段,以便在模闆中通過使用者自定義指令使用該變量

1-1、基本用法:

例如:

<#macro greet>

<font size="+2"> Hello JOE!</font>

</#macro>

使用時:

<@greet></@greet>

如果沒有體内容也可以用

<@greet />

1-2、變量:

1)、可以在宏定義之後定義參數,宏參數是局部變量,隻在宏定義中有效。如:

<#macro greet person>

<font size="+2"> Hello ${person}!</font>

<@greet person="emma"> and <@greet person="LEO">

輸出為:

<font size="+2"> Hello emma!</font>

<font size="+2"> Hello LEO!</font>

注意:宏的參數是FTL表達式,是以,person=emma和上面的例子中具有不同的意義,這意味着将變量emma的值傳給person,這個值可能是任意一種資料類型,甚至是一個複雜的表達式。

宏可以有多個參數,使用時參數的次序是無關的,但是隻能使用宏中定義的參數,并且對所有參數指派。如:

<#macro greet person color>

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

<@greet color="black" person="emma" />正确

<@greet person="emma" />錯誤,color沒有指派,此時,如果在定義宏時為color定義預設值<#macro greet person color="black">這樣的話,這個使用方法就是正确的。

<@greet color="black" person="emma" bgcolor="yellow" />錯誤,宏greet定義中未指定bgcolor這個參數

              . 編寫函數

    2.注冊與使用

        有兩種方式:

      (1).在模闆檔案中注冊,在模闆中使用

<#assign getSysdate= package com.freemarker.test.SqlGetSysdateMethod?new()>

<#assign curdate= getSysdate(yyyy-MM-ddt)/>

(2).處理模闆檔案時注冊關鍵代碼:

Map<String,Object> root=new HashMap<String, Object>();  

root.put(getSysdate, new StringLengthMethod());

Configuration config=new Configuration();  

            File file=new File(templatePath);  

            //并加載模闆檔案  

            config.setDirectoryForTemplateLoading(file);  

            //設定包裝器,并将對象包裝為資料模型  

            config.setObjectWrapper(new DefaultObjectWrapper());  

            //擷取模闆,并設定編碼方式,這個編碼必須要與頁面中的編碼格式一緻  

            Template     template=config.getTemplate(templateName,templateEncoding); 

            //合并資料模型與模闆  

            template.process(root, out);

<#macro pagination totalCount pageSize>  

<#--聲明一個函數transform 轉換uri,在新的uri上pager_offset參數  -->  

    <#assign transform = "util.TransformURI"?new()>  

    <#--聲明一個函數,得到目前頁碼-->  

    <#assign pagerOffset = "util.PagerOffset"?new()>  

    <#--聲明一個函數,根據傳入的totalCount,pageSize得到總頁數-->  

    <#assign pagerCount = "util.PageCount"?new()>  

    <#assign pageCount=pagerCount(totalCount,pageSize)>  

    <#--得到目前的URI和請求參數,得到目前的頁碼-->  

    <#if request.queryString?exists>  

        <#assign uri=request.requestURI+"?"+request.queryString>  

        <#assign pageIndex=pagerOffset(uri)>  

        <#assign new_uri=transform(uri)>  

    <#else>  

        <#assign uri=request.requestURI>  

    </#if>  

    <#if (pageIndex>pageCount)>  

        <#assign pageIndex=pageCount>  

    <#if (pageIndex>1)>  

        <a href="${new_uri+1}" title="首頁"><<</a>  

    <#--如果前面頁數過多,顯示"..."-->  

    <#if (pageIndex>5)>  

        <#assign prevPages=pageIndex-9>  

        <#if prevPages lt 1>  

            <#assign prevPages=1>  

        </#if>  

        <#assign start=pageIndex-4>  

        <a href="${new_uri+prevPages}" title="向前5頁">...</a>  

        <#assign start=1>  

     </#if>  

    <#-- 顯示目前頁附近的頁-->  

    <#assign end=pageIndex+4>  

    <#if (end>pageCount)>  

        <#assign end=pageCount>  

    <#list start..end as index>  

        <#if pageIndex==index>  

            <b>${index}</b>  

        <#else>  

            <a href="${new_uri+index}">${index}</a>  

    </#list>  

    <#--如果後面頁數過多,顯示"...":-->  

    <#if (end lt pageCount)>  

        <#assign endend=end+5>  

        <#if (end>pageCount)>  

            <#assign end=pageCount>  

        <a href="${new_uri+end}" title="向後5頁">...</a>  

    <#-- 顯示"下一頁":-->  

    <#if (pageIndex lt pageCount)>  

        <a href="${new_uri+pageCount}" title="末頁">>></a>  

</#macro>  

自定義了三個方法:

PageCount.java

package util;   

import java.util.List;   

import freemarker.template.TemplateMethodModel;   

import freemarker.template.TemplateModelException;   

/**  

 * 根據傳入的參數,計算出所有的頁數  

 * @author legolas  

 */  

public class PageCount implements TemplateMethodModel {

    @Override  

    public Object exec(List args) throws TemplateModelException {

        Integer totalCount = 0;   

        Integer pageSize = 0;   

        try {   

            totalCount = Integer.parseInt((String) args.get(0));  

            pageSize = Integer.parseInt((String) args.get(1));   

        } catch (NumberFormatException e) {   

    throw new TemplateModelException("請輸入正确的總記錄數和頁面記錄數");   

        }   

        Integer pageCount = totalCount / pageSize   

          + (totalCount % pageSize == 0 ? 0 : 1);   

        return pageCount;   

    }   

}  

TransformURI.java

 package util;   

 * 根據傳入的uri,在uri後面加上分頁參數  

 *  

public class TransformURI implements TemplateMethodModel{   

        String uri = (String) args.get(0);   

        int n = uri.lastIndexOf("?");   

        if (n == -1) {   

            return uri + "?pager_offset=";   

        if (uri.lastIndexOf("?pager_offset") != -1) {   

            uri = uri.substring(0, uri.lastIndexOf("=") + 1);   

            return uri;   

        String queryString = uri.substring(n + 1, uri.length());  

        String suburi = uri.substring(0, n + 1);   

        String[] strings = queryString.split("&");   

        for (int i = 0; i < strings.length; i++) {   

            if (strings[i].startsWith("pager_offset")) {   

                continue;   

            }   

            suburi += strings[i];   

            suburi += "&pager_offset=";   

        }  

        return suburi;   

    }

}

PagerOffset.java

 * 得到目前的頁碼  

public class PagerOffset implements TemplateMethodModel {   

    public Object exec(List args) throws TemplateModelException {  

        String[] string = uri.split("pager_offset=");   

        if (string.length == 1) {   

            return 1;   

        } else {   

            Integer pager_offset = 1;   

            try {   

                pager_offset = Integer.parseInt(string[1]);   

            } catch (NumberFormatException e) {   

                pager_offset = 1;   

            return pager_offset;   

              * FreeMarker作為視圖元件是由Servlet負責加載該模闆,并使用資料模型填充該模闆,并且将填充後

                     的标準HTML響應輸出給浏覽者.

              * 在Struts2架構的支援下,Struts2架構充當了之前的Servlet角色.

              * 為了使所有的使用者請求都經過Struts2架構處理,我們将所有的FreeMarker模闆放在WEB-INF/ftl路徑下.

              * 放在WEB-INF/路徑下可以提供更好的安全性,因為Web容器會保證浏覽者無法通路到WEB-INF/路徑下的資源.       

                     1>.FreeMarker模闆内建的變量

                     2>.ValueStack中的變量.

                     3>.ActionContext中的變量.

                     4>.HttpServletRequest範圍的屬性.

                     5>.HttpSession範圍的屬性.

                     6>.ServletContext範圍的屬性.

                     stack:代表ValueStack本身,可這樣通路其中變量:${stack.findString('ognl expr')}

                     action:代表剛剛執行過的Action執行個體.

                     response:代表HttpServletResponse執行個體.

                     request:代表HttpServletRequest執行個體.

                     res:代表HttpServletRequest執行個體.

                     session:代表HttpSession執行個體.

                     application:代表ServletContext執行個體.

                     base:代表使用者請求的上下文路徑.

                     <#if Application.attributeName?exists>

                            ${Application.attributeName}

                     使用struts2标簽輸出:<@s.property value="%{Application.attributeName}"/>

                     <#if Parameter.parameter?exists>

                            ${Parameter.parameter}

繼續閱讀