万维易源使用帮助手册
[TOC]
本系统中使用的变量为mustache语法。
mustache官方给出的是定义是:Logic-less templates,翻译过来就是逻辑很少的模板语言。
本系统中,mustache可用于多个配置进行变量替换,如下图示例:

# mustache基本语法
## 1. {{变量}}
一个比较典型的mustache模板如下所示:
```javascript
Hello,my name is {{name}},
I am {{age}} years old 。
```
给出的变量容器如下所示:
```json
{
"name": "张三",
"age": 25
}
```
那么得到的结果又会是怎样的呢?
```javascript
Hello,my name is 张三,
I am 25 years old 。
```
## 2. {{@变量}}
注意:本语法为易源数据的自定义指令,并不是mustuche标准语法。
假设我们要生成一段sql语句,可以如下:
```javascript
select * from user where name="{{name}}" and age={{age}}
```
变量容器如下所示:
```json
{
"name": "张三",
"age": 25
}
```
则生成的结果是:
```javascript
select * from user where name="张三" and age=25
```
可以看到{{变量}}语法是纯变量替换。在sql语句如果使用{{变量}},那我们需要为字符串手动添加单
引号或双引号,并且在传值的时候要自己控制sql反注射。
我们来试下sql注射的情况:
```javascript
--语句模板是:
select * from user where name="{{name}}" and age={{age}}
--变量是:
{
"name": "张三\" or \"1==1",
"age": "25 or 1==1"
}
--那么最终生成的是:
select * from user where name="张三" or "1==1" and age=25 or 1==1
```
**闻到危险的味道了吗?
**
有什么办法可以解决呢?我们可以使用{{@变量}}的语法。请看如下:
```javascript
--语句模板是:
select * from user where name={{@name}} and age={{@age}}
--变量是:
{
"name": "张三\" or \"1==1",
"age": "25 or 1==1"
}
--那么最终生成的是:
select * from user where name="张三\" or \"1==1" and age="25 or 1==1"
```
也就是使用了{{@变量}},前面加了个@符号,这个指令会区分字符串和数字,并会把变量做为整体输出(自动转义了其中的单双引号等特殊字符)。
由于变量做了整体输出,而不仅是字符串替换,在编写时不用考虑单双引号,方便很多。
## 3. {{&变量}}
{{&变量}}将变量做urlencode后进行输出。
例如您要post一段body到服务端,原来的post体是这样子的:
```html
name=张三&age=25&type=1
```
那我们可能把name和age暴露出来,做为一个接口的外部输入参数,比如
```java
new NormalRequest("url")
.addTextPara("name","张三")
.addTextPara("age","25")
.post
```
然后在生成body体时,使用变量:
```html
name={{name}}&age={{age}}&type=1
```
但是这有一个问题,{{变量}}指令是【原值替换】,因此post时存在编码问题,在服务端会收到乱码。那如何做呢?请看如下:
```html
name={{&name}}&age={{age}}&type=1
```
其中name使用了{{&变量}},它会把"张三"做urlencode,最终生成的串为:
```html
name=%e5%bc%a0%e4%b8%89&age=25&type=1
```
看到上面的串,是不是比较熟悉了。
## 4. {{#变量}}和{{/变量}}对
这是一组标签对,就像<html>与</html>一样是个开始和结束的组合对。它有两个用法,真假判断,以及循环列表。
### 1. 空值及boolean判断
我们通常有这样的需求:在一个sql语句中,用户传了什么字段来,我们才拼接那个字段的条件,例如java代码:
```java
String sql="select * from user where 1==1 "
if(params.name){
sql+=" and name=?"
}
if(params.age){
sql+=" and age=?"
}
```
我们用mustache怎么实现上述语句的拼接?
```java
select * from user where 1==1
{{#name}}
and name={{@name}}
{{/name}}
{{#age}}
and age={{@age}}
{{/age}}
```
是不是挺方便的?
注意:当
```java
key!=null
and key!=false
and key.size()>0
```
时 ,{{#key}}表达式为true .
### 2. 遍历列表

还是一样的,如果要拼接的sql语句中包括List变量,我们可以这么做:
```java
select * from user where 1==1
{{#typeList}}
or type={{@.}}
{{/typeList}}
--typeList是
[1,2,3,"test"]
--上述将生成
select * from user where 1==1
or type=1
or type=2
or type=3
or type="test"
```
上述用到了{{@}}和{{.}}的组合,意思是把typeList中的单项,做字符串转义后输出。{{.变量}}用用于循环列表中,指代当前项,有点类似于this的意味。
当然这只是一个示例用法,通常并不会设置type为数字和字符串共存。
## 5. {{.变量}}
用于循环列表时,表示【当前条目】,类似于this的作用。详见上一小节【遍历列表】内容。