变量
变量会从当前模板的上下文查找值, 如果要输出一个变量的值, 可以使用
{{ variable }}
`</pre>
这样模板引擎会从上下文寻找变量`variable`并打印出来. 变量可以使用`.`访问其属性, 和 js 一样也可以通过`[]`访问属性
<pre>`{{ user.name }}
{{ user['name'] }}
`</pre>
如果一个变量的值是`undefined`或`null`, 那么什么也不会输出, 也不会报错.
### 支持的数据类型
XTemplate 支持 js 中所有基本数据类型
- Boolean
- Number
- String
- Null
- Undefined
- Object
- Array
### 输出
使用`{{ foo }}`来输出`escape`之后的数据, `{{{ foo }}}`来输出`unescape`的原始数据
<pre>`escaped: {{ foo }}
unescaped: {{{ foo }}}
`</pre>
如果希望输出最原始数据(包括`{{}}`), 那么需要使用`{{% %}}`语法
<pre>`{{%
{{ x }}
%}}
`</pre>
渲染这个模板, 会输出
<pre>`{{ x }}
`</pre>
#### 添加注释
<pre>`{{! comment }}
`</pre>
#### 添加空格
`{{~`删除空格前缀
`~}}`删除空格后缀
### 作用域
每一个模板都有一个独立的作用于, 在字幕版中可以访问父模板的上下文, 但是字幕版中定义或者修改变量不会影响到父模板的变量
<pre>`// parent.xtpl
{{ set (a=1,b=2) }}
{{ include ('sub.xtpl') }}
in parent:
a = {{ a }}
b = {{ b }}
`</pre>
<pre>`// sub.xtpl
in sub:
{{ set b = 3 }}
a = {{ a }}
b = {{ b }}
`</pre>
渲染 parent.xtpl 得到
<pre>`in sub:
a: 1
b: 3
in parent:
a: 1
b: 2
`</pre>
### 根数据
通过`root.foo` 可以访问到渲染的根数据, 即调用`render`方法时传入的数据
用数据`{ name: 'foo', array: [{name:'bar'}] }`渲染下面模板:
<pre>`{{ #each(arr) }}
{{root.name}} {{name}}
{{/each}}
`</pre>
得到
<pre>`foo bar
`</pre>
## 方法和逻辑
可以使用变量上 js 提供的方法:
<pre>`var x = [1,2,3]
`</pre>
<pre>`{{#each(x.slice(1))}}{{this}} {{/each}} // => 2 3
`</pre>
### 操作符
XTemplate 支持在数据上使用一些操作符:
<pre>`+, -, *, /, %
`</pre>
<pre>`===, !==, >, >=, <, <=
`</pre>
<pre>`||, &&, !
`</pre>
<pre>`?:
`</pre>
### 函数调用
如果你传递 js 的方法到模板中, 那么可以使用它
<pre>`{{foo(1,2,3)}}
`</pre>
### 内置函数
<pre>`range(start, end, [step])
`</pre>
不包括 end
<pre>`set(key = value, [key = value])
`</pre>
`set` 用于定义或修改一个变量
<pre>`{{ set(x=1) }}
{{ set(y=3,z=2) }}
{{x}}
{{y+z}}
`</pre>
渲染得到
<pre>`1
5
`</pre>
`void`, 允许忽略模板渲染
<pre>`{{ set(x=1) }}
{{ void(x) }}
`</pre>
将渲染空
## 命令
命令是一些特殊的区块, 对于这些特殊的区块, XTemplate 会做特殊处理. XTemplate 自带了一些内置的命令, 也可以自定义命令
`if`
<pre>`{{# if(variable) }}
It is true
{{/ if}}
`</pre>
如果 vairable 为 true, 则渲染命令块
<pre>`{{# if(variable) }}
{{ elseif (vairable)}}
{{ else }}
{{/ if }}
`with`
和 js 中的`with`类似
`</pre>
var a = {
b:1
}
```
<pre>`{{{#with(a)}}}
{{b}} // 1
{{/with}}
`</pre>
`each`
`each`可以对 array 和 dictionary 进行迭代
<pre>`// array
{{ set (array = [{
name: 'foo'
}, {
name: 'bar'
}])}}
{{#each(array)}}
{{xindex}} {{this.name}}
{{/each}}
`</pre>
渲染得到
<pre>`0 foo
1 bar
`</pre>
<pre>`// dictionary
{{ set (dictionary = {
foo:'bar',
hello:'world'
})}}
{{#each(dictionary,'value','key')}}
{{key}}{{value}}
{{/each}}
`</pre>
渲染得到
<pre>`foo bar
hello world
`</pre>
### 访问上层变量
在`with`和`each`中, 可以通过`../`访问外层的同名变量
<pre>`// {a: 1, b:[{a:2}]}
{{#with(x)}}
{{#each(b)}}
{{../a}}{{a}} // 12
{{/with}}
{{/with}}
`</pre>
### 宏
宏允许你定义一个可复用的代码片段
<pre>`{{#macro("test","param",default=1)}}
param is {{param}} {{default}}
{{/macro}}
`</pre>
现在可以调用该宏
<pre>`{{macro("test", "2")}}
{{macro("test","2",default=2)}}
`</pre>
渲染结果
<pre>`param is 2 1
param is 2 2
`</pre>
### include
`include` 引入其他的模板, 在共享组件的时候十分有效
<pre>`{{ include ('item.html') }}
`</pre>
如果下网引入子模板的时候可以在子模板的上下文设置其他值, 可以通过`include`后面的参数传入
<pre>`// parent.html
{{ set(x='x',y='y') }}
{{ include ('sub.html', xx=x,yy=x) }}
`</pre>
<pre>`// sub.html
x:{{x}}
y:{{y}}
xx:{{xx}}
yy:{{yy}}
`</pre>
parent.html渲染结果
<pre>`x: x // from parent.html
y: y // from parent.html
xx: x // from sub.html
yy: x // from sub.html
`</pre>
### includeOnce
功能和`include`一样, 区别在于对于同一个模板, 只在第一次调用的时候起作用.
### parse
如果希望能够让子模板拥有一个完全独立的上下文, 不需要父级作用于, 则可以使用`parse`
<pre>`// parent.html
{{ set(x = 'x', y = 'y') }}
{{ parse('sub.html', xx = x, yy = x) }}
`</pre>
<pre>`// sub.html
x: {{x}}
y: {{y}}
xx: {{xx}}
yy: {{yy}}
`</pre>
parent.html渲染结果
<pre>`x:
y:
xx:x
yy:x
`</pre>
## 模板继承
当编写一个 template 的时候, 可以定义`blocks`, 这样在字幕版中可以重写这些 block
<pre>`// parent.xtpl
<!DOCTYPE html>
<html>
<head>
<....>
{{{block ('head')}}}
</head>
<body>
{{{block ('body')}}}
</body>
</html>
`</pre>
<pre>`// child.xtpl
{{ extend ('./parent.xtpl')}}
{{#block ('head')}} // overwrite head block
<....>
{{/block}}
{{#block ('body')}} // overwrite body block
<...>
{{/block}}
渲染 child.xtpl 可以获得新的模板下的实例