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

xtemplate语法的更多相关文章

  1. XTemplate语法基础

    XTemplate 是富逻辑的 KISSY 模板引擎,面向复杂的业务逻辑场景,同时保持高性能和丰富的配置方法,是易学易懂的模板语言. 一个典型的XTemplate模板实例: Hello {{name} ...

  2. XTemplate模板学习和使用总结

    XTemplate模板学习和使用总结 前言   XTemplate是我接触的第一个模板语言,用在公司的一个NodeJS项目中,跟它打交道经常是因为需要使用它的语法向模板中注入数据.因为是刚入门前端不久 ...

  3. vueJs的简单入门以及基础语法

    1-1基本数据绑定 <div id="app"> {{ msg }} </div> //script new Vue({ el:"#app&quo ...

  4. 四、vue语法补充

    1.自定义过滤器 格式: {{ msg | filters}} 2.computed 属性默认只有 getter ,不过在需要时你也可以提供一个 setter <!DOCTYPE html> ...

  5. [ASPX] 模版引擎XTemplate与代码生成器XCoder(源码)

    模版引擎XTemplate是一个仿T4设计的引擎,功能上基本与T4一致(模版语法上完全兼容T4,模版头指令部分兼容). 自己设计模版引擎,就是为了代码生成器.网站模版.邮件模版等多种场合,也就是要能拿 ...

  6. 我的MYSQL学习心得(一) 简单语法

    我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类型 我的MYSQL学习心得(五) 运 ...

  7. Swift与C#的基础语法比较

    背景: 这两天不小心看了一下Swift的基础语法,感觉既然看了,还是写一下笔记,留个痕迹~ 总体而言,感觉Swift是一种前后端多种语言混合的产物~~~ 做为一名.NET阵营人士,少少多多总喜欢通过对 ...

  8. 探索C#之6.0语法糖剖析

    阅读目录: 自动属性默认初始化 自动只读属性默认初始化 表达式为主体的函数 表达式为主体的属性(赋值) 静态类导入 Null条件运算符 字符串格式化 索引初始化 异常过滤器when catch和fin ...

  9. [C#] 回眸 C# 的前世今生 - 见证 C# 6.0 的新语法特性

    回眸 C# 的前世今生 - 见证 C# 6.0 的新语法特性 序 目前最新的版本是 C# 7.0,VS 的最新版本为 Visual Studio 2017 RC,两者都尚未进入正式阶段.C# 6.0 ...

随机推荐

  1. iOS 热更新插件

    1.JSPatch 平台 http://jspatch.com/Docs/intro 2.React Native 中文文档 http://wiki.jikexueyuan.com/project/r ...

  2. 数据结构录 之 BST的高级应用。

    BST就是二叉检索树,或者是二叉排序树,或者叫二叉搜索树等等. BST的平衡问题可以去学习AVL树或者Treap或者Splay这些平衡树. BST的一些高级应用: 1,求BST中比k小的数的个数: 只 ...

  3. 一个action读取另一个action里的session

    action 1: private Map session; session.put("projectname_session", request1.getParameter(&q ...

  4. Ext中包含了几个以get开头的方法

    Ext中包含了几个以get开头的方法,这些方法可以用来得到文档中DOM.得到当前文档中的组件.得到Ext元素等,在使用中要注意区别使用.1.get方法get方法用来得到一个Ext元素,也就是类型为Ex ...

  5. Deep learning:三十八(Stacked CNN简单介绍)

    http://www.cnblogs.com/tornadomeet/archive/2013/05/05/3061457.html 前言: 本节主要是来简单介绍下stacked CNN(深度卷积网络 ...

  6. Android 4.0 ICS SystemUI浅析——StatusBar结构分析

    Android 4.0 ICS SystemUI浅析——StatusBar结构分析 分类: Android2012-06-30 14:45 23687人阅读 评论(8) 收藏 举报 androidsi ...

  7. php dependency innjection

    You’ve probably heard of the acronym SOLID by now, which is an object oriented programming paradigm ...

  8. 使用msm文件创建msi

    一.不使用merge module的ModuleSubstitution和ModuleConfiguration 1.创建MyMsm.msm <?xml version="1.0&qu ...

  9. [iOS]C语言知识点系列视频

    C语言知识点系列视频 目录 C语言技术视频-01-变量的定义 C语言技术视频-02-程序分支结构(if...else) C语言技术视频-03-程序分支结构(switch) C语言技术视频-04-程序循 ...

  10. php中使用mysql_fetch_array输出数组至页面中展示

    用的是CI框架,很好的MVC结构 在Model层 public function showProteinCategory(){ $sql = "SELECT DISTINCT protein ...