forked from goofychris/art-template
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
224 lines (216 loc) · 13.4 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>artTemplate - JavaScript Template Engine</title>
<style type="text/css">
body { font-size:14px; color:#666; font-family:'Microsoft Yahei', Tahoma, Arial!important; font-family:Tahoma, Arial; background:#dbdfe3; }
a { color:#039; }
a:hover { color:#06C; }
img { border:none 0; }
pre { position:relative; padding:5px; font-size:12px; border:1px solid #EFEFEF; background:#F9F9F9; z-index:2; border-radius: 5px; }
pre:before, pre:after { visibility:hidden; display:block; content:""; width:0; height:0; border:9px solid transparent; position:absolute; }
pre:before { border-top-color:#EEF7F5; position:absolute; left:18px; bottom:-18px; z-index:2; }
pre:after { border-top-color:#c7dcd3; left:18px; bottom:-19px; z-index:1; }
pre.select { background:#EEF7F5 !important; border:1px solid #D7EAE2; border-right-color:#c7dcd3; border-bottom-color:#c7dcd3; }
pre.select:before, pre.select:after { visibility:visible; }
h1.title, h1.title a { text-align:center; color:#30475e; text-decoration:none; }
h1.title strong { font-size:42px; position:relative; }
h1.title strong:after { content:''; display:block; position:absolute; left:50%; bottom:24px; width:56%; margin-left:-28%; height:1px; box-shadow:0 20px 15px rgba(0, 0, 0, .8); }
h6.subTitle { text-align:center; font-weight:normal; color:#C1C1C1 }
#header, #main, #footer { width:640px; margin:auto; }
#header .summary { padding:20px; background:#30475e; color:#FFF; border-radius: 8px; zoom:1; font-size:14px; line-height:1.5; }
#header .summary:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
#header .summary a { color:#FFF; }
#header .summary a:hover { color:#CCC; }
#header .summary strong { display:inline-block; width:5em; }
#header .summary p { margin:20px 0; }
#main .card { padding:20px; margin-top:60px; background: #FFF; border:1px solid #d1d6db; border-radius: 8px; }
#main .card:after { position:relative; z-index:-1; content: ""; display: block; height: 10px; border-radius: 10px; box-shadow:0 20px 20px rgba(2, 37, 69, .6); }
#main .card h2 { text-align:center; }
#main .card h3 { color:#30475e; }
#main .card ul dl { padding-left:1em; border-left:1px dashed #DDD; }
#main .card ul dt { padding:8px 0; font-weight:bold; }
#main .card ul dd { margin-left:0; }
#main .card ul dd dl { margin-left:2em; }
#footer { padding:20px 0; text-align:center; color:#999; }
#footer .copyright a { color:#999; }
@media only screen and (max-width:980px) {
h1.title {
font-size:24px;
}
#header, #main, #footer {
max-width:100%;
}
img {
max-width:100%
}
}
@media print {
#header .summary, a { color: #000 !important; }
#header, #main, #footer { width:auto; }
#main .card { padding:10px; margin-top:10px; box-shadow:none; border:none 0; border-top: 1px dashed #666; border-radius:0; }
#main .card h2 { text-align:left; }
#main .card:after { display:none; }
h1.title strong:after, #index { display:none; }
}
</style>
<script type="text/javascript">
//<![CDATA[
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-32376609-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
//]]>
</script>
</head>
<body>
<div id="header">
<h1 class="title"><a href="https://github.com/aui/artTemplate"><strong>artTemplate</strong></a></h1>
<div class="summary" id="summary">
<p>artTemplate 是新一代 javascript 模板引擎,它采用预编译方式让性能有了质的飞跃,并且充分利用 javascript 引擎特性,使得其性能无论在前端还是后端都有极其出色的表现。在 chrome 下渲染效率测试中分别是知名引擎 Mustache 与 micro tmpl 的 25 、 32 倍。</p>
<p>除了性能优势外,调试功能也值得一提。模板调试器可以精确定位到引发渲染错误的模板语句,解决了编写模板过程中无法调试的痛苦,让开发变得高效,也避免了因为单个模板出错导致整个应用崩溃的情况发生。</p>
<p>artTemplate 这一切都在 1.7kb(gzip) 中实现!<a href="https://github.com/aui/artTemplate">View on GitHub</a></p>
</div>
</div>
<div id="main">
<div class="card">
<h2>快速上手</h2>
<h3>书写模板 </h3>
<p>模板逻辑语法默认采用原生的 javascript 语法,与微型模板引擎 tmpl 保持一致:模板逻辑语法开始与结束的界定符号为"<%" 与 "%>","<%"后面紧跟"="号则输出变量内容。</p>
<p>页面中 type="text/html" 的脚本标签会被浏览器忽略,可以不用考虑转义也能分行书写模板。例如定义一个 ID 为 "t-list" 的模板:</p>
<pre><script id="t-list" type="text/html">
<ul>
<% for (i = 0; i < list.length; i ++) { %>
<li>条目内容 <%= i + 1 %> :<%= list[i] %></li>
<% } %>
</ul>
</script> </pre>
<h3>渲染模板 </h3>
<p><em>template.render(id, data)</em> </p>
<p>示例:</p>
<pre>var html = template.render('t-list', {
list: ['文艺', '博客', '摄影', '电影', '民谣', '旅行', '吉他']
});</pre>
<p>template.render(id, data) 方法可以被简写成 template(id, data) 。</p>
<p>以上就是 artTemplate 的基本功能使用,接下来是高级功能介绍。</p>
</div>
<div class="card">
<h2>编译模板</h2>
<p><em>template.compile([id], source)</em></p>
<p>页面中内嵌的模板可以直接渲染,如果要在 js 文件中定义模板需要提前编译模板语句。</p>
<p>id 参数是可选的,如果定义了 id 编译后的模板将被缓存到引擎内部,以后随时可以由 template.render(id, data) 方法进行渲染。</p>
<p>示例:</p>
<pre>var render = template.compile('<% for (var i in names) { %><%=name[i]%><% } %>');
var html = render(data);//渲染</pre>
<p>template.compile([id], source) 方法可以被简写成 template([id], source) 。</p>
</div>
<div class="card">
<h2>辅助方法</h2>
<p><em>template.helper(name, callback)</em></p>
<p>在使用原生语法的引擎中,模板中若引用外部对象,随着项目复杂度增加,那时候谁都不能确定模板中的变量到底是数据还是全局对象,这种复杂的依赖关系将为会项目带来巨大的维护成本。而 artTemplate 的模板语句是在沙箱中执行的,意味着强制断绝与全局对象的依赖,模板编写者无法再像原来一样随意读写外部对象,而需要公用的辅助方法统一由template.helper() 进行注册管理,强制语法规范有助于团队更好的协作。</p>
<p>辅助方法一般用来进行字符串替换,如XSS过滤、UBB替换、脏话替换等。例如扩展一个XSS过滤方法:</p>
<pre>template.helper('escapeHTML', (function () {
var rHtml = /&(?!\w+;)|[<>"']/g;
var map = {
"&": "&amp;",
"<": "&lt;",
">": "&gt;",
'"': "&quot;",
"'": "&#x27;"
};
var fn = function (s) {
return map[s] || s;
};
return function (content) {
return typeof content === 'string'
? content.replace(rHtml, fn)
: content;
};
})());</pre>
<p>在模板中的使用方式:</p>
<pre><%= escapeHTML(content) %></pre>
<p>模板中已经内置包含局部模板方法:</p>
<p>include(id, [data]) data 参数可选,默认为传入当前模板数据</p>
</div>
<div class="card">
<h2>设置界定符</h2>
<p>若前端模板语法与后端语法产生冲突,可以修改模板引擎界定符,例如:</p>
<pre>template.openTag = "<!--[";
template.closeTag = "]-->";</pre>
</div>
<div class="card">
<h2>可选语法扩展</h2>
<p>原生语法虽然自由强大,但语句难免冗长,若想使用更加简洁的模板逻辑语法,把语法扩展 <a href="template-extensions.js">template-extensions.js</a> 合并到 <a href="template.js">template.js</a> 即可。</p>
<p>合并语法扩展后,模板界定符号会设置为 "{" 与 "}"。</p>
<p>示例:</p>
<pre>{if title}<br /> <h3>{echo title}</h3><br /> <ul><br /> {each list as val i}<br /> <li>条目内容 {echo i + 1} :{echo val}</li><br /> {/each}<br /> </ul><br />{/if}</pre>
<p>支持的语句:</p>
<ul>
<li><strong>条件</strong>:{if ...} {else if ...} {else} {/if}</li>
<li><strong>遍历</strong>:{each ...} {/each}</li>
<li><strong>包含</strong>:{include ...}</li>
<li><strong>输出</strong>:{echo ..}</li>
</ul>
<p>其中 echo 输出语句可以采用简写,直接使用界定符包括变量即可:</p>
<pre><h3>{title}</h3></pre>
<p>不同的是采用简写的输出语句会进行编码处理,防止 XSS 漏洞。</p>
<p>artTemplate 引擎架构非常灵活,可轻松扩展一套新语法,同时结合 template.helper() 方法可让模板更强大,请参考 <a href="template-extensions.js">template-extensions.js</a> 举一反三。</p>
</div>
<div class="card">
<h2>模板语法规范</h2>
<p>1、不能使用 javascript 关键字作为模板变量,包括 ECMA5 严格模式下新增的关键字: </p>
<pre>break,case,catch,continue,debugger,default,delete,do,else,false,finally,for,function,if,in
,instanceof,new,null,return,switch,this,throw,true,try,typeof,var,void,while,with
,abstract,boolean,byte,char,class,const,double,enum,export,extends,final,float,goto
,implements,import,int,interface,long,native,package,private,protected,public,short
,static,super,synchronized,throws,transient,volatile
,arguments,let,yield</pre>
<p>2、不能读写全局变量,除非给模板定义辅助方法。</p>
</div>
<div class="card">
<h2>自动化打包工具</h2>
<p> 有时候考虑到模板复用或者需要异步加载,可以使用 tools 目录下的自动化合并工具,有 HTML 与批处理两个版本。其中批处理版本可以把页面内嵌的模板抽取出来在同目录生成对应的 js 文件,以便使用 seajs 等脚本加载器异步加载。</p>
<p>若更改了默认模板界定符(<%%>),需要在 merger.html 与 merger.cmd 重新设定下,以便工具能够识别模板逻辑语法。</p>
</div>
<div class="card">
<h2>与 tmpl 兼容</h2>
<p> artTemplate 可以通过简单的设置兼容 john 开发的 tmpl 微型模板引擎: </p>
<pre>var tmpl = template;
template.helper('tmpl', template.render);</pre>
<p>这样可以由 tmpl 平滑迁移到 artTemplate,并原来 tmpl 模板中的套嵌仍然有效,同时也解决了 tmpl 模板不能包含单引号与反斜杠的 BUG。</p>
<p>需要注意的地方:tmpl 模板中原来引用的全局变量会因为 artTemplate 沙箱机制导致无法访问,需要通过 template.helper() 方法进行定义。</p>
</div>
<div class="card">
<h2>演示</h2>
<ul>
<li><a href="./test/test.html">基本例子</a></li>
<li><a href="./test/test-include.html">嵌入子模板</a></li>
<li><a href="./test/test-helper.html">辅助方法</a></li>
<li><a href="./test/test-extensions.html">自定义语法</a></li>
<li><a href="./test/test-debug.html">错误调试</a></li>
<li><a href="./test/test-extensions-debug.html">错误调试[自定义语法]</a></li>
<li><a href="./test/test-tag.html">自定义界定符</a></li>
<li><a href="./test/test-undefined.html">未定义数据输出</a></li>
<li><a href="./test/test-tmpl.html">与tmpl兼容</a></li>
<li><a href="./test/test-compiled.html">编译原理</a></li>
<li><a href="./test/test-speed.html">引擎渲染速度竞赛</a></li>
</ul>
</div>
<div class="card">
<p>若有一定javascript基础,推荐阅读 <a href="http://book.douban.com/subject/6397064/">《基于 MVC 的 JavaScript Web 富应用开发》</a> ,你可以更好的采用模板引擎做到视图与数据分离。</p>
<p>artTemplate 采用中庸之道的设计理念,默认采用 javascript 语法保证编码自由,同时也能通过一定限制保证模板符合规范;亦可采用简单极致的语法,而又不会在基本功能上进行牺牲。</p>
<p>反馈:<a href="http://t.qq.com/tangbin">腾讯微博</a> <a href="http://weibo.com/planeart">新浪微博</a></p>
</div>
</div>
<div id="footer">
<p class="copyright">© <a href="http://cdc.tencent.com">cdc.tencent.com</a></p>
<p class="validators"> <a href="http://validator.w3.org/check?uri=referer"><img
src="http://www.w3.org/Icons/valid-xhtml10" alt="Valid XHTML 1.0 Strict" height="31" width="88" /></a> </p>
</div>
</body>
</html>