1. 程式人生 > >Web前端:FreeMarker技術指南

Web前端:FreeMarker技術指南

一、什麼是模板引擎,為什麼要用模板引擎

B/S程式設計中,常常有美工和程式設計師二個角色,他們具有不同專業技能:美工專注於表現——建立頁面、風格、佈局、效果等等可視元素;而程式設計師則忙於建立程式的商業流程,生成設計頁面要顯示的資料等等。

很多時候,要顯示的資料在設計的時候並不存在,它們一般是在執行時由程式產生的,比如執行價格不高於800NTUSB Disk”查詢的返回結果。這種技術需求產生了JSPScriptletJSP十分強大,但是也常常被濫用,並導致一些不良的後果

  1. 將邏輯和表現混合在一起。
  2. 破壞了美工和程式設計師職責的正常分解。
  3. 使JSP頁面難以閱讀和維護。

模板引擎就是為了解決上面的問題而產生的。在設計

HTML的時候,我們加入一些特定指令來指定要插入哪些資料,這些加了特殊指令的HTML或者其他文字,我們稱為模板(Template)。而模板引擎會在輸出頁面時,用適當的資料替代這些程式碼。

模板和嵌入JSPHTML是不同的,模板指令只有很有限的程式設計能力,可以避免混入商業邏輯。

二、Java常用的模板引擎 Velocity vs FreeMarker

1.Velocity FreeMarker簡單好學

2.FreeMarker Velocity功能強大

三、一個簡單的FreeMarkerDemo

1.匯入Jar包:

FreeMarker需要freemarker-2.3.19.jar

包,Struts2裡面有這個Jar包。

2.編寫模板檔案

FreeMarker的模板檔案的字尾名是ftl。這裡是我寫的一個Example.ftl,我把它放在WebRoot下的Template資料夾下。

<html> <head> <title>Example</title> </head> <body > <h1>大家好,我的名字叫${name},我家住在${address},我今年${age}歲了!</h1> </body> </html>

3.模板的解析

模板需要被解析之後才能生成最終的檔案,

FreeMarker的資料模型也是在模板中配置的。

ExampleResolution.java

publicclass ExampleResolution { publicvoid resolution(){ Writer out = null; Configuration cfg = new Configuration(); cfg.setServletContextForTemp<wbr>lateLoading(ServletActionContext.getServletContext(),"TemplateFiles"); cfg.setDefaultEncoding("UTF-8"); Map root = newHashMap(); root.put("name","李鑫龍"); root.put("address","合肥市望江西路666號"); root.put("age", 23); try { Template template = cfg.getTemplate("Example.ftl"); String path = ServletActionContext.getServletContext().getRealPath("/"); File file = new File(path +"example.html"); out = new BufferedWriter(new OutputStreamWriter(newFileOutputStream(file))); template.process(root, out); } catch (IOException e) { e.printStackTrace(); } catch (TemplateException e) { e.printStackTrace(); }finally{ try { out.flush(); out.close(); } catch (IOException e) { e.printStackTrace(); } } } }</wbr>

4.Action配置

publicclass ServiceActionimplements Action { @Override public String execute()throws Exception { ExampleResolution er = new ExampleResolution(); er.resolution(); return Action.SUCCESS; } }

5.struts.xml配置

<packagename="default" namespace="/"extends="struts-default,json-default"> <action name="example"class="com.lubby.action.ServiceAction"> <resulttype="redirect">/example.html</result> </action> </package>

6.效果顯示

</html> <head> <title>Example</title> </head> <body > <h1>大家好,我的名字叫李鑫龍,我家住在合肥市望江西路666號,我今年23歲了!</h1> </body> </html>

四、FreeMarker的資料模型

資料模型是樹型結構,可以任意複雜和深層次,如下面的例子:

(root) | +- animals | | | +- mouse | | | | | +-size = "small" | | | | | +-price = 50 | | | +- elephant | | | | | +-size = "large" | | | | | +-price = 5000 | | | +- python | | | +- size = "medium" | | | +- price = 4999 | +- test ="It is a test" | +- whatnot | +-because = "don't know"

類似於目錄的變數稱為hashes,包含儲存下級變數的唯一的查詢名字類似於檔案的變數稱為scalars,儲存單值
scalars
儲存的值有兩種型別:字串(用引號括起,可以是單引號或雙引號)和數字(不要用引號將數字括起,這會作為字串處理)

scalars的訪問從root開始,各部分用“.”分隔,如animals.mouse.price

另外一種變數是sequences,和hashes類似,只是不使用變數名字,而使用數字索引,如下面的例子:

(root) | +- animals | | | +- (1st) | | | | | +-name = "mouse" | | | | | +-size = "small" | | | | | +-price = 50 | | | +- (2nd) | | | | | +-name = "elephant" | | | | | +-size = "large" | | | | | +-price = 5000 | | | +- (3rd) | | | +- name = "python" | | | +- size = "medium" | | | +- price = 4999 | +- whatnot | +- fruits | +- (1st)= "orange" | +- (2nd)= "banana"

這種對scalars的訪問使用索引,如animals[0].name 這種對scalars的訪問使用索引,如animals[0].name

五、模板的常用指令

FreeMarker模板中可以包括下面幾個特定部分:
1.${…}
:稱為interpolationsFreeMarker會在輸出時用實際值進行替代。

1.1 ${name}可以取得rootkeynamevalue

1.2 ${person.name}可以取得成員變數為personname屬性

2.<#…>FTL標記(FreeMarker模板語言標記):類似於HTML標記,為了與HTML標記區分

3.<@>:巨集,自定義標籤

4.註釋:包含在<#---->(而不是<!---->)之間

.常用的FTL標記:

1if指令:用於判斷的指令

  <#if (2>3)>

二比三大

    <#else>

三比二大

</#if>

2list指令:用來遍歷MapList

2.1遍歷List的資料

  <#list arrList as item>

  ${item}

  </#list>

  2.2遍歷Map的資料

<#listmyMap?keys as item>

${item}-à${myMap[item]}

</#list>

  2.3 item_has_next:判斷list是否還有值,

<#listarrList as item>

  <#if item_has_next>more,

<#else>end.

</#if>  

</#list>

2.4<#break />指令可以跳出迴圈

<#listarrList as item>

<#if!item_has_nex>end. <#break />

</#if>

more,

</#list>

3include指令:用來引入另一個另一個ftl模板或者html頁面

<#include“TemplateFiles/example.ftl”> 

4assign指令:用於為該模板頁面建立或替換一個頂層變數

變數為String  <#assign address=”上海”>

我家住在${address}

結果:我家住在上海

變數為map: <#assign person={"name":"Tom","age":20,"address":"上海"} >

我的名字叫${person.name},我今年${person.age},我家住在${person.address}

結果:我的名字叫Tom,我今年20,我家住在上海

5import指令:用於匯入FreeMarker模板中的所有變數,並將該變數放置在指定的Map物件中。

<#import "/libs/mylib.ftl"as my>

6.判斷為空: FreeMarker預設是不允許值為空或者值不存在的,否則一定會報錯。所以我們需要一些方法來判斷是否為空或者是否存在

方法一:<h1>Welcome${user!"Anonymous"}!</h1>

user為空或者不存在會預設為Anonymous.

${user!}這個當user不存在或為空時候,不會報錯,也不會輸出。

方法二:<#if name??>name is exist</#if>

這裡會先判斷,若name為空或不存在則不會執行if內部的,也不會報錯

七、內建函式:

使用方法類似於訪問雜湊的子變數,只是使用?代替.例如:${test?upper_case?html}常用的內建函式列舉如下:

?html: html字元轉義

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

?lower_case :字串的小寫形式

?upper_case :字串的大寫形式

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

?substring:截字串

?lenth: 取長度

?size: 序列中元素的個數

?int : 數字的整數部分(比如- 1.9?int 就是- 1

?replace:字串替換

一些示例:

${username?[0,10]}

${appHtml?replace('<@person.component/>', "AK47test")}

八、FreeMarker macro(巨集)的使用

1.example1.ftl 設定巨集

<#macroname >

我的名字叫做${name}!

</#macro>

2.example2.ftl 呼叫example1.ftl的巨集

<#inclue“example1.ftl”>

<#macroname=”王曉樂”></#macro>

最終可以在example2.ftl模板生成的頁面中得到

我的名字叫做王曉樂!

3.關於關於巢狀指令<#nested>

<#macrogreet>

<#nested>

<#nested>

</#macro>

呼叫:<@greet>hello!</@greet>

結果: hello!

hello!

九、利用macro簡單封裝的jqGrid的使用方法

1.macro名和引數的呼叫Demo

<@myjqgrid url="jqgridtest.action" colNameList=["來電號碼","業務型別","編號"] colModelList=[["customer","string"],["bussiness","string"],["id","int"]] caption="jqgrid測試三" width="500" height="250" divId="jqgridOne" />

2.引數的含義

url:請求的actionURL

colNameListjqGrid表所需要顯示的欄位

colModelListjqGridcolModelList中的欄位的英文名,和排序的型別

caption:表格的標題名

width:長度

height:高度

divIddivid

十、利用macro簡單封裝的highcharts的使用方法

1.macro名和引數的呼叫Demo

<@highcharts divId="container1" type="column" title="2012年氣溫變化表一" subtitle="合肥氣象局提供" yTitle="溫度 (°C)" function=" return'<b>'+ this.series.name +'</b><br/>'+ this.x +': '+ this.y+'°C';" width="500" height="300"/>

2.引數的含義

divIddivid

type:圖表的型別 / line直線 / pie餅狀 / bar橫向條狀 / column柱狀圖

title:圖表的標題

subtitle:圖表的副標題

yTitle:縱座標的標題

function:當滑鼠移到節點時,返回的資訊

width:寬度

height:高度