使用artTemplate模板引擎开发网站

artTemplate

artTemplate是一款性能卓越的 javascript 模板引擎。它采用预编译方式让性能有了质的飞跃,并且充分利用 javascript 引擎特性,使得其性能无论在前端还是后端都有极其出色的表现。在 chrome 下渲染效率测试中分别是知名引擎 Mustache 与 micro tmpl 的 25 、 32 倍(性能测试)。
test.png
除了性能优势外,调试功能也值得一提。模板调试器可以精确定位到引发渲染错误的模板语句,解决了编写模板过程中无法调试的痛苦,让开发变得高效,也避免了因为单个模板出错导致整个应用崩溃的情况发生。

下载: 简洁语法版(推荐) 、 原生语法版Github

特性

  1. 性能卓越,执行速度通常是 Mustache 与 tmpl 的 20 多倍(性能测试)
  2. 支持运行时调试,可精确定位异常模板所在语句(演示)
  3. 对 NodeJS Express 友好支持
  4. 安全,默认对输出进行转义、在沙箱中运行编译后的代码(Node版本可以安全执行用户上传的模板)
  5. 支持include语句,可在浏览器端实现按路径加载模板
  6. 支持预编译,可将模板转换成为非常精简的 js 文件
  7. 模板语句简洁,无需前缀引用数据
  8. 支持所有流行的浏览器

作为前端模版引擎

快速上手

编写模版

创建一个html文件,引入template.js,然后在正文中放置一个id为content的div标签,用来存放接下来根据模板动态生成的html内容。

1
2
3
4
5
6
7
8
9
10
<html>
<head>
<meta charset="UTF-8">
<title>demo</title>
<script src="template.js"></script>
</head>
<body>
<div id=”content”></div>
</body>
</html>

使用一个type="text/html"的script标签存放模板:

1
2
3
4
5
6
7
8
<script id="test" type="text/html">
<h1>{{title}}</h1>
<ul>
{{each list as value i}}
<li>索引 {{i + 1}} :{{value}}</li>
{{/each}}
</ul>
</script>

渲染模版

1
2
3
4
5
6
7
8
<script>
var data = {
title: '标签',
list: ['文艺', '博客', '摄影', '电影', '民谣', '旅行', '吉他']
};
var html = template.render('test', data);
document.getElementById('content').innerHTML = html;
</script>

演示

不转义HTML

模板引擎默认数据包含的 HTML 字符进行转义以避免 XSS 漏洞,若不需要转义的地方可使用==。

1
2
3
<script id="test" type="text/html">
{{#value}}
</script>

若需要关闭默认转义,可以设置template.isEscape = false
演示

在js中存放模板

template.compile([id], source)将返回一个渲染函数。其中 id 参数是可选的,如果使用了 id 参数,可以使用template.render(id, data)渲染模板。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<script>
var source = '<ul>'
+ '{{each list as value i}}'
+ '<li>索引 {{i + 1}} :{{value}}</li>'
+ '{{/each}}'
+ '</ul>';
var render = template.compile(source);
var html = render({
list: ['摄影', '电影', '民谣', '旅行', '吉他']
});
document.getElementById('content').innerHTML = html;
</script>

演示

添加辅助方法

template.helper(name, callback)辅助方法一般用来进行输出字符串或字符串替换。
例如编写一个显示当前时间的辅助方法:

1
2
3
4
5
6
7
8
9
10
template.helper('dateFormat', function (date, format) {
//..
return value;
});
var data = {
time: (new Date).toString(),
};
var html = template('test', data);
document.getElementById('content').innerHTML = html;

在模板中的使用方式:

1
{{time | dateFormat:'yyyy年 MM月 dd日 hh:mm:ss'}}

支持传入参数与嵌套使用:

1
{{time | say:'cd' | ubb | link}}

注意:引擎不会对辅助方法输出的 HTML 字符进行转义。
演示

作为后端引擎使用(配合node.js)

安装art-template

1
npm install art-template --save

编写artTemplate模板

在工作区下,创建index.html,并将如下代码输入index.html,保存。其中<ul>标签中的内容,就是模板代码。

1
2
3
4
5
6
7
<div id='main'>
<ul>
{{each list}}
<li>编号:{{$value.id}} &nbsp;&nbsp;姓名:{{$value.name}}</a></li>
{{/each}}
</ul>
</div>

渲染模板

还记得template(id, data)方法吗?这是在前端DOM环境下的用法。 其实在NodeJS环境下,它就相当于template(filename, data)了,可以将需要渲染的模板文件名当作路径传给它的第一个参数。

1
2
3
4
5
6
7
8
9
10
11
12
13
var http = require('http');
var os = require('os');
http.createServer(function(request, response) {
var template = require('art-template');
//数据
var data = {list: [{id:'1', name:'张三'}, {id:'2', name:'李四'}]};
//渲染模板
var html = template('./index', data);
response.writeHead(200, {'Content-Type': 'text/html'});
response.write(html);
response.end();
}).listen(3000);
console.log("Server is running, listening on port 3000…");

配置base指定模板目录可以缩短模板的路径,并且能够避免include语句越级访问任意路径引发安全隐患。例如:

1
2
template.config('base', __dirname);
var html = template('index/main', data)

在Windows命令行下,进入工作区,执行node server.js,服务器就启动了。 此时在本地机器上使用浏览器访问http://localhost:3000将会看到Html输出了。

搭配express使用

express框架是由javascript语言开发的,基于Node.js平台的,快速、开放、极简的web开发框架。

安装art-template

1
npm install art-template --save

改造app.js

app.js是express的主要文件,这个文件里包含了指定模板引擎、指定视图文件默认路径的代码。需要将指定模板引擎的代码改为指定用art-template引擎。视图文件默认路径保持不变,因此无需改动。

1
2
3
4
5
6
7
8
9
//首先,引入artTemplate模块
var template = require('art-template');
//用art-template引擎替换默认的jade引擎
template.config('base', '');
template.config('extname', '.html');
app.engine('.html', template.__express);
app.set('view engine', 'html');
//app.set('view engine', 'jade');

编写artTemplate模板

进入express文件夹中的views子文件夹,创建index.html,并将如下代码输入index.html,并保存。

1
2
3
4
5
6
7
<div id='main'>
<ul>
{{each list as value i}}
<li>索引 {{i + 1}} :{{value}}</li>
{{/each}}
</ul>
</div>

渲染模版

express默认访问index路由。进入routes文件夹,打开router.js,增加渲染模板的代码,如下:

1
2
3
4
5
6
7
8
9
router.get('/', function(req, res, next) {
// 数据
var data = {
title: '标签',
list: ['文艺', '博客', '摄影', '电影', '民谣', '旅行', '吉他']
};
// 渲染模板
res.render('index', data);
});

代码中的res.render('index', data)调用,会调用artTemple模块中的template.__express方法,并传入模板文件名、数据。 template.__express方法是在app.js中注册给express框架的。

预编译工具

使用预编译工具可以让前端模版不再受浏览器的限制,支持如后端模版一样按文件放置、include 语句等特性,可以像后端一样书写前端模板!

编译后的模板不再依赖前端模板引擎与后端,模板可以通过 SeaJS 或 RequireJS 等加载器进行异步加载,亦能利用它们成熟的打包合并工具进行上线前的优化,如合并与压缩。

预编译工具:TmodJS

TmodJS 一经启动,就无需人工干预,每次模板创建与更新都会自动编译,引入一个 js 即可使用template(path)接口调用本地模板文件,直到正式上线都无需对代码进行任何修改,整个过程简单自然。

安装TmodJS

1
npm install -g tmodjs

编译模板

只需要运行tmod这个命令即可,默认配置参数可以满足绝大多数项目。

1
tmod [模板目录] [配置参数]

模板目录必须是模板的根目录,若无参数则为默认使用当前工作目录,tmodjs 会监控模板目录修改,每次模板修改都会增量编译。

配置参数

  • --debug 输出调试版本
  • --charset value 定义模板编码,默认utf-8
  • --output value 定义输出目录,默认./build
  • --type value 定义输出模块格式,默认default,可选cmd、amd、commonjs
  • --no-watch 关闭模板目录监控
  • --version 显示版本号
  • --help 显示帮助信息

配置参数将会保存在模板目录配置文件中,下次运行无需输入配置参数(–no-watch 与 –debug 除外)。

示例

1
tmod ./tpl --output ./build

使用模板

根据编译的type的配置不同,会有两种不同使用方式:

使用默认的格式

TmodJS 默认将整个目录的模板压缩打包到一个名为 template.js 的脚本中,可直接在页面中使用它:

1
2
3
4
5
<script src="tpl/build/template.js"></script>
<script>
var html = template('news/list', _list);
document.getElementById('list').innerHTML = html;
</script>

template.js 还支持 RequireJS、SeaJS、NodeJS 加载。示例

指定格式(amd / cmd / commonjs)

此时每个模板就是一个单独的模块,无需引用 template.js:

1
2
var render = require('./tpl/build/news/list');
var html = render(_list);

注意:模板路径不能包含模板后缀名

演示

TmodJS 源码包test/tpl是一个演示项目的前端模板目录,基于默认配置。切换到源码目录后,编译:

1
tmod test/tpl

编译完毕后你可以在浏览器中打开 test/index.html 查看如何使用编译后的模板。

配置

TmodJS 的项目配置文件保存在模板目录的 package.json 文件中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{
"name": "template",
"version": "1.0.0",
"dependencies": {
"tmodjs": "1.0.0"
},
"tmodjs-config": {
"output": "./build",
"charset": "utf-8",
"syntax": "simple",
"helpers": null,
"escape": true,
"compress": true,
"type": "default",
"runtime": "template.js",
"combo": true,
"minify": true,
"cache": false
}
}
字段 类型 默认值 说明
output String "./build" 编译输出目录设置。如果设置为 false 则不输出
charset String "utf-8" 模板使用的编码(暂时只支持 utf-8)
syntax String "simple" 定义模板采用哪种语法。可选:simplenative
helpers String null 自定义辅助方法路径
escape Boolean true 是否过滤 XSS。如果后台给出的数据已经进行了 XSS 过滤,就可以关闭模板的过滤以提升模板渲染效率
compress Boolean true 是否压缩 HTML 多余空白字符
type String "default" 输出的模块类型,可选:defaultcmdamdcommonjs
runtime String "template.js" 设置输出的运行时名称
alias String null 设置模块依赖的运行时路径(仅针对于非default的类型模块配置字段。如果不指定模块内部会自动使用相对 runtime 的路径)
combo Boolean true 是否合并模板(仅针对于 default 类型的模块)
minify Boolean true 是否输出为压缩的格式
cache Boolean true 是否开启编译缓存
verbose Boolean true 是否打印日志