posts - 19, comments - 53, trackbacks - 0, articles - 283
            BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

          FreeMarke開(kāi)發(fā)指南

          Posted on 2009-08-19 18:16 Gavin.lee 閱讀(523) 評(píng)論(0)  編輯  收藏 所屬分類: FreeMarker

          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一些常用方法或注意事項(xiàng)
          表達(dá)式轉(zhuǎn)換類
          數(shù)字循環(huán)
          對(duì)浮點(diǎn)取整數(shù)
          給變量默認(rèn)值
          判斷對(duì)象是不是null
          常用格式化日期
          添加全局共享變量數(shù)據(jù)模型
          直接調(diào)用java對(duì)象的方法
          字符串處理(內(nèi)置方法)
          在模板里對(duì)sequences和hashes初始化
          注釋標(biāo)志
          sequences內(nèi)置方法
          hashes內(nèi)置方法
          4 freemarker在web開(kāi)發(fā)中注意事項(xiàng)
          web中常用的幾個(gè)對(duì)象
          view中值的搜索順序
          在模板里ftl里使用標(biāo)簽
          如何初始化共享變量
          與webwork整合配置
          5高級(jí)方法
          自定義方法
          自定義 Transforms

          1概念
          最常用的3個(gè)概念
          sequence  序列,對(duì)應(yīng)java里的list、數(shù)組等非鍵值對(duì)的集合
          hash      鍵值對(duì)的集合
          namespace 對(duì)一個(gè)ftl文件的引用,利用這個(gè)名字可以訪問(wèn)到該ftl文件的資源

          2指令
          if, else, elseif
          語(yǔ)法
          <#if condition>
            ...
          <#elseif condition2>
            ...
          <#elseif condition3>
            ...
          <#else>
            ...
          </#if>

          switch, case, default, break
          語(yǔ)法
          <#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>
          數(shù)字
          <#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
          語(yǔ)法
          <#list sequence as item>
          ...
          <#if item = "spring"><#break></#if>
          ...
          </#list>
          關(guān)鍵字
          item_index:是list當(dāng)前值的下標(biāo)
          item_has_next:判斷l(xiāng)ist是否還有值

          用例
          <#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
          語(yǔ)法
          <#include filename>
          or
          <#include filename options>
          options包含兩個(gè)屬性
          encoding=”GBK” 編碼格式
          parse=true 是否作為ftl語(yǔ)法解析,默認(rèn)是true,false就是以文本方式引入.注意在ftl文件里布爾值都是直接賦值的如parse=true,而不是parse=”true”
          用例
          /common/copyright.ftl包含內(nèi)容
          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”>
          輸出結(jié)果
          <h1>Some test</h1>
          <p>Yeah.
          <hr>
          Copyright 2001-2002 Juila Smith
          All rights reserved.

          import
          語(yǔ)法
          <#import path as hash>
          類似于java里的import,它導(dǎo)入文件,然后就可以在當(dāng)前文件里使用被導(dǎo)入文件里的宏組件

          用例

          假設(shè)mylib.ftl里定義了宏copyright那么我們?cè)谄渌0屙?yè)面里可以這樣使用
          <#import "/libs/mylib.ftl" as my>

          <@my.copyright date="1999-2002"/>

          "my"在freemarker里被稱作namespace

          compress
          語(yǔ)法
          <#compress>
            ...
          </#compress>
          用來(lái)壓縮空白空間和空白的行
          用例
          <#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
          語(yǔ)法
          <#escape identifier as expression>
            ...
            <#noescape>...</#noescape>
            ...
          </#escape>
          用例
          主要使用在相似的字符串變量輸出,比如某一個(gè)模塊的所有字符串輸出都必須是html安全的,這個(gè)時(shí)候就可以使用該表達(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
          語(yǔ)法
          <#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 賦予一個(gè)變量bgColor,下面可以通過(guò)my.bgColor來(lái)訪問(wèn)這個(gè)變量
          <#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

          同時(shí)也支持中文賦值,如:
          <#assign 語(yǔ)法>
            java
          </#assign>
          ${語(yǔ)法}
          打印輸出:
          java
          global
          語(yǔ)法
          <#global name=value>
          or
          <#global name1=value1 name2=value2 ... nameN=valueN>
          or
          <#global name>
            capture this
          </#global>

          全局賦值語(yǔ)法,利用這個(gè)語(yǔ)法給變量賦值,那么這個(gè)變量在所有的namespace中是可見(jiàn)的,如果這個(gè)變量被當(dāng)前的assign語(yǔ)法覆蓋 如<#global x=2> <#assign x=1> 在當(dāng)前頁(yè)面里x=2將被隱藏,或者通過(guò)${.global.x}來(lái)訪問(wèn)

          setting
          語(yǔ)法
          <#setting name=value>
          用來(lái)設(shè)置整個(gè)系統(tǒng)的一個(gè)環(huán)境
          locale
          number_format
          boolean_format
          date_format, time_format, datetime_format
          time_zone
          classic_compatible
          用例
          假如當(dāng)前是匈牙利的設(shè)置,然后修改成美國(guó)
          ${1.2}
          <#setting locale="en_US">
          ${1.2}
          輸出
          1,2
          1.2
          因?yàn)樾傺览遣捎?#8220;,”作為十進(jìn)制的分隔符,美國(guó)是用“.”

           

          macro, nested, return
          語(yǔ)法

          <#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
          定義循環(huán)輸出的宏
          <#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"/>
          輸出結(jié)果
          <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>
          </@repeat>
          輸出
          1. 0.5
            2. 1
            3. 1.5
            4. 2 Last!

           


          t, lt, rt
          語(yǔ)法
          <#t> 去掉左右空白和回車換行

          <#lt>去掉左邊空白和回車換行

          <#rt>去掉右邊空白和回車換行

          <#nt>取消上面的效果


          3一些常用方法或注意事項(xiàng)


          表達(dá)式轉(zhuǎn)換類
          ${expression}計(jì)算expression并輸出
          #{ expression }數(shù)字計(jì)算#{ expression ;format}安格式輸出數(shù)字format為M和m
          M表示小數(shù)點(diǎn)后最多的位數(shù),m表示小數(shù)點(diǎn)后最少的位數(shù)如#{121.2322;m2M2}輸出121.23

           
          數(shù)字循環(huán)
          1..5 表示從1到5,原型number..number

          對(duì)浮點(diǎn)取整數(shù)
          ${123.23?int} 輸出123

          給變量默認(rèn)值
          ${var?default(“hello world<br>”)?html}如果var is null那么將會(huì)被hello world<br>替代

          判斷對(duì)象是不是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ù)模型
          在代碼里的實(shí)現(xiàn)
              cfg = Configuration.getDefaultConfiguration();
          cfg.setSharedVariable("global", "you good");
          頁(yè)面實(shí)現(xiàn)可以通過(guò)global指令,具體查看指令里的global部分

          直接調(diào)用java對(duì)象的方法
          ${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的長(zhǎng)度
               var?word_list  效果同 var?split(“ ”)
           var?word_list?size


          取得字符串長(zhǎng)度
          var?length


          大寫輸出字符
          var?upper_case


          小寫輸出字符
          var?lower_case


          首字符大寫
          var?cap_first


          首字符小寫
          var?uncap_first


          去掉字符串前后空格
          var?trim

          每個(gè)單詞的首字符大寫
          var?capitalize


          類似String.indexof:
           “babcdabcd”?index_of(“abc”) 返回1
           “babcdabcd”?index_of(“abc”,2) 返回5

          類似String.lastIndexOf
           last_index_of和String.lastIndexOf類似,同上

          下面兩個(gè)可能在代碼生成的時(shí)候使用(在引號(hào)前加”\”)
          j_string: 在字符串引號(hào)前加”\”
           <#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: 只替換第一個(gè)出現(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.


          在模板里對(duì)sequences和hashes初始化
          sequences

          1. [“you”,”me”,”he”]
          2. 1..100
          3. [ {“Akey”:”Avalue”},{“Akey1”:”Avalue1”},
          {“Bkey”:”Bvalue”},{“Bkey1”:”Bvalue1”},
          ]


          hashes      {“you”:”a”,”me”:”b”,”he”:”c”}


          注釋標(biāo)志
          <#--
          這里是注釋
          -->
          舊版本的freemarker采用的是<#comment> 注釋 </#comment>方法

          sequences內(nèi)置方法
          sequence?first
          返回sequence的第一個(gè)值;前提條件sequence不能是null
          sequence?last
           返回sequence最后一個(gè)值
          sequence?reverse
           反轉(zhuǎn)sequence的值
          sequence?size
           返回sequence的大小
          sequence?sort
           對(duì)sequence按里面的對(duì)象toString()的結(jié)果進(jìn)行排序
          sequence?sort_by(value)
          對(duì)sequence 按里面的對(duì)象的屬性value進(jìn)行排序
          如: sequence里面放入的是10 個(gè)user對(duì)象,user對(duì)象里面包含name,age等屬性
          sequence?sort_by(name) 表示所有的user按user.name進(jìn)行排序
          hashes內(nèi)置方法
          hash?keys
           返回hash里的所有keys, 返回結(jié)果類型sequence
          hash?values
           返回hash里的所有value, 返回結(jié)果類型sequence

          4 freemarker在web開(kāi)發(fā)中注意事項(xiàng)
          freemarker與webwork整合
          web中常用的幾個(gè)對(duì)象
          Freemarker的ftl文件中直接使用內(nèi)部對(duì)象:
          ${Request ["a"]}
          ${RequestParameters["a"]}
          ${Session ["a"]}
          ${Application ["a"]}
          ${JspTaglibs ["a"]}

          與webwork整合之后 通過(guò)配置的servlet 已經(jīng)把request,session等對(duì)象置入了數(shù)據(jù)模型中
          在view中存在下面的對(duì)象
            我們可以在ftl中${req}來(lái)打印req對(duì)象
          · 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}將會(huì)以下面的順序查找name值
          · freemarker variables
          · value stack
          · request attributes
          · session attributes
          · servlet context attributes
          在模板里ftl里使用標(biāo)簽
          注意,如果標(biāo)簽的屬性值是數(shù)字,那么必須采用nubmer=123方式給屬性賦值
          JSP頁(yè)面
          <%@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頁(yè)面
          <#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上使用的時(shí)候?qū)蚕頂?shù)據(jù)的初始化支持的不夠,不能在配置初始化的時(shí)候?qū)崿F(xiàn),而必須通過(guò)ftl文件來(lái)初始化全局變量。這是不能滿主需求的,我們需要在servlet init的時(shí)候留出一個(gè)接口來(lái)初始化系統(tǒng)的共享數(shù)據(jù)
          具體到和webwork整合,因?yàn)楸旧韜ebwork提供了整合servlet,如果要增加全局共享變量,可以通過(guò)修改 com.opensymphony.webwork.views.freemarker.FreemarkerServlet來(lái)實(shí)現(xiàn),我們可以在這個(gè) servlet初始化的時(shí)候來(lái)初始化全局共享變量
          與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>
          <!—模板載入文件夾,這里相對(duì)context root,遞歸獲取該文件夾下的所有模板-->
              </init-param>
              <init-param>
                <param-name>NoCache</param-name> <!—是否對(duì)模板緩存-->
                <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>
          <!—模板更新時(shí)間,0表示每次都更新,這個(gè)適合開(kāi)發(fā)時(shí)候-->
                <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>

          5高級(jí)方法
          自定義方法
          ${timer("yyyy-MM-dd H:mm:ss", x)}
          ${timer("yyyy-MM-dd ", x)}

          在模板中除了可以通過(guò)對(duì)象來(lái)調(diào)用方法外(${object.methed(args)})也可以直接調(diào)用java實(shí)現(xiàn)的方法,java類必須實(shí)現(xiàn)接口TemplateMethodModel的方法exec(List args). 下面以把毫秒的時(shí)間轉(zhuǎn)換成按格式輸出的時(shí)間為例子
          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對(duì)象放入到數(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
          實(shí)現(xiàn)自定義的<@transform>文本或表達(dá)式</@transform>的功能,允許對(duì)中間的最終文本進(jìn)行解析轉(zhuǎn)換

          例子:實(shí)現(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() {
                  }
              }
          }
          然后將此對(duì)象put到數(shù)據(jù)模型中
          root.put("upcase", new UpperCaseTransform());

          在view(ftl)頁(yè)面中可以如下方式使用

          <@upcase>
          hello world
          </@upcase>

          打印輸出:
          HELLO WORLD

          主站蜘蛛池模板: 镇雄县| 界首市| 长丰县| 新闻| 白沙| 屯昌县| 濉溪县| 勃利县| 江陵县| 子洲县| 松江区| 闵行区| 长乐市| 双峰县| 亚东县| 龙门县| 永川市| 东明县| 丰县| 锡林浩特市| 巴马| 盘山县| 黄浦区| 本溪| 宝鸡市| 贵港市| 德惠市| 漾濞| 营山县| 鹤岗市| 遂宁市| 淮滨县| 泊头市| 钟山县| 香港 | 景宁| 星座| 信丰县| 山阳县| 固安县| 三门县|