2.1.0 • Published 8 years ago

jsview v2.1.0

Weekly downloads
1
License
MIT
Repository
github
Last release
8 years ago

JSTPL 2.1.0

极速 JavaScript Template Engine V2.1.0 (最新) https://codeload.github.com/huangbh/jstpl/zip/master

##第一章 基本示例

本引擎支持两种方式的模板定义:
第一种, 函数式:
function tpl_test_func(mydata){
	/* title is: {mydata.title} 
	*/
	var ls=mydata.list;
	for(var i=0;i<ls.length;i++){
		/* id is {ls[i].id} and name is {ls[i].name} {N}*/ 
	}
	/** good work! */
}
然后调用方式如下:
	var data={title:"JSTPL", list:[{id:1,name:"laohuang"},{id:2,name:"JSTPL"}]}
	var tpl_func = $tpl(tpl_test_func);
	var html_func = tpl_func(data); 
	
第二种,DOM声明:
<script type="text/jstpl" id="tpl_test_dom" jstpl="mydata">
	title is :{mydata.title}
	<% var ls=mydata.list; 
	for(var i=0;i<ls.length;i++){ 
	%> id is {ls[i].id} and name is {ls[i].name}
	<% } %>%
	good work!
</script>

其调用方式如下:
	var tpl_dom = $tpl('tpl_test_dom');
	var html_dom = tpl_dom(data);

以上调用, 会产生相同的结果

请注意到函数的参数和 DOM 模板的 jstpl 属性,都是模板的参数定义,是可以有无限多个的,逗号隔开即可.
你甚至可以在模板里使用 arguments ,以获取随意长的不定参数
function tpl_test(arg1,arg2){/*{arg1}/{arg2}/{arguments.length}*/}

另外 DOM 模式下, jstpl 属性如果没有,将缺省给一个参数名为 data:
<script type="text/jstpl" id="tpl_test_dom">{data}</script>

<特别注意>
从2.1.0开始支持 with 方式, 只是需要做如下设置:
$tpl.set('use_with',true);
这样无论 function 还是 dom, 都可以不需要声明参数名称了,例如上面的例子,可以改写为如下:
function tpl_test_func(){
	/* title is: {title} 
	*/
	var ls=list;
	for(var i=0;i<ls.length;i++){
		/* id is {ls[i].id} and name is {ls[i].name} {N}*/ 
	}
	/** good work! */
}
dom 是同样的, 也就是说可以不用声明 jstpl='data'了.

##第二章 基本语法

(1)
从上面的示例, 其实可以看出, 
在函数式下, 除了模板文本都是放在/* */里面的,其余都是正常的js代码, 
(注意//这样的注释也是正常的 js 代码)
解析后所有的模板文本会自动拼接并返回
而{...}中的内容,则表示为模板文本中的变量

而DOM声明模式下恰好相反, 所有的js代码都放在 <% %> 中间,
告诉大家一个秘密,其实解析时,
不过是把函数式中的/*和*/换成了 %>和<%而已,剩下的就好理解了.

(2)
对于函数式而言,简单用法可以如下:
var str = $tpl(function(mydata){if(mydata){/*{mydata}*/}})("laohuang");

对于DOM 方式而言,简单用法可以直接用文本解决:
var str = $tpl("mydata", "<%if(mydata){%>{mydata}<%}%>")("JSTPL");

(3)
无论哪种方式,$tpl(...)都将产生一个函数,确保这样,
因为是函数,你可以按照函数方式任意调用,包括 apply 和 call方式.

(4)
另外必须注意的是,由于是用 new Function(...)方式生成的函数,
其作用域将是全局的,不要试图在模板函数里引用局部作用域的变量,
你可以通过传参或者apply和 call 设置 this 的方式来使用局部变量.

##第三章 转义处理

对于有些模板文本, 其实大家不希望解析, 尤其存在{} 这类特殊字符时
第一类的办法是整体不解析
	如在函数式下, 是用 /** */来包含, 比如 /**{data.title}*/将不会被解析
	如在DOM下, 是判断第一个字符是否为 % , 
	比如 ...%>% {data.title}<% ..., 
	其实大家看得出来跟上面一样,只不过是把*变成了%而已


第二类办法是在{}中通过\转义, 形式为{\...}, 
	比如{\*} {\/}{\\}, {\<hello>},{\%},都不会被解析为js, 而只是简单地认为是一个文本了
	这个办法产生一些值得注意的小技巧,
	比如如果我要在模板文件的第一字符输出*或%或/或\,
	都可以通过{\...}的形式来转义

当然上面办法仍有不逮之处, 尤其对于 {} 这两个字符而言. 
系统为这种情况准备了两个特殊的变量 A='{', B='}', 这样如果要输出{}, 你可以用{A}和{B}来代替了

在实际模板代码编写过程中,仍有一种情况会产生麻烦,
就是输出</script>,当然拆开是好办法,我介绍最好的写法是这样的</{\script}>这样看起来比较好一点

##第四章 保留字符

本模板的实现最终是生成js函数,而且语法也是极度自由,只有一条规则需要大家遵守: 

A-Z的26个单个大写字母和单个下划线_是保留的,在生成函数时会用到!

也就是说模板中无论什么时候,你都不要试图用单个大写字母和单个下划线来声明变量, 
注意是单个字母, 双字母是随你的.

简单介绍一下系统目前用到的单字母系统变量:

H 为最终生成html的内容容器
J 表示为JSTPL环境,也就是公共空间,外部设置的参数或函数通过它来访问
A 表示 { 
B 表示 }
_ 表示为字符串合并函数 _(...)
R 表示 \r
N 表示 \n
X 表示 *
P 表示 %

这些是方便写模板用, 比如{N}以输出一个换行符, {X}输出一个*, {A}和{B}上面介绍过的,输出{和}
H是最终生成结果,在老版IE下是一个数组,其他都是字符串

##第五章 特殊解析

第一类, 模板文本如何赋值给一个中间变量?
	方式是通过 \ 转义, 例子如下
	/*\x=\hello,{name}*/
	...%>\x=\hello,{name}<%...
	alert(/*\\hello,{name}*/)
	简单地说该语法将会把第二个\之后的内容解析后返回, 
	且第一个\必须是模板文本的第一个字符
	当然还有如下用法:
	/*\var x=\...*/
	/*\x+=\...*/

第二类, 系统还提供了另外一个转义符号 / 和 _(...)的系统函数,第一类的例子也可以改写为:
	x=_(/*/hello,{name}*/)
	x=_(%>/hello,{name}<%)
	alert(_(/*/hello,{name}*/))

	如果你有一个函数是类似于_(...)接收不定参数的, 例如myfunc(...),那么你就可以直接用这种方式来做
	myfunc(/*/hello,{name}*/);

##第六章 嵌套复用

模板嵌套有两种方式
一种是直接调用$ tpl(...) 的方式,这种方式有点 hard code 的味道,
	不过简单粗暴直接,简单情况下是不错的.例如:
	/*{$tpl(my_tpl_func)(data)}*/
	
另一种是采取模板参数化方式,具体例子如下:
	function tpl_panel(data, nested){
		/*<div>
			<span>{data.title}</span>
			<div>{nested(data.list)}</div>
		</div>*/
	}
	在调用的时候可以这样:
	var tpl_nested = ...// 可以来自function 或 DOM, 
	var html = $tpl(tpl_panel)(data,tpl_nested);
	
这么一来, tpl_panel就变成一个通用的模板,可以完全被复用在各种地方了

当然这个nested也可以是你自己随便写的函数...
你还可以把更多函数当做参数...
你甚至可以由此引入各种运行时环境...

##第七章 控制输出

H是最终输出结果存储的地方, 或许有时候你需要自己来操作这个变量(当然不建议这么干),也可以.
只是你只有一种办法来自己控制添加数据, 那就是H=H.concat(...)函数
其他的都不支持.

##第八章 公用空间

为模板支持了一个公共空间, 以便于外部向模板内部传递一些公用的数据,设置或方法
在外部可以通过如下函数来设置:
$tpl.set(key,value)
$tpl.set({key:value,...})

$tpl.J(key,value)
$tpl.J({key:value,...})

可以看出 set(...) 和 J(...)等价,
这么做是因为在模板内部, 访问公用空间的方法就是:
var v = J.key;
var v = J.key.p1.p2;
var v = J.key.func(...);
var v = J.key(...);
没错,就是通过 JSTPL 环境来调用的.

当然,这里的公用空间用重要的用途,
比如$tpl.set('use_with',true);
会被用来设置模板的参数将忽略根参数名,而直接访问属性.
在 Node.js 环境中设置一些其他参数.

##第九章 支持 Node.js

一般引入方式如下: var $tpl = require('./jstpl');
在 Node.js下有如下要点:
0, 缺省情况下是使用 with 模式的, 
	也就是说 $tpl.set('use_with',true);是自动执行.
1, 可设置视图的 root 目录, 
	例如 $tpl.set('root', __dirname + '/views');
2, 可设置视图文件名的后缀, 
	例如 $tpl.set('suffix', '.htm'); 缺省值是 .htm
3, 可设置视图的 header和 footer, 也是一个视图, 
	例如 $tpl.set('header', 'myheader'); 
	这里的 myheader 应当是在 root 目录下的 myheader.htm
4, 调用视图方法为: 
	var html = $tpl.render('view1','view2',...)(mydata); 
	这个方法会自动在前后调用 header 和 footer 视图
5, 单独调用任意一个视图
	var html = $tpl.view('myview')(mydata);
	这个方法不会自动在前后调用 header 和 footer
6, 缺省情况下,视图会按照路径自动缓存, 但如果设置$tpl.set('debug',true);
	则将每次访问都重新加载,这方便于做开发
7, 视图内部新增了一个特殊方法,以便于嵌入其他视图
	例如:{$include('myheader')}
	就可以嵌入自己的视图了
8, 还增加了如下视图生成方法,方便于配合express的 res.render(...)
	var tpl = $tpl.compile(txt);
	var html = tpl.render(mydata);//目前尚未支持自动加 header 和 footer...

##第十章 王婆卖瓜

1,本模板的实现不依赖于任何其他框架
2,经过测试,目前为止本模板的解析与渲染速度表现最好
3,函数式的模板实现可以让模板以 js 的方式下载,降低页面加载的模板数量
4,模板的两种方式极大地扩展了模板的自由度,且两种模板之间转换非常容易
5,模板完全使用 JavaScript 来控制条件与循环,赋予开发者最大的自由度
6,函数式模板能够借助现有的各种JavaScript 编译环境规避大多数语法问题
7,最终生成的模板实际是一个JavaScript函数,调用方式极度自由
8,非常自由的模板嵌套调用方式,能大大降低模板的代码量,便于模块化管理
9,自动判断执行环境,同时支持 Node.JS和浏览器环境