NVelocity C#模板引擎

NVelocity是一個基於.NET的模板引擎(template engine)。它允許任何人僅僅簡單的使用模板語言(template language)來引用由.NET代碼定義的對象。從而使得界面設計人員與.NET程序開發人員基本分離。

 一、nVelocity的常用功能簡介

    1、 在頁面中定義變量,並進行簡單的運算。

    2、 在頁面中獲得對後臺程序實體對象的引用。

    3、 在頁面中迭代實體對象集合。

    4、 在頁面中獲得實體對象的屬性,及其方法。

    5、 對邏輯判斷語句的支持。

    6、 對外部文件的引用。

    7、 對外部文件的解析。

二、nVelocity的工作原理

    可以使用.NET的反射實現。以下是nVelocity對迭代實體類的簡單實現步驟:

    1、 定義People類,並擁有Name與Sex屬性。表示一個人。

    2、 在頁面中列出人物列表,則輸入以下代碼:

        #foreach($p in $ps)

          <p>歡迎您:$p.Name</p>

        #end

    3、 獲取人物列表,保存在_List中。並指定頁面中的字符串“ps”對應_List。

    4、以文本方式讀取模板文件,並匹配#foreach…#end段,如果匹配到則繼續匹配$X in $XX 段,分別記錄用於保存集合與單項的字符,本次爲“p”與“ps”。

    5 、用Type對象的GetProperties()方法獲取_list中每一項的所有屬性,並在#foreach  #end段中循環將$p + 屬性名稱替換爲當前對象的當前屬性的值。當然如果要調用對象的方法也可以用同樣的方式獲得。

三、基本語法

     1、特殊字符介紹

         A、“#”:表示開始做什麼事情。

         B、“$”:表示用於獲得什麼。(以$開頭的表示“引用”意思是取得一些東東.可引用變量,屬性,方法)

         C、“##“:單行註釋。

         D、 “#*… …*#”:多行註釋。

     2、關鍵字

          A、 Set:開始做什麼事情,比如定義變量,給變量重新賦值等。(注意:如果右邊的操作數是一個屬性或命令的引用而返回null,那麼賦值將不會成功,且在隨後的VTL中也不能再取出使用,如果要用做if條件,一個解決辦法是,先給變量賦一個值,然後再將一個屬性或命令的引用賦給該變量)

          B、 Foreach:迭代語句

          C、 If:條件判斷語句

          D、 Elseif

          E、 Else

          F、 Include:對外部文件的引用,開始位置爲模板路徑。

          G、 Parse:對外部文件的引用,並用nVelocity方式解析。

          H、 Macro:創建宏,可以重複做某件事,類似於方法。

          I、  Even:雙數執行

          J、  Odd :單數執行

          K、 Each:每次都執行

    (備註:所有變量在未定義之前不能使用(因爲我們習慣了有全局變量的習慣),一個合法的VTL標示符是以一個字母開頭的。.NET後臺定義的對象除外。模板語言區分大小寫,所有的關鍵字必須爲小寫,默認情況下,NVelocity解析是不分大小寫的,當然可以通過設置runtime.strict.math=true,採用嚴格解析模式。)

四、使用示例

    1、  在頁面中使用變量

        定義變量:#set($a = “CNF”)

        引用變量:歡迎光臨:$a

         定義變量:#set($a = 1)

         運算:#set($a = $a + 1)

         輸出:$a   ##得:2

         運算:#set($a = $a*5)

         輸出:$a   ##得:10

       #set( $criteria = ["name", "address"] )

         #foreach( $criterion in $criteria )

               #set( $result = false )  //先設置默認值

               #set( $result = $query.criteria($criterion) )

               #if( $result )

                       Query was successful

              #end

         #end

     (備註:從以上可以看出nVelocity的替換順序與.NET程序代碼的執行基本一致,如果放在Foreach語句塊中可以實現累加。並用If語句獲得行號,對特殊行號的內容特殊處理。所有變量在未定義之前不能使用,.NET後臺對象除外,最好採用正規引用格式,${a},正規引用格式一般用於在模板中直接調整字符串內容;靜態引用輸出:NVelocity遇到一個不能處理的引用時,一般他會直接輸出這個引用$email的寫法,頁面上會看到的是$email,我們可以在$後面加上一個!號,那麼就會輸出空白.$!{email}如果不能處理會輸出空白。如果email己定義了 (比如它的值是 foo),而這裏你卻想輸出 $email. 這樣一個字符串,就需要使用轉義字符”\”,如:\$email)

    2、  在頁面中使用條件判斷語句

        #if ($p.StrSex == "女")

            #set($Sex = "女士")

       #elseif ($p.StrSex == "男")

            #set($Sex = "先生")

       #elseif ($p.StrSex == "無")

            #set($Sex = "人妖")

       #else

            #set($Sex = "怪物")

       #end

     (備註:可以嵌套在Foreach語句塊中,用於對每個列表對象進行特殊顯示處理。)

    3、  創建宏,可以當做方法使用。

         

創建:#macro(Add $a $b)

         #set($c = $a + $b)

          <p>最後結果:$c</p>

      #end

 調用:#Add(1 2)

   

   (備註:模板引擎的初始化方法有3種,一種參數爲模板文件內容,一種是帶模板文件地址。結果發現帶模板文件內容的,在應用宏的時候好像有點問題。另外一個就是假如在宏裏面加入一個判斷語句,則可以實現遞歸調用。)

    4、使用對象方法

        定義變量:#set($str = “CNF”)

        調用方法:$str.SubString(0,1) 

         輸出:C

         定義變量:#set($a = 123)

         調用方法:$a.GetType()

         輸出:System.Int32

    (備註:不管是.NET代碼定義的對象,還是設計人員在頁面中定義的變量,都可以使用對象的方法及屬性,這一點非常強大。)

     5、使用even與odd簡化代碼,each輔助

         如上面所說用IF語句可以在列表中爲每行創建不同的樣式,但如果只需要區分單行與雙行的話,可以使用even與odd簡化代碼。如下:

    

     #foreach($p in $ps)

              #even

              <p>雙行:$p.StrName</p>

             #odd

             <p>單行:$p.StrName</p>

      #end

    (備註:在使用這兩個關鍵字時,出現了與創建宏一樣的問題,即在初始化模板引引擎的時候,如果是用模板文件內容初始化的,會出現問題)

     6、引用外部文件

          Include與parse都有引入外部文件的作用,不同的是parse會根據nVelocity模板語言解析外部文件。也就是說如果引入當前模板,則會出現死循環。

          #include 腳本元素讓模板設計者可以在模板中引入一個本地文件, 這個被引入的文件將不會經過NVelocity的解析. 安全起見,可以引放的文件只是是配置參數TEMPLATE_ROOT所定義目錄下的,默認爲當前目錄下.

#include( "head.html" )

        如果需要引入多個文件,可以像下面這樣.   

#include( "one.gif","two.txt","three.htm" )

            當然,還可用一個變量名來代替文件名引入.    

#include( "greetings.txt", $seasonalstock )

      #parse 元素指示可以引入一個包含TVL的本地文件,這個文件將被NVeloict engine解析輸出。

#parse( "me.vm" )

         與 #include 指令不同, #parse 可以從引入的模板中得到變量引用.但#parse指令只能接受一個參數.VTL templates 被#parse 的模板中還可以再包含#parse聲明,默認的深度爲10,這是由配置參數directive.parse.max.depth在文件velocity.properties中決定的,你可以修改它以適合項目要求。

     7、使用Foreach語句

          上面多次列出Foreach語句,相信已經知道它的作用。即循環列出一組對象集合。比如:#foreach($p in $ps),其中$ps需要與後臺代碼中具體的實體類名稱對應,$p代表$ps中的其中一項。上面已經提到過,即$p可以調用實體類的屬性和方法。

    (備註:#foreach 語句必須以#end結束,通過引用變量$velocityCount可以訪問到NVelocity提供的計數器:)

    8、創建數組

          創建:#set($List = [“男”,”女”])

          遍歷:#foreach($Item in $List)

                      <p>List成員:$Item</p>

                       #end

          輸出:List成員:男

               List成員:女

提供一個NVelocity 操作類VelocityHelper,方便大家使用:點擊下載

NVelocity.dll下載:點擊下載

    VelocityHelper調用如下:

     

VelocityHelper vh = new VelocityHelper();

vh.Init("~/template/");    //模板路徑

vh.Put("templateVariable", Variable);

vh.Display("index.htm");

附:NVelocity常用語法指令

    對變量的引用:$ [ ! ][ { ][ a..z, A..Z ][ a..z, A..Z, 0..9, -, _ ][ } ]。

       在NVelocity中,對變量的引用都是以$開頭加上變量名稱。當使用!時表示當此變量值爲空時,顯示空字符串。比如當$article爲空,那會顯示“$article“,而$!article會顯示爲“”。{}爲變量名稱限定,有時候變量名稱後會有字符串,這是就需要用到{}了。比如$articleshow,想引用$article,這時只要修改爲${article}就可以。其實,NVelocity對整個模板解析後都會變成這種模式。

     對屬性的引用:$ [ { ][ a..z, A..Z ][ a..z, A..Z, 0..9, -, _ ]* .[a..z, A..Z ][ a..z, A-Z, 0..9, -, _ ]* [ } ] 。

     例如$article.Title或者${article.Title}。

     對方法的引用:$ [ { ][ a..z, A..Z ][ a..z, A..Z, 0..9, -, _ ]* .[ a..z, A..Z ][ a..z, A..Z, 0..9, -, _ ]*( [ optional parameter list...  ] ) [  } ]。

     例如:$article.GetListByTitle(‘nvelocity’)或${article.GetListByTitle(‘nvelocity’)}。其實對對象的屬性值也可以用$article.get_Title()獲得。

     賦值指令#set:# [ { ] set [ } ]  ( $ref = [ ", ' ]arg[ ", ' ] )。

     例如:$article.Title=’NVelocity’,$$article.Categories=[1,2,3],當然右側也可以使用複雜的表達式:$article.Title=$otherArticle.Title.SubString(0,3),算術表達式:$article.Page=4/3等等。屬性賦值也可以用$article.set_Title(‘NVelocity’)。

     條件指令#if:# [ { ] if [ } ] ( [condition] ) [output] [ # [ { ] elseif [ } ] ( [condition] ) [output] ]* [ # [ { ] else [ } ] [output] ] # [ { ] end [ } ] 。

     條件可以是返回bool的複查表達式。例如:#if($article.Total>1) $article.Title #else 沒有數據 #end。

     循環指令#foreach:# [ { ] foreach [ } ] ($refinarg)statement# [ { ] end [ } ]。

     例如:#foreach($article in $articles) $article.Title #end。

     引用靜態資源指令#include:# [ { ] include [ } ] ( arg[ arg2 ... argn] )。

      例如:#include(‘tmp.js’),會把tmp.js文件內容插入當前流。當然可以使用表達式:#include($article.Url)。

     引用並解析資源指令#parse:# [ { ] parse [ } ] ( arg )。

     例如:#parse(‘tmp.js’),與#include不同是,假如tmp.js文件中有NVelocity的指令,變量會進行處理,並把結果插入到當前流。

     停止指令#stop:# [ { ] stop [ } ] 。

     當NVelocity解析到此指令時,會停止解析過程。一般用戶調試。

     計算指令#evaluate:# [ { ] evaluate [ } ] ( arg )。

     例如:#evaluate(‘$article.Title’),會在當前輸出$article.Title

NVelocity的$與Jquery的$發生衝突時的解決方法有以下幾個: 
1、 
使用jQuery.noConflict。 如:var j = jQuery.noConflict(); j.ajax(); 
缺點:當使用jQuery的相關插件時,會使得插件失效哦! 
2、 
使用jQuery代替$. 如:jQuery.ajax(); 
缺點:不適合擴展,一旦替換成第三方庫時,那就麻煩大發 
3、 
wrap jQuery中的衝突方法。 
如$.ajax()在Velocity中會衝突,則重新定義如下: 
function dw(){} 
dw.ajax=function(s){ jQuery.ajax(s); } dw.ajax(); 
4、 
定義一個$JQ爲$. 以後在js 中就可以用${JQ}AJAX了. 
在前臺這樣寫(定義):#set($JQ="$.") 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章