xtemplate語法


 

XTemplate 是富邏輯的 KISSY 模板引擎,面向復雜的業務邏輯場景,同時保持高性能和豐富的配置方法,是易學易懂的模板語言。

一個典型的XTemplate模板實例:

Hello {{name}}
You have just won ${{value}}! {{#if data}} {{#each data}} {{name}}-{{xindex}}/{{xcount}} {{/each}} {{/if}}

對應要填充的JSON:

{ name:'Kissy', value:'10000', data:[ {name:1}, {name:2} ] }

拼裝結果:

Hello Kissy You have just won $10000! 1-0/2 2-1/2 

XTemplate 可以放置於HTML、配置文件、程序代碼中,核心機制就是把模板中的標簽替換為JSON對象給定的值,並同時具有一定的模板語言邏輯。 模板中除了提供最簡單的變量替換,還提供if、else和foreach等常見功能。所謂標簽,指的是雙花括號包含的一個標記,{{name}}就是一個標簽,{{#name}}也是一個標簽。XTemplate模板語言是抽象的,可以有多種編程語言的實現,KISSY 的xtemplate模塊實現了 XTemplate 標記語言。

這樣來引入xtemplate模塊:

KISSY.use('xtemplate',function(S,XTemplate){ // use XTemplate });

如何通過KISSY來解析XTemplate模板?先看一個簡單的例子,實現變量替換:

KISSY.use('xtemplate', function (S, XTemplate) { var tpl = 'this is {{title}}!'; var data = { title: 'o' }; var render = new XTemplate(tpl).render(data); alert(render);// => "this is o!" });

你也可以直接離線編譯 xtemplate 為 kissy 模塊,那么線上直接引入 xtemplate/runtime 即可,還省去了在線編譯的時間,提高運行效率。

KISSY.use('xtemplate/runtime,tpls/x',function(S, XTemplate,x){ var data={z:1}; new XTemplate(x).render(data); });

詳見:xtemplate 離線編譯

更多例子:KISSY XTemplate Demos


KISSY XTemplate 語法

{{key}}變量替換

使用{{key}}輸出變量值,key表示要替換的JSON中的key,替換為JSON中key對應的value。比如XTemplate:

this is {{title}}!

要填充的JSON對象:

{ title:'Kissy' }

拼裝結果為:

this is Kissy!

{{if condition}}條件語句

使用{{if condition}}來實現條件判斷,condition表示要判斷的值,判斷是否存在、為空、是否為falsy。比如模板為:

{{#if title}} has title {{/if}} {{@if title2}} has title2 {{else}} not has title2 {{/if}}

要填充的JSON對象:

{ title:'kissy', title2:'' }

填充結果為:

has title 
not has title2 

其中{{#if}}{{@if}}完全等價,在某些環境中(比如velocity)里#有特殊語義,這時可以用@作為if前綴。

此外,title的取值不為這些值時被認為是真值:0null''falseNaNundefined。當取值為空數組[]或空對象'{}'時,則認為是真值。

{{^if condition}}條件非語句

使用{{^if condition}}來實現條件非,如果condition值為空或者假值(0null''falseNaNundefined),則此語句為 true。如果condition有值且是真值,語句為 false。比如這段 XTemplate 模板:

{{^if title}} do not has title {{/if}} {{^if title2}} do not has title2 {{else}} has title2 {{/if}}

填充的JSON為:

{ title:undefined, title2:'' }

填充結果為:

do not has title do not has title2 

{{#each}}循環語句

循環對象數組

使用{{#each data}}表示循環,data表示循環的對象,數組類型,每個item為一個對象,比如這段 XTemplate:

{{#each data}} {{name}}-{{xindex}}/{{xcount}} {{/each}}

如果填充的JSON為數組類型:

{ data:[ {name:1}, {name:2} ] }

渲染結果為:

1-0/2
2-1/2

這時循環內的{{xindex}}表示循環的索引值,{{xcount}}表示循環的總次數,{{name}}是數組中每個對象的屬性name,替換為屬性的值

循環單數組

循環的data為數組類型,每個item為一個值,而非對象,比如這段XTemplate:

{{#each data}} {{this}}-{{xindex}}/{{xcount}} {{/each}}

要填充的JSON對象為:

{ data:['jayli','yiminghe'] }

渲染結果為:

jayli-0/2
yiminghe-1/2

其中循環內的{{this}}表示當前循環的item值,{{xindex}}{{xcount}}含義同上

each中數據層次相對位置的訪問

循環體內可以獲取JSON對象上的其他屬性,同過相對位置寫法獲得,比如這段XTemplate:

{{#each data}} {{this}}-{{../total}} {{/each}}

要填充的JSON對象為:

{ data: [1, 2], total: 3 }

填充結果為:

1-3
2-3

其中,{{../total}}表示從循環體內跳出到data屬性所在的層級,去查找data屬性的兄弟屬性total的值。同樣,{{#each}}可以被{{@each}}代替。

{{#with}}語句

類似 JavaScript 中的with語法,with 語句是為逐級的對象訪問提供命名空間式的速寫方式。我們在 XTemplate 中增加了類似的功能。比如{{#with data}}...{{/with}},中間可以直接調用對象data里的屬性,輸出對應的值。

比如這段 XTemplate

{{#with data}} {{name}}-{{age}} {{/with}}

要填充的JSON為:

{ data:{ name:'jayli', age:'2' } }

填充結果為:

jayli-2

其中{{#with}}可以用{{@with}}代替

支持 with 中數據層次間的相對位置訪問

{{#each}}一樣,with 語句中也可以用相對路徑寫法來訪問對象其他層級的屬性,比如這段模板:

{{#with data}} {{#with p}} {{name}}-{{age}}-{{../l2}}-{{../../l1}} {{/with}} {{/with}}

要填充的JSON為:

{
    l1: 1,
    data: {
        l2: 2,
        p: {
            name: 'h',
            age: 2
        }
    }
}

填充結果為:

h-2-2-1

{{!comment}} 注釋

XTemplate的注釋寫法為{{!comment}},其中comment為注釋內容,注釋將會被忽略。

\\{{prop}} 標簽的轉義

如果想直接輸出{{prop}}的內容,而不想被解析為標簽,則用轉義寫法\\{{prop}},比如模板:

output \\{{name}} as {{name}}

要填充的JSON為:

{name:'jay'}

輸出結果為:

output {{name}} as jay

{{{prop}}} html 標簽轉義

如果輸出的內容中包含字符<>,在普通標簽{{prpp}}中會被轉義為&lt;&gt;,如果不想被轉義,需使用{{{prop}}},比如這段模板:

my {{title}} is {{{title}}}

要填充的JSON為:

{ title:'<a>' }

輸出結果為:

my &lt;a&gt; is <a>

用表達式作為變量

目前支持的表達式為+-*/%。比如這段模板:

{{n+3*4/2}}

填充JSON為

{n:1}

輸出結果為:

7

關系表達式

目前支持目前支持 === !== > >= < <=,比如這段模板:

{{#if n>n2+4/2}} {{n+1}} {{else}} {{n2+1}} {{/if}}

要填充的JSON:

{ n:5, n2:2 }

輸出結果為:

6

each 循環中的關系表達式

直接看例子,看這段模板:

{{#each data}}
    {{#if this>../limit+1}} {{this+1}}-{{xindex+1}}-{{xcount}} {{/if}} {{/each}}

要填充的JSON

{ data: [11, 5, 12, 6, 19, 0], limit: 10 }

填充結果:

13-3-6
20-5-6

with 中的關系表達式

直接看例子,看這段模板:

{{#with data}} {{#if n>../limit/5}} {{n+1}} {{/if}} {{/with}}

填充JSON為:

{ data: { n: 5 }, limit: 10 }

輸出結果為:

6

{{set}}設置變量

通過{{set expression}}來設置變量的值,可以設置多個,賦值表達式之間用空格分隔,比如這段模板:

{{#each data}}
    {{set n2=this*2 n3=this*3}} {{n2}}-{{n3}} {{/each}}

填充JSON:

{ data: [1, 2] }

結果為:

2-3
4-6

對 mustache 對象的兼容

XTemplate 支持對 mustache 形式的對象的兼容,比如這段模板:

{{#data}}{{name}}-{{age}}{{/data}}

填充JSON為:

{ data: { name: 'h', age: 2 } }

輸出結果為

h-2

對 mustache 數組的兼容

XTemplate 支持對 mustache 形式的數組的兼容,比如這段模板:

{{#data}} {{name}}-{{xindex}}/{{xcount}} {{/data}}

填充JSON:

{ data: [ {name: 1}, {name: 2} ] }

輸出結果為:

1-0/2
2-1/2

KISSY XTemplate 附加功能

以上語法可以在不同語言中實現,在 JavaScript 環境中得益於 JS 語言的動態性,KISSY 為 XTemplate 提供了更多的瀏覽器端的渲染策略和工具。這些功能只在 JavaScript 的實現中可用, 如果你的模板可同時被JavaScript渲染也會被其他語言渲染(比如在后台被Java渲染),請盡可能避免這種用法。

全局行內單個標簽擴展

如果我想擴展 XTemplate 中的標簽個數,需要自定義擴展標簽,使用XTemplate.addCommand()實現全局行內命令擴展,比如這樣一段擴展(自定義一個單個標簽,無配對出現):

XTemplate.addCommand('global', function (scopes, option) { return 'global-' + option.params[0]; });

這樣這段模板就可以渲染出來:

my {{global title}}

如果JSON為{title:'1'},那么渲染結果為:

my global-1

全局塊狀標簽擴展

除了擴展單個標簽,還可以擴展塊狀標簽,例子:

 XTemplate.addCommand('global', function (scopes, option) { return 'global-' + option.fn(scopes); });

對於這段模板就可以被識別:

{{#global}} {{title}} {{/global}}

如果JSON對象為{title:1},渲染結果為:

global-1

刪除全局標簽的定義

removeCommand()方法來刪除自定義的全局標簽,調用格式為:XTemplate.removeCommand(commandName,fn)

局部行內標簽擴展

如果要把標簽擴展不做成全局,可以臨時定義針對一段模板的標簽擴展,做法是在XTemplage()函數中傳入第二個配置參數:

var render = new XTemplate(tpl, { commands: { 'global': function (scopes, option) { return 'global-' + option.params[0]; } } }).render(data);

局部塊狀標簽擴展

類似行內標簽擴展,塊狀標簽擴展需要用option.fn(scopes)來激活,參照上文,做法是:

var render = new XTemplate(tpl, { commands: { 'global': function (scopes, option) { return 'global-' + option.fn(scopes); } } }).render(data);

局部后綴名判斷標簽擴展

參照標簽的擴展規則,再來看一個更復雜的例子,我們可以自定義條件判斷的規則:

var render = new XTemplate(tpl, { commands: { 'endsWith': function (scopes, option) { return S.endsWith(option.params[0], option.params[1]) ? option.fn(scopes) : ''; } } }).render(data);

這里擴展了自定義標簽endsWith,對於這段模板:

{{d}} ends with {{#endsWith d "jpg"}}jpg{{/endsWith}} {{#endsWith d "gif"}}gif{{/endsWith}}

JSON對象為{d:'x.jpg'},輸出結果為:

x.jpg ends with jpg

下載地址:https://www.npmjs.org/package/xtemplate


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM