用js解析smarty语法的模板,达到服务端smarty与客户端共享同一套模板的目的
analysis smarty's grammar with js, then you can use smarty both on server and client
非常感谢DOT引擎,其实smartyMonkey的思路和很多写法都借鉴了DOT。
安装(install):
可以通过npm安装(you can install with npm):
npm install smartymonkey
或者直接下载使用。
or just download it
在服务端(node环境下)我们可以直接引用smartyMonkey模块,require('src/smartyMonkey');
该模块的导出,是一个create方法,可以创建smartyMonkey的实例
in a server enviroment(node enviroment),we can just require smartyMonkey.require('src/smartyMonkey');
this module,export a create method, which can create a instance of smartyMonkey
如(for example):
var smartyMonkey = require('smartyMonkey');
var sm = smartyMonkey.create();
var tpl_fn = sm.compile(data);
var out = tpl_fn('monkey');
在客户端(浏览器环境下),smartyMonkey会暴露一个smartyMonkey对象到执行js的上下文中,一般是window,这个对象同样有一个create方法:
on a client enviroment, you include smartyMonkey in your page, and then smartyMonky will export a object to window, this object is window.smartyMonkey, it also have a create method, which can create a instance of smartyMonkey
<script src="./smartyMonkey.js"></script>
<script>
var smartyMonkey = window.smartyMonkey
var sm = smartyMonkey.create();
var tpl_fn = sm.compile(data);
var out = tpl_fn('monkey');
</script>
小贴士(Tips):
在实际使用过程中,如果是在客户端编译的话,那么我们肯定要把模板的源代码传到客户端,但是我们写的模板代码,会在服务端被smarty解析掉,所以,为了把模板源代码传送到客户端,我们可以使用smarty的literal标签,防止自己的smarty模板在服务端被解析掉。
###① 输出(print)
-
首先,我们要写一个模板(hello.tpl):
hello {%*test*%}{%$it%} -
然后,我们调用smatyMonkey对模板进行编译,及使用:
var smartyMonkey = require('../../src/smartyMonkey');
var fs = require('fs');
fs.readFile(
'./back.tpl',
'utf-8',
function (err, data) {
var sm = smartyMonkey.create();
var tpl_fn = sm.compile(data);
var out = tpl_fn('monkey');
console.log(out);
}
); -
输出:
hello monkey
###② 循环(loop)
-
首先,我们要写一个模板(loop.tpl):
{%foreach $loop1 as $key => $value%}
<div>key is: {%$key%}</div>
<div>val is: {%$value%}</div>
{%/foreach%} -
接着我们编译一下含有foreach循环的模板(index.js): var smartyMonkey = require('../../src/smartyMonkey');
var fs = require('fs');
fs.readFile(
'./loop.tpl',
'utf-8',
function (err, data) {
sm = smartyMonkey.create();
var tpl_fn = sm.compile(data, {varnames: ['loop1']});
var out = tpl_fn(['h', 'e', 'l', 'l', 'o']);
console.log(out);
}
); -
输出:
<div>key is: 0</div> <div>val is: h</div> <div>key is: 1</div> <div>val is: e</div> <div>key is: 2</div> <div>val is: l</div> <div>key is: 3</div> <div>val is: l</div> <div>key is: 4</div> <div>val is: o</div>
foreach的另一种写法:
1. 模板:
{%foreach from=$loop1 key=key item=value name=loop1%}
<div>key is: {%$key%}</div>
<div>val is: {%$value%}</div>
<div>index is: {%$smarty.foreach.loop1.index%}</div>
{%/foreach%}
2. 调用:
同上
3. 输出:
<div>key is: 0</div> <div>val is: h</div> <div>index is: 0</div> <div>key is: 1</div> <div>val is: e</div> <div>index is: 1</div> <div>key is: 2</div> <div>val is: l</div> <div>index is: 2</div> <div>key is: 3</div> <div>val is: l</div> <div>index is: 3</div> <div>key is: 4</div> <div>val is: o</div> <div>index is: 4</div>
###③ 条件语句(condition)
-
模板中的代码(code in template): {%if $a%}
this is a:{%$a%}
{%else%}
there is no a
{%/if%} -
调用:
.....
var tpl_fn = sm.compile(data, {varnames: ['a']});
var out = tpl_fn('aval');
console.log('has a:', out);
var out = tpl_fn();
console.log('no a:', out);
..... -
输出:
has a: this is a:aval
no a: there is no a
###④ 赋值(interpolate)
- 模板(interpolate.tpl):
{%$b = 'test'%}
b is :{%$b%}
{%$a = $b%}
a is :{%$a%}
{%$a=$c%}
new a is: {%$a%}
- 调用:
.....
var tpl_fn = sm.compile(data, {varnames: ['c']});
var out = tpl_fn('cval');
console.log(out);
..... - 输出:
b is :test a is :test new a is: cval
###⑤ 多个参数(multiple parameters)
smartyMonkey支持传入多个参数,只要compile的时候,指定第二个参数即可:
- 模板:
a is {%$a%}
b is {%$b%}
c is {%$c%}
2.调用:
.....
var tpl_fn = sm.compile(data, {varnames: ['a', 'b', 'c']});
var out = tpl_fn('aval', [1,2,3,4], 99);
console.log(out);
.....
3. 输出:
a is avalb is 1,2,3,4c is 99
###⑥ 过滤器(filter)
可以在模板中增加过滤器与过滤器所对应的函数,或语句。内置解析过滤器的只有一个count,被解析为js的.length
- 模板:
a's length is: {%$a|count%} 2.调用:
.....
var tpl_fn = sm.compile(data, {varnames: ['a']});
var out = tpl_fn('aval');
console.log(out);
..... - 输出:
a's length is: 4
注:我们可以通过扩展filter,来增加模板的功能
例:
- 模板:
{%$a|encodeURIComponent%}
2.调用:
var sm = smartyMonkey.create({
filterMap: {
encodeURIComponent: function (code) {
return 'encodeURIComponent(a)';
}
}
}); - 输出:
http%3A%2F%2Fwww.baidu.com%2Fs%3Fwd%3DsmartyMonkey
smartyMonkey支持扩展语法与处理器,也可以覆盖默认的语法和处理器。
我们通过在create的时候添加regxs与execFns,来增加/替换 替换规则与替换函数。可以达到对语法的扩充。
例:
var smartyMonkey = require('../../src/smartyMonkey');
var fs = require('fs');
fs.readFile(
'./extend.tpl',
utf-8',
function (err, data) {
var sm = smartyMonkey.create({
regxs: {
smComments: /{%*[\s\S]*?*%}/g
},
execFns: {
smComments: function () {
return '-----注释替换-----';
}
}
});
var tpl_fn = sm.compile(data, {varnames: ['loop1', 'a']});
var out = tpl_fn(['h', 'e', 'l', 'l', 'o'], '19');
console.log(out);
}
);
输入(extend.tpl): {%test test%}
输出: -----注释替换-----
如有任何问题,请及时联系 if you has any question please contact with me