天天看點

beetl 1.  什麼是 Beetl 2.  基本用法 3.  進階用法 4.  Spring MVC

1.  什麼是Beetl 1

1.1.  Beetl能為你做些什麼 2

2.  基本用法 4

2.1.  Hello Beetl 4

2.2.  控制語句和占位符号 5

2.3.  定義變量 6

2.4.  算術表達式 7

2.5.  邏輯表達式 7

2.6.  循環語句 8

2.7.  條件語句 9

2.8.  函數調用 10

2.9.  格式化 10

2.10.  直接調用class 方法和屬性 10

2.11.  錯誤處理 11

2.12.  安全輸出 12

2.13.  其他瑣碎功能 12

3.  進階用法 14

3.1.  總是使用GroupTemplate 14

3.2.  允許優化,超越其他模闆引擎 16

3.3.  自定義函數 17

3.4.  格式化函數 17

3.5.  嚴格MVC 控制 18

3.6.  虛拟屬性 18

3.7.  标簽 19

3.8.  空格處理 20

3.9.  自定義錯誤處理 21

4.  Spring MVC 21

4.1.  配置ViewResolver 21

4.2.  模闆中擷取參數 22

1.  什麼是 Beetl

Beetl 是 Bee Template language , Bee 譯為忙碌的人,意指忙碌中國的開發人員。目前版本 1. 1 beta,大小約3 00 K5 它具有如下特性:

1  非常簡單 :它的文法是 javascript 一個子集,隻有少量的大家熟悉的符号。任何了解 java ,或者 javascript 的人,都能快速學會。如果從未用過任何模闆語言,用 Beetl 是非常很合适的

2  功能齊全: beetl具有目前流行的模闆引擎所支援的功能,如具備freemarker 所提供的絕大部分功能

3   性能卓越 : 在優化模式下運作, 每秒渲染模闆數高于其他模闆引擎,而消耗的系統資源低于其他模闆引擎。

4   提供一系列其他模闆語言沒有提供的功能 ,如自定義占位符号,控制語句符号,虛拟屬性,自定義函數,标簽 tag等, 安全輸出等。 它們并不複雜,但有可能解決你在使用别的模闆語言時候遇到的一些不便捷的問題。

5   同時支援較為松散的 MVC 和嚴格的 MVC ,如果在模闆語言裡嵌入計算表達式,複雜條件表達式,以及函數調用有幹涉業務邏輯嫌疑,你可以禁止使用這些文法。關于這一點,可以參考 strictly enforces model-view separation

6 能與Spring MVC 和 Struts2結合起來

1.1.  Beetl 能為你做些什麼

作為模闆語言,你可以用于任何适合在 MVC 的地方。如 代碼生成 ,或者 web 界面 ,

因為 Beetl 是基于 antlr 實作文法解析的,是以如果你僅僅對 antlr 感興趣, beetl 仍然可以作為你的一個重要參考

關于 Beetl 性能 :

Beetl 目前渲染一個 7K 檔案,内含少量控制語句和占位符,所需要時間是 1 毫秒,這是在我一個四年前的老機器上跑得,作為代碼生成,你完全無需擔心性能。

Beetl(runtime,) Freemarker(2.3.1.8) Beetl 1.0(使用優化模式) Velocity
7K ( 1000 次) 1050 790   560

注:優化模式即将模闆編譯成 class,目前測試性能表明性能高于freemarker,消費的系統資源低于freemarkder。

關于功能:

http://freemarker.sourceforge.net/fmVsVel.html   是一篇freemaker與velocity功能比較的文章,很幸運 Beetl能以簡單易學,更易擴充的方式支援所有功能 。  

下表是以此文章為基礎做的比較

功能點 Beetl Freemarker velocity
Number and date suppor t yes yes no
Internationalization: Yes,但不支援中文變量名 yes no
Loop handling: Ye s yes no
Array handling on the template language level yes yes no
Macros Yes Yes no
Name-spaces: No yes no
Java-independent string, list, and map manipulations with built-in functions/operators: yes yes no
Expose typos and other mistakes in template Yes, better yes no
Advanced rendering control: yes yes no
Literals: yes yes no
Advanced white-space removal No ,beetl不需要此額外功能 yes no
Integration with other technologies: yes yes yes
Powerful XML transformation capabilities: no yes no
Advanced template metaprogramming: No,不明白為啥有此需求 yes no
function No,覺得模闆不需要 yes No
自定義控制語句 yes no no
自定義占位符号 yes no no
嚴格MVC控制 yes no no
虛拟屬性 yes no no
文本處理函數 yes yes no
自定以錯誤處理 Hanlder yes no no

2.  基本用法

2.1.  Hello Beetl

package   org.bee.tl.samples;

import   java.io.IOException;

import   org.bee.tl.core.BeeTemplate;

public   class   HelloBeetl {

    public   static   void   main(String[] args) throws   IOException {

      Template template = new   BeeTemplate( "Hello, ${ name } " );// 1

      template.set( "name" , "Beetl" );//2

      String result = template.getTextAsString();//3

      System. out .println(result);

   }

}

1   用于 BeeTemplate 建立一個模闆,此時使用的是一個字元串輸入 , 輸入也可以是 java.io.File 或者java.io.reader. 對于 beetl 來說,如果輸入是檔案,那将會緩存中間的解析結果而大幅度提升性能

2   定義變量, set 方法允許字元串 , 對象作為參數,如果需要引用對象的屬性,則用小數點,如 $user.name$, 如果屬性是個 List 集合,可以用 [ 索引 ], 如 $user.friends[0]$, 如果屬性是 Map 集合,

  使用 [key],key 為任何對象,如 $books[‘thinking in java’].author$

3   調用 template.getTextAsString()   或者 template.getText(OutputStream os) 都可以獲得模闆渲染的結果

2.2.  控制語句和占位符号

Beetl 預設情況下,采用 <% 作為控制語句開始, %> 作為控制語句結束

<%  for(user in userList){  %>

hello,$ { user.name }

<% } %>

預設情況下,占位符号使用 " $ {" 作為開始和 "}" 結尾占位符号

$ { users[index] }

然而, Beetl 支援自定義控制語句和占位符号,以适應不同類型模闆檔案,如果有你喜歡的風格,譬如 jsp類似的, 則可以采用如下定義

public static void main(String[] args) {

  String input = ”…..”

      Template template =new BeeTemplate(input);

      template.setStatementStart("<%");

      template.setStatementEnd("%>");

      template.setPlaceholderStart(" ${ ");

      template.setPlaceholderStart(" } ");

      template.getTextAsString(); 

     //   或者可以直接調用 

      //template.config("<%","%>","${","}");

}

此代碼可以解析如下模闆檔案  

<% var name=”lijz”; 

var greeting = “morning”;

%>

Hello  ${ name }   ${ greeting~ }

以下内容如果不做特殊說明,控制語句使用 <% %> 和占位符号采用 ${}

2.3.    定義變量

Beetl 允許定義變量,準确的說, 允許定義臨時變量 (在模闆頁面,使用臨時變量并不值得推薦,但Beetl能支援),如下所示

<% var name= ' lijz ', loopCount=100 +other  ,girlName %>

關鍵字 var 是必須的,這點不同于 javascript

Beelt 中得變量同 javascript 一樣,有自己的作用域,如下模闆輸出為 ”lucy”

<% var name=’lijz’,i=1;  %>

<% if(i>=1) { %>

  <% var name= ' lucy ' ; %>

  Hello, $ { name }

<%}%>

 Beetl  支援定義 Json 變量,雖然此功能并不是很實用,推薦複雜的資料結構,還是要再控制層設定比較好

<%  var usersList=[{“name”:”lijz”,”age”:18},{“name”:”lucy”,”age”:16}]; %>

她得名字是  $ { userList[1][“name”] }

變量命名規則同javascript或者 java ,但不允許以倆個下劃線開頭 "__", 這是因為以此開頭的多為 Beetl 内部的一些臨時變量

2.4.  算術表達式

Beetl支援類似 javascript 的算術表達式和條件表達式,如 + - * / %  以及(),如下例子

<% :var a=1,b=2,c=3;  %>

the result is $ { (a+b)*c-0.75 }

注:算數表達式無需擔心計算精度問題,beetl底層用BigDecimal實作。

2.5.  邏輯表達式

Beetl支援類似 Javascript,java 的條件表達式 如 > ,  < ,  ==  , != , >= , <=  以及  !, 如下例子

<%  var a=1,b=2,c=3;if((b-c)>=1){  %>

Hello big!

<% }else{ %>

:( ,small!

<% } %>

2.6.  循環語句

Beetl 支援 for in  循環格式,以及 break , continue , return ( 實際上可以出現在任何地方 ) ,如下例子

//java代碼

tempalte.set("userList",userList);

//模闆

總共  ${ userList.~ size }

<% for(user in userList){ %>

$ { user _ index }  . Welcome $ { user.name } !

<% } %>

  循環中可以使用數組, List  或者  Map 的子類,當使用 Map 子類的時候,如下例子  

<%  var softMap={'beetl':'very good ','freemarker':'very good!'}; %>

Compare the $ { softMap~size }  soft ware as follows

<% for(soft in softMap){ %>

$ { soft _index} /  $ { soft _szie}  . $ { soft.key }  is $ { soft.value }

<% } %>

key  既是 Map 裡的 key 值

value  既是 Map 裡的 Value 

如果循環中,需要引用目前索引 , 變量名加上字尾“_index”,代表目前循環的計數器,從0開始。在循環體裡還可以變量名加上後最 _size表示長度

2.7.  條件語句

Beetl  支援 同 javascript , java 一樣的 if  語句,和  switch.  如下例子

<% var isGirl = true; %>

<% if(isGir){ %>

姑娘,你好

<% }else{ %>

小夥子,你好

<% } %>

Switch  和  case   可以使用任何表達式,下列中, switch  将變量 score 與 case  中得各個常量比較,如果沒有找到,則執行 default

<% var score = 1; %>

<% switch(score){ %>

<% case 1:{ %>

Get 1 score!

<% break; }%>

<% default:{ %>

Default here

<% }

}%>

2.8.  函數調用

Beetl内置了少量實用函數,可以在 Beetl 任何地方調用,一般情況是在占位符裡調用。

如下例子是調用 date  函數,不傳參數情況下,傳回目前日期

Today   is $ {date()}

  Beetl允許使用者自定義函數以适合特定領域使用,請參考進階用法。也歡迎有人把他認為能公用的函數發給我,我将作為核心函數放入 beetl 裡  

2.9.  格式化

幾乎所有的模闆語言都支援格式化, Beetl 也不列外,如下例子 Beetl 提供的内置日期格式

<% var date = now();  %>

Today is $ { date, dateFormat ="yyyy-MM-dd" } .

Today is $date, dateFormat $

如果沒有為格式化函數輸入參數,則使用預設值, dateFormat 格式化函數預設值是 local

Beetl允許使用者自定義格式化函數以适合特定領域,請參考進階使用者,也歡迎有人把他認為能公用的格式化函數發給我,我将作為核心函數放入 beetl 裡

2.10.    直接調用 class方法和屬性

預設情況,是不允許直接調用對象的方法的,必須先調用groupTemplate. enableNativeCall();

[email protected](“lucy”)$ 

[email protected] n d$ 

[email protected]()$ 

[email protected]_NUM$

可以調用 instance的public方法和屬性,也可以調用靜态類的屬性和方法   ,需要加一個@訓示此調用是直接調用class

2.11.  錯誤處理

Beetl預設情況使用 org.bee.tl.core.DefaultErrorHandler  來處理文法解析錯誤和運作時刻的錯誤,預設情況下,會顯示如下資訊

l  錯誤行号

l  錯誤原因以及異常棧

l  錯誤的關鍵字

l  以及錯誤上下 3行

如下所示

  Template t = new BeeTemplate(" <% :if(!isGirl){var c=1;} %> "); 

 //使用嚴格MVC限制,是以不允許變量定義 

  t.makeStrict(true);  

  t.set("isGirl", false);  

  t.getTextAsString() ;  

  會導緻如下編譯錯誤  

  STRICK_MVC  位于 1 行,符号  var  

  1| <% if(!isGirl){var c=1;}  %>

  關于如何自定義錯誤處理,請參考進階用法

2.12.  安全輸出

Beetl允許占位符在有可能抛錯的情況下忽略此錯誤,使用 !(  )  訓示括号裡的代碼如果出錯,系統将忽略此錯誤

比如 

${!(user.wife,name)}

如果user 的 wife 屬性為空,則将抛出空指針異常,如果使用安全輸出訓示,則系統忽略此異常。如下是預編譯後的代碼

 try{

    out.write(user.getWife().getName());

   }catch(Exception ex){

  }

注意,針對空值得情況,建議使用空值政策,參考(2.13 )

${user.wife,name!"N/A"}

如下是空值政策預編譯後的代碼

if(user!=null&&user.getWife()!=null){ 

     out.write(user.getWife().get Name ()); 

 }else{ 

       out.write("N/A"); 

}

2.13.  其他瑣碎功能

對齊:  我發現别的模闆語言要是做到對齊,非常困難 ,Beetl 你完全不用擔心,比如 velocty , stringtemlate ,freemarker 例子都出現了不對齊的情況,影響了美觀, Beetl 完全無需擔心輸出對齊

包含其他模闆檔案 :在 Beetl 中,這不是一個特殊的功能,通過調用函數 includeFT, 或者 includeST 都可以實作,前者是包含一個檔案模闆,後者是将一個 string 模闆作為輸入。詳細使用請參考進階用法

Escape :可以使用\ 做escape 符号,如\$monkey\$ 将作為一個普通的文本,輸出為$monkey$.再如為了在錢後加上美元符号(占位符恰好又是美元符号)可以用這倆種方式hello,it's

$money$\$, 或者Hello,it's $money+"\$"$ 。如果要輸出\符号本生,則需要用倆個\\,這點與 javascript,java 語義一緻.  

空值政策:  如果一個變量為空,則輸出的時候預設為空字元串,也可以制定輸出

$ { u. wife.name!"N/A"}

如果 u 為空,或者u.wife為空,輸出都是"N/A"

标簽: 類似 jsp的标簽Tag, 允許你将模闆檔案中的一段檔案内容作為輸入,經過函數操作,變成特定的輸出,如下标簽replaceProperties

<% replaceProperties( ip,port ) {  %>

Server_ip= 127.0.0.1

Server_port= 8080

<% } %>  

<% if(isProduct) { delNext(){  %>

Debug_para1=.....

Debug_para2=......

<% } %>

第一個例子中,如果在 java 代碼中, tempalte.set("ip",targetIP),template.set("port",targetPort);

則模闆檔案裡等于号後的字元串将被以此替換 .

第二個例子,如果在 java 代碼中, template.set("isProduct",true), 則所有 debug 參數都将被删除。關于标簽的概念,請參考進階用法

表達式計算:  org.bee.tl.core . SimpleRuleEval  . 擴充了BeeTemplate , 可以用來計算表達式 ,如下代碼

SimpleRuleEval eval = new SimpleRuleEval("b+15");

eval.set("a", 3);

int  o = eval.calc Int ();

此時 o 為  18

表達式可以是任何計算表達式或者條件表達式,如(12+5)*3,或者 a>12&&a<=18

  其他方法還有

calc()傳回Object,(對于算數計算,Object為BeeNumber類型) 

calcInt() 傳回Int 

calcBoolean() 傳回boolean 

calcDouble() 傳回double 

其他詳細參考API

3.  進階用法

3.1.  總是使用 GroupTemplate

  無論你是在學習使用 Beetl,還是在項目中使用Beetl,好的習慣是正确初始化GroupTemplate,并通過GroupTemplate獲得Template,如下代碼

import  org.bee.tl.core.GroupTemplate;

public   class  GroupTemplateUtil {

static  GroupTemplate  group  =  new  GroupTemplate( "/home/template" );

static  {

group .setPlaceholderStart( "<%" );

group . setPlaceholderEnd ( "%>" );

group .setStatementStart( "${" );

group .setStatementEnd( "}" );

group .enableOptimize();  //1

group .enableNativeCall();  //2

group .enableChecker(10);  //3

addCommonFunction ();  //4

addCommonFormat ();  //5

}

public   static  GroupTemplate getGroup (){

return   group ;

}

public   static   void  addCommonFunction(){

}

public   static   void  addCommonFormat(){

}

}

  1. 允許優化成class代碼運作

 2 運作直接調用java類

 3 每10秒檢查一下模闆檔案是否更新

 4 增加項目自定義方法

 5 增加項目自定義的格式化函數

然後你可以在代碼裡調用

Template t = GroupTemplateUtil  .getGroup

() .getFileTemplate( "/exp/string_add_template.html" );

T.set("user",new User());

String str = t.getTextAsString();

3.2.  允許優化,超越其他模闆引擎

  預設情況下, Beetl采用解釋執行,性能略低于其他模闆語言,且同其他模闆語言一樣,消耗了較大的系統資源。Beetl1.0版本後可以在運作時預編譯成class,獲得最好的性能

需要調用groupTemplate .enableOptimize();

預設情況下,是以預編譯的類都将放在 user.home的.bee目錄下,如下示例

目前并不是所有的模闆都能優化成class代碼。請參考代碼優化了解如何編寫模闆代碼。但無論如何,如果優化失敗,beetls将會解釋執行。

3.3.  自定義函數

 Beetl 允許提供自定義函數以适合特定業務需求,自定義函數需要實作 org.bee.tl.core.Function 。如下定義了一個now 函數僅僅傳回一個 java.util.Date 執行個體

public   class   DateFunction  implements   Function {

       public   Date  call(Object... paras) {

             return   new   Date();

      }     

       public    static   void   main(String[] args)  throws   IOException{

            GroupTemplate group =  new   GroupTemplate();

            group.registerFunction( "now" ,  new   DateFunction());

            Template t = group.getStringTemplate( "today is $now()$" );

            System. out .println(t.getTextAsString());

      }

}

注冊的方法名可以帶".",如下

group.registerFunction("date.now", new DateFunction());則在模闆裡,可以使用today is

${date.now()}.

3.4.  格式化函數

 Beetl 允許提供自定義格式化函數,用于格式化輸出。   格式化函數需要實作 org.bee.tl.core.Format

public   class   DateFormat  extends   Format  {

       public   Object format(Object data,String pattern){

            SimpleDateFormat sdf =  null ;

             if (pattern== null ){

                  sdf =  new   SimpleDateFormat();

            } else {

                  sdf =  new   SimpleDateFormat(pattern);

            }

             return   sdf.format(data);

      }

       public   static   void   main(String[] args) throws   IOException {

            GroupTemplate group =  new   GroupTemplate();

            group.registerFunction( "now" ,  new   DateFunction());

            group.registerFormat( "df" ,  new   DateFormat());

            Template t = group.getStringTemplate( "today is $now(),df=’yyyy-MM-dd’$" );     

            System. out .println(t.getTextAsString());

      }

}

其中,也可以直接用today is ${now(),shortDate}   如果沒有=号,format(Object data, String pattern) 中的pattern 為空

注冊的格式化函數名可以帶".",如下:

group.registerFormat("date.short", new DateFormat());則在模闆裡,可以使用today is  ${now(),date.short}.

3.5.  嚴格MVC 控制

  如果設定了嚴格 MVC ,則以下文法将不在模闆檔案裡允許,否則将報出 STRICK_MVC  錯誤

定義變量,為變量指派

算術表達式

除了隻允許布爾以外,不允許邏輯表達式和方法調用

Class方法和屬性調用

如果你嗜好嚴格 MVC,可以調用groupTemplate . enableStrict ( )

3.6.  虛拟屬性

無需為 java 對象定義額外的屬性用于輔助顯示,虛拟屬性可以輕易做到,如 Beetl 為 java.util.Collection  定義的一個虛拟屬性 size ,用于表示集合大小

group .registerVirtualAttributeEval( new   VirtualAttributeEval(){

       public   Object eval(Object o,String attributeName,Context ctx){

             if (attributeName.equals( "size" )){

                   return   (( Collection )o).size();

            } else {

                   throw   new   IllegalArgumentException();

            }

      }

       public   boolean   isSuppoert( Class  c,String attributeName){

                          if (Collection. class.isAssignableFrom(c)&&attributeName.equals( "size" )){

                   return   true ;

           } else {

                   return   false ;

            }

      }

});

這樣,是以 Collection 子類都有虛拟屬性 size 。 $userList.~size$  輸出 userList 集合長度

實作虛拟屬性,必須實作接口倆個方法,一個是 isSupport, 這讓 Beetl 用于找到 VirtualAttributeEval , eval 方法用于計算虛拟屬性

3.7.  标簽

所謂标簽,即允許處理模闆檔案裡的一塊内容,功能等于同 jsp tag。 如下 {} 的内容在 beetl 運作的時候将會被删除

<% del(){ %>

This content will be deleted 

<% } %>

自定義标簽 org.bee.tl.core.T ag ,需要實作 requriedInput ,用于告訴 Beetl ,是否需要先渲染文本體。

setInput 是把渲染的結果傳回給标簽函數

getOutput  最後 用于傳回文本處理函數的結果

如下是 Beetl 提供的内置的 del 文本處理函數實作

public   class   DeleteFunction  extends   Tag {

       public   String getOutput(){

             return   "" ;

      }     

       @Override

       public    boolean   requriedInput(){

             return   false ;

      }

}

可以通過父類屬性 args, 擷取輸入參數,詳細可以參考 API

3.8.  空格處理

大多數模闆語言都會輸出額外的空格或者回車, JSP也如此,freemaker還專門有一删除多餘空格的函數, 在beetl中,是不需要此功能的

上圖來源于南磊翻譯的中文版Freemarker,說是以上代碼會有過多的換行(br),必須使用删除多餘空行函數才能使模闆輸出達到我 們想得樣子。Beetl沒有此額外函數做這事情,因為Beetl自動就能分辨出這些額外空行。 

為什麼beetl無需擔心額外空行呢,其實很簡單,beetl碰到隻有beetl語句的行,無論是前有空格還是後有回車,都會忽略的,看過beetl 在優化模式下生成的class代碼就很容易能看出來。 

3.9.  自定義錯誤處理

groupTemplate. .setErrorHandler(h) 用于設定你自定義的錯誤處理,譬如,預設情況下,錯誤處理會顯示錯誤所在行,錯誤原因,以及模闆上下 3行的内容,如果你不希望客戶看到你的模闆内容,你可以自定義錯誤處理, 請參考 org.bee.tl.core . DefaultErrorHandler

4.  Spring MVC

4.1.  配置 ViewResolver

為了能在Spring MVC中使用Beetl,必須配置ViewResolver,如下

  < bean   id = "beetlConfig"   class ="org.bee.tl.ext.spring.BeetlGroupUtilConfiguration"   init-method ="init" >

< property   name = "root"   value = "/" />

< property   name = "optimize"   value = "true" />

< property   name = "nativeCall"   value = "true" />

< property   name = "check"   value = "2" />

</ bean >

< bean   id = "viewResolver"   class ="org.bee.tl.ext.spring.BeetlSpringViewResolver" >

</ bean >

Root屬性告訴Beetl 模闆檔案未WebRoot的哪個目錄下,通常是/ ,預設是/

optimize 屬性允許優化,預編譯成class。預設是true

nativeCall 運作本地調用,預設是true

check 是每隔多少秒檢測一下檔案是否改變,設定較短時間有利于開發,線上上環境,設定為0,則不檢查模闆更新,預設是2秒

其他屬性還有

tempFolder:預編譯生成的源檔案以及class的位置,預設是WebRoot/WEB-INF/.temp 目錄下

占位符指定:statementStart,statementEnd,placeholderStart,placeholderEnd  預設分别是 <% %> ${ }

4.2.  模闆中擷取參數

在 Spring MVC中,任何在 ModelMap 中的變量都可以直接在 Beetl 中引用,在 Session 中的變量,需要使用session[" 變量名 "]

如下 HelloWorldController  代碼

@Controller

@SessionAttributes ( "currUser" ) 

public   class   HelloWorldController  {

@RequestMapping ( "/hello" )

public  ModelAndView helloWorld(ModelMap model ) {

String message =  "Hello World, Spring 3.0!" ;

model.addAttribute( "name" , "joel" );

model.addAttribute( "currUser" , "libear" );

return   new  ModelAndView( "/hello.html" ,  "message" , message);

}

}

則在模闆中,通路name,message,currUser分别采用如下方式

${name},${message},${session["currUser"]}

@RequestMapping(value = "demo1",method=RequestMethod.GET) public ModelAndView test1(HttpServletRequest request,@ModelAttribute PageData pageData){ ModelAndView mav = new ModelAndView(); mav.setViewName("demo"); mav.addObject("key","beetlvalue"); List list = comEmployeeService.getModelList(new ComEmployee(), null); mav.addObject("lists", list); comEmployeeService.getPageDataModelList(ComEmployee.class,pageData); return mav; } 以下是模版的簡單文法..... 累積 【${pageData.totalCount!}】條資料 ${key!} list循環

<% for(user in pageData.dataList!){ if(userLP.index == 10) break; %>

name:${user.userNick} ==== index:${userLP.index} === 檢視 ===== 添加 ===== 删除

<%}%>

  <% var userList=[{name:'lijz',age:18},{name:'lucy',age:16}]; var map={"001":{name:'lijz'},"002":{name:'lucy'}}; print("list:總共"+userList.~size+"

"); for(user in userList){ %> ${userLP.index} ${user.name}

<%}%> <% print("map總共"+map.~size+"

"); for(user in map){ %> ${userLP.index} ${user.key} ${user.value.name}

<%}%> 控制判斷 <% for(user in userList){ if(user.age==18){ print("it's lijz'"); continue; }else if(user.age==16){ print("It's lucy"); break; }else{ print("return "); return ; } } print("end loop"); %>

elsefor <% for(user in userList){ print(user.name); }elsefor { print("no data"); } %>

if else <% var user = map["001"]; if(user.name=="lijz"){ print(user.name); }else{ return ; } %>

nvl ${nvl(userList,"Beetl")}

exist <% print(exist("session")+" "); print(exist("user")+" "); %>

debug <% //debug("僅僅在背景列印,前台什麼都沒有"); %>

print <% print("hello"); println("hello"); printf("hello,%s,your age is %s","lijz",12+""); %>

numberFormat <% var number = 12.7893; %> number=${number,numberFormat='#.##'} or number=${number,'#.##'}

定義變量 <% var number = 1 ; var str = "hello"; var now = date(); var isChecked = true; var nullValue = null; %> number is ${number},str is ${str},time is ${now} ${isChecked} nullValue=${nullValue}.

多個臨時變量 <% var number = 1 ,str="hello",now = date(); %> number is ${number},str is ${str},time is ${now}

屬性引用: <% var user = {name:'lijz',wife:{name:'lucy',age:17}}; var map = {key1:'value1',key2:'value2'} ; %> ${user.wife.name}

推薦 ${map["key1"]} <% var bigNumber = 7777777777777.23; var templateVar = { %> big number is ${bigNumber} <%};%> 現在輸出模闆變量: ${templateVar}

isEmpty <% var str1 = null; %> ${isEmpty(str1)}

<% var now = date(); var date = date("2013-1-1","yyyy-MM-dd"); %> now=${now,dateFormat='yyyy年MM月dd日'} date=${date,dateFormat='yyyy年MM月dd日'} or now=${now,'yyyy年MM月dd日'} list循環

size:${lists.~size!}

<% for(user in lists!){ if(userLP.index == 10) break; %> name:${user.userName} ==== index:${userLP.index}

<%}%>

bodyValue: