🧨1. 介绍
https://github.com/aui/art-template
它采用作用域预声明来优化模板渲染速度,从而获得来接近JavaScript极限的运行性能,并同时支持nodejs和浏览器
1.1.特性
模板引擎是第三方模块,让开发者以更友好的方式拼接字符串,是代码啊更清晰,更加易于维护
1.2. 模板
art-template同时支持两种语法,标准语法可以让模板更容易读写,
原始语法具有强大的逻辑处理能力
标准语法
{{if user}}
<h2>{{user.name}}</h2>
{{/if}}
原始语法
<% if (user) { %>
<h2><%= user.name %></h2>
<% } %>
1.3.渲染模板
var template = require('art-template');
var html = template(__dirname + '/tpl-user.art', {
user: {
name: 'y'
}
});
1.4.核心方法
// 基于模板名渲染模板
template(filename, data);
// 将模板源代码编译成函数
template.compile(source, options);
// 将模板源代码编译成函数并立刻执行
template.render(source, data, options);
🧨2.安装
2.1.npm
npm install art-template --save
2.2.在浏览器中实时编译
<div id="content">
</div>
<!-- 如果渲染模板的时候,传过来的数据集中有user数据,那么在页面中显示h2标签,h2标签里面是用户的名字 -->
<script id="demo" type="text/html">
{{if user}}
<h2>{{user.name}}</h2>
{{/if}}
<% if (user) { %>
<h2><%= user.name %></h2>
<% } %>
<h1>{{title}}</h1>
<ul>
<!-- {{each list as value i}}
<li>索引{{i+1}}:{{value}}</li>
{{/each}} -->
{{each list}}
<li>索引{{$index+1}}:{{$value}}</li>
{{/each}}
</ul>
</script>
<script>
var html = template("demo", {
title: "我是标题",
user: {
name: "张三"
},
list:["张三","李四","王五","马六"]
})
document.getElementById("content").innerHTML = html
</script>
🧨3. 语法
art-template 支持标准语法与原始语法。标准语法可以让模板易读写,而原始语法拥有强大的逻辑表达能力。标准语法支持基本模板语法以及基本 JavaScript 表达式;原始语法支持任意 JavaScript 语句,这和 ejs一样。
3.1.输出
标准语法
{{value}}
{{data.key}}
{{data['key']}}
{{a ? b : c}}
{{a || b}}
{{a + b}}
原始语法
<%= value %>
<%= data.key %>
<%= data['key'] %>
<%= a ? b : c %>
<%= a || b %>
<%= a + b %>
模板一级特殊变量可以使用 $data
加下标的方式访问:
{{$data['user list']}}
3.2.原文输出
标准语法
{{@ value }}
原始语法
<%- value %>
原文输出语句不会对
HTML
内容进行转义处理,可能存在安全风险,请谨慎使用。
3.3.条件
标准语法
{{if value}} ... {{/if}}
{{if v1}} ... {{else if v2}} ... {{/if}}
原始语法
<% if (value) { %> ... <% } %>
<% if (v1) { %> ... <% } else if (v2) { %> ... <% } %>
3.4.循环
part2_syntax/app.js/循环
标准语法
{{each target}}
{{$index}} {{$value}}
{{/each}}
原始语法
<% for(var i = 0; i < target.length; i++){ %>
<%= i %> <%= target[i] %>
<% } %>
target
支持array
与object
的迭代,其默认值为$data
。$value
与$index
可以自定义:{{each target val key}}
。
3.5.变量
标准语法
{{set temp = data.sub.content}}
原始语法
<% var temp = data.sub.content; %>
3.6.模板继承
// 标准语法
{{extend './layout.art'}}
{{block 'head'}} ... {{/block}}
/// 原始语法
<% extend('./layout.art') %>
<% block('head', function(){ %> ... <% }) %>
模板继承允许你构建一个包含你站点共同元素的基本模板“骨架”。
渲染 index.art 后,将自动应用布局骨架。
3.7.子模板
. data
数默认值为 $data
;标准语法不支持声明 object
与 array
,只支持引用变量,而原始语法不受限制。
标准语法
{{include './header.art'}}
{{include './header.art' data}}
原始语法
<% include('./header.art') %>
<% include('./header.art', data) %>
3.8.过滤器
注册过滤器
template.defaults.imports.dateFormat = function(date, format){/*[code..]*/};
template.defaults.imports.timestamp = function(value){return value * 1000};
过滤器函数第一个参数接受目标值。
🎗标准语法
{{date | timestamp | dateFormat 'yyyy-MM-dd hh:mm:ss'}}
{{value | filter}}
过滤器语法类似管道操作符,它的上一个输出作为下一个输入。
🎗原始语法
<%= $imports.dateFormat($imports.timestamp(date), 'yyyy-MM-dd hh:mm:ss') %>
4.调试
template.defaults.debug
art-template 内建调试器,能够捕获到语法与运行错误,并且支持自定义的语法。
在 NodeJS 中调试模式会根据环境变量自动开启:process.env.NODE_ENV !== 'production'
设置 `template.defaults.debug=true` 后,等同于:
{
"cache": false,
"minimize": false,
"compileDebug": true
}
5.模板变量
template.defaults.imports
模板通过 $imports
可以访问到模板外部的全局变量与导入的变量。
// 导入变量
template.defaults.imports.log = console.log;
<% $imports.log('hello world') %>
内置变量清单
$data
传入模板的数据$imports
外部导入的变量以及全局变量print
字符串输出函数include
子模板载入函数extend
模板继承模板导入函数block
模板块声明函数
6. 解析规则
art-template 可以自定义模板解析规则,默认配置了原始语法与标准语法。
修改界定符
// 原始语法的界定符规则
template.defaults.rules[0].test = /<%(#?)((?:==|=#|[=-])?)[ \t]*([\w\W]*?)[ \t]*(-?)%>/;
// 标准语法的界定符规则
template.defaults.rules[1].test = /{{([@#]?)[ \t]*(\/?)([\w\W]*?)[ \t]*}}/;
它们是一个正则表达式,你可以只修改界定符部分。例如修改 <%
%>
为 <?
?>
:
var rule = template.defaults.rules[0];
rule.test = new RegExp(rule.test.source.replace('<%', '<\\\?').replace('%>', '\\\?>'));
✨✨✨
其中test
是匹配字符串正则,use
是匹配后的调用函数。
关于 use
函数:
- 参数:一个参数为匹配到的字符串,其余的参数依次接收
test
正则的分组匹配内容 返回值:必须返回一个对象,包含code与output
两个字段:
code
转换后的 JavaScript 语句output 描述 code的类型,可选值:
'escape'
编码后进行输出'raw'
输出原始内容false
不输出任何内容
7.压缩页面
template.defaults.minimize
art-template 内建的压缩器可以压缩 HTML、JS、CSS,它在编译阶段运行,因此完全不影响渲染速度,并且能够加快网络传输。
开启
template.defaults.minimize = true;
配置
参见:https://github.com/kangax/html-minifier
默认配置
template.defaults.htmlMinifierOptions = {
collapseWhitespace: true,
minifyCSS: true,
minifyJS: true,
// 运行时自动合并:rules.map(rule => rule.test)
ignoreCustomFragments: []
};
8.API
8.1.template(filename, content)
根据模板名渲染模板。
- 参数:
(1)
{string} filename
(2){Object,string} content
- 返回值:
(1) 如果
content
为Object
,则渲染模板并返回string
(2) 如果content
为string
,则编译模板并返回function
浏览器版本无法加载外部文件,filename
为存放模板的元素id
8.2. .compile(source, options)
编译模板并返回一个渲染函数。
- 参数
(1)
{string} source
(2){Object} options
- 返回值:
{function}
示例
var render = template.compile('hi, <%=value%>.');
var html = render({value: 'aui'});
8.3. .render(source, data, options)
编译并返回渲染结果。
参数
:
{string} source
{Object} options
- 返回值:
{string}
示例
var html = template.render('hi, <%=value%>.', {value: 'aui'});
.defaults
模板引擎默认配置。参考 选项。
- 类型:
{Object}
8.4. .extension
给 NodeJS require.extensions
注册的模板渲染函数。
- 类型:
{Object}
示例
加载 .ejs
模板:
var template = require('art-template');
require.extensions['.ejs'] = template.extension;
var view = require('./index.ejs');
var html = view(data);
.art
默认被注册,可以直接使用:
var template = require('art-template');
var view = require('./index.art');
var html = view(data);
需要注意的是:此功能仅对 NodeJS 生效
9.express-art-template
- 为了使art-template模板引擎能够更好的和Express框架配合,模板引擎官方在原art-template模板引擎的基础上封装了express-art-template.
- 使用npm install art-template express-art-template命令进行安装。
- 在一个项目中可以使用多个模板引擎
express的engine()方法:当渲染后缀为art的模板时使用express-art-template
第一个参数是模板的后缀第二个参数是使用的什么模板
express的set()方法:
- 设置模板存放目录
(1) 第一个参数是设置存放模板目录的文件夹
(2) 第二个参数是存放模板的绝对路径
- 设置默认的模板后缀,设置模板时,如果没有写模板后缀就使用当前设置的模板后缀
(1) 第一个参数是 默认模板的配置项
(2) 第二个参数是后缀的名字
express的render()方法:
渲染模板(在该方法的内部会自动拼接后缀、模板与数据的拼接、把结果相应给客户端)
- 参数是模板名称。
- 对象,即 向模板中传递的数据
// 引入express框架
const express = require('express');
// 引入路径模块
const path = require('path');
// 创建服务器网站
const app = express();
// 1. 告诉express框架使用什么模板引擎渲染什么后缀的模板文件
app.engine('art',require('express-art-template'))
// 2. 告诉express框架模板存放的位置是什么
// 第一个views是固定的,是express的配置项名字,告诉express框架模板存放的位置
// 第二个views是文件夹的名字
app.set('views',path.join(__dirname,'views'))
// 3. 告诉express框架模板的默认后缀是什么 ( 方便在渲染模板的时候,省去后缀 )
app.set('view engine','art');
// 创建一个路由
app.get('/index',(req,res) => {
// 渲染模板 (可以省掉art) -- res.render()
// 1.拼接模板路径
// 2.拼接模板后缀
// 3.哪一个模板和哪一个数据进行拼接
// 4.将拼接结果响应给客户端
res.render('index',{
// 模板要展示的数据
msg: 'message'
})
})
app.get('/list',(req,res) => {
res.render('list',{
msg: 'list page'
})
})
// 监听端口
app.listen(3000);