变量

变量会从当前模板的上下文查找值, 如果要输出一个变量的值, 可以使用

{{ 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}} // =&gt; 2 3
`</pre>

### 操作符

XTemplate 支持在数据上使用一些操作符:

<pre>`+, -, *, /, %
`</pre>

<pre>`===, !==, &gt;, &gt;=, &lt;, &lt;=
`</pre>

<pre>`||, &amp;&amp;, !
`</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
&lt;!DOCTYPE html&gt;
&lt;html&gt;
  &lt;head&gt;
    &lt;....&gt;
    {{{block ('head')}}}
  &lt;/head&gt;
  &lt;body&gt;
    {{{block ('body')}}}
  &lt;/body&gt;
&lt;/html&gt;
`</pre>

<pre>`// child.xtpl
{{ extend ('./parent.xtpl')}}

{{#block ('head')}} // overwrite head block
  &lt;....&gt;
{{/block}}

{{#block ('body')}} // overwrite body block
  &lt;...&gt;
{{/block}}

渲染 child.xtpl 可以获得新的模板下的实例