阅读更多

3顶
0踩

Web前端

转载新闻 编写一个简单的JavaScript模板引擎

2015-03-23 11:17 by 副主编 mengyidan1988 评论(3) 有5373人浏览
随着Nodejs的流行,JavaScript在前端和后端都开始流行起来。有许多成熟的JavaScript模板引擎,例如Swig,既可以用在后端,又可以用在前端。

不过很多时候,前端模板仅仅需要简单地创建一个HTML片段,用Swig这种全功能模板有点大材小用。我们来尝试自己编写一个简单的前端模板引擎,实际上并不复杂。

在编写前端模板引擎代码之前,我们应该想好如何来调用它,即这个模板引擎的接口应该是什么样的。我们希望这样调用它:
// 创建一个模板引擎:
var tpl = new Template('<p>Today: { date }</p>\n<a href="/{ user.id|safe }">{ user.company }</a>');
// 渲染得到HTML片段:
var model = {
    date: 20150316,
    user: {
        id: 'A-000&001',
        company: 'AT&T'
    }
};
var html = tpl.render(model);
console.log(html);
// <p>Today: 20150316</p>
// <a href="/A-000&001">AT&amp;T</a>

因此,一个模板引擎就是把一个字符串中的变量用model的变量替换掉,就完成了。

像Swig这种类Jinja2的模板引擎,它可以替换{{ model.prop }}这样的变量。

我们选用{ model.prop }来实现我们自己的变量替换,基本思想是用一个正则表达式来匹配{ xxx.xxx }:
var re = /\{\s*([a-zA-Z\.\_0-9()]+)\s*\}/m
var match = re.exec('a { template } string');

如果正则匹配成功,则match不为空,match[0]是匹配到的字符串{ template },match[1]是捕获的变量template,match.index是匹配的索引。

只要不断地匹配到变量,然后用model的内容替换,就可以得到最终的HTML。但是,分析user.addr.zipcode然后去model中查找并不容易。而且,模板应该可以预编译,这样,后续渲染速度就会很快。

JavaScript允许用new Function('source')来通过字符串创建一个函数,这个函数和我们用function ()定义的函数是一模一样的,因此,一个模板引擎的编译过程就是创建一个函数,然后调用该函数就实现了模板渲染。

需要编译的函数代码应该像这样:
function () {
    var r = [];
    r.push('<p>Today: ');
    r.push(this.date);
    r.push('</p>\n<a href="/');
    r.push(this.user.id);
    r.push('">');
    r.push(this.user.company);
    r.push('</a>');
    return r.join('');
}

注意到变量名从variable.prop变成了this.variable.prop,是因为调用该函数时我们会把model绑定到this变量上。

因此,模板引擎的代码如下:
function Template(tpl) {
    var
        fn,
        match,
        code = ['var r=[];'],
        re = /\{\s*([a-zA-Z\.\_0-9()]+)\s*\}/m,
        addLine = function (text) {
            code.push('r.push(\'' + text.replace(/\'/g, '\\\'').replace(/\n/g, '\\n').replace(/\r/g, '\\r') + '\');');
        };
    while (match = re.exec(tpl)) {
        if (match.index > 0) {
            addLine(tpl.slice(0, match.index));
        }
        code.push('r.push(this.' + match[1] + ');');
        tpl = tpl.substring(match.index + match[0].length);
    }
    addLine(tpl);
    code.push('return r.join(\'\');');
    // 创建函数:
    fn = new Function(code.join('\n'));
    // 用render()调用函数并绑定this参数:
    this.render = function (model) {
        return fn.apply(model);
    };
}

现在,这个简单的模板引擎已经可以工作了。但是它还有几个小问题需要解决,一是默认的变量在替换时应该做HTML转义,二是如果某些不需要转义的变量,可以用{ user.id|safe }这样的表达式表示user.id无需转义。

经过HTML转义和{ variable|safe }处理的最终代码如下:
function Template(tpl) {
    var
        fn,
        match,
        code = ['var r=[];\nvar _html = function (str) { return str.replace(/&/g, \'&amp;\').replace(/"/g, \'&quot;\').replace(/\'/g, \'&#39;\').replace(/</g, \'&lt;\').replace(/>/g, \'&gt;\'); };'],
        re = /\{\s*([a-zA-Z\.\_0-9()]+)(\s*\|\s*safe)?\s*\}/m,
        addLine = function (text) {
            code.push('r.push(\'' + text.replace(/\'/g, '\\\'').replace(/\n/g, '\\n').replace(/\r/g, '\\r') + '\');');
        };
    while (match = re.exec(tpl)) {
        if (match.index > 0) {
            addLine(tpl.slice(0, match.index));
        }
        if (match[2]) {
            code.push('r.push(String(this.' + match[1] + '));');
        }
        else {
            code.push('r.push(_html(String(this.' + match[1] + ')));');
        }
        tpl = tpl.substring(match.index + match[0].length);
    }
    addLine(tpl);
    code.push('return r.join(\'\');');
    fn = new Function(code.join('\n'));
    this.render = function (model) {
        return fn.apply(model);
    };
}

现在就可以用我们预设的代码来使用这个模板引擎了。不过,把模板写在字符串中也不是一个好办法。最佳解决方案是利用<script>标签,把模板写在里面,注意一定要加上type="text/plain":
<script id="tpl" type="text/plain">
    <p>Today: { date }</p>
    <a href="/{ user.id|safe }">{ user.company }</a>
</script>

然后,用jQuery来获得模板内容并渲染:
var tpl = new Template($('#tpl').html());
var s = tpl.render({
    date: 20150101,
    user: {
        id: 'A-000&001',
        company: 'AT&T'
    }
});
$('#other').html(s);

这样,我们就用不到30行代码实现了一个简单的JavaScript模板引擎。

来自:廖雪峰的官方网站
3
0
评论 共 3 条 请登录后发表评论
3 楼 Jelly_oy 2015-03-24 14:39
希望楼主提供一个完整下载
2 楼 Jelly_oy 2015-03-24 14:39
同问,怎么用啊?
1 楼 yizhyi 2015-03-23 12:23
怎么用呀?

发表评论

您还没有登录,请您登录后再发表评论

相关推荐

  • 教你使用javascript简单写一个页面模板引擎

    我需要的是一个小巧的,纯粹以Javascript编写的东西,能够直接运行在浏览器上。当我某天偶然发现John Resig的这篇博客,我惊喜地发现,这不正是我苦苦寻找的东西嘛!我稍稍做了一些修改,代码行数差不多20行左右。...

  • myTpl.js:用Javascript编写的简单模板引擎

    简单的模板引擎,用Java编写的逻辑有限。 在可以找到用PHP编写的版本。 用法 var tpl = myTpl ( 'tplDir' ) ; var data = { "name" : "John Doe" } ; tpl . load ( "test" , "myDiv" , data ) ; 模板文件 Hello! My...

  • 详解Javascript模板引擎mustache.js

    主要为大家介绍了Javascript模板引擎mustache.js,mustache.js是一个简单强大的Javascript模板引擎,使用它可以简化在js代码中的html编写,压缩后只有9KB,非常值得在项目中使用,需要的朋友可以参考下

  • boxwood:用JavaScript编写的逐步增强HTML模板引擎

    用JavaScript编写的逐步增强HTML模板引擎 目录 背景 该库是旨在生成最佳渲染功能的编译器。 该函数应进行缓存和重用,以提供比其他模板语言更好的性能。 它也可以在各种上下文中使用,以呈现html页面,电子邮件...

  • 探究Javascript模板引擎mustache.js使用方法

    主要为大家介绍了Javascript模板引擎mustache.js使用方法,mustache.js是一个简单强大的Javascript模板引擎,使用它可以简化在js代码中的html编写,压缩后只有9KB,非常值得在项目中使用,感兴趣的小伙伴们可以参考...

  • myTemplate:JavaScript 模板引擎

    javascript 模板引擎目录特性源码简洁明了,学习成本极低不使用with,因此模板中可以输出全局变量支持自定义分隔符默认HTML转义(防XSS攻击)支持Node RequireJS支持所有流行的浏览器快速上手编写模板使用一个type=...

  • luigi:luigi (~417B) 是一个用 JavaScript 编写的 HTML5 的简约模板引擎

    luigi (~417B) 是一个用 JavaScript 编写的 HTML5 的简约模板引擎。 安装 bower install luigi 用法 &lt;!doctype html &gt; &lt; meta charset =' utf-8 ' &gt; &lt;!-- Target View --&gt; &lt; div&gt; Loading template....

  • Hanjst:Han JavaScript Template Engine 汉吉斯特 JavaScript模板引擎

    :person_raising_hand: 汉斯特 韩语JavaScript模板语言和引擎 。 汉是我妻子的姓,也是我女儿和儿子的名字之一。 汉在汉人拼音中也是华人。 :person_raising_hand: Hanjst的目的是...的最后一个元素: 单句 &lt; sc

  • jiko:全功能JavaScript模板引擎

    其目的是向Javascript程序员提供一种使用与服务器端最先进的模板引擎(如Jinja和Mako)一样强大的引擎编写模板的方法。 &lt;&#37; var rows = _.map(_.range(0, 10), function(el) { return _.range(0, 10); });...

  • jsmart:jSmart是Smarty Javascript模板引擎,是PHP Smarty模板引擎的端口

    jSmart是Smarty模板引擎到Javascript的端口,Javascript是一个JavaScript模板库,它支持模板以及著名PHP模板引擎所有功能(函数,变量修饰符等)。 jSmart完全用JavaScript编写,没有任何DOM /浏览器或第三方...

  • Beetl模板引擎-其他

    Beetl本身还具有很多独特功能来完成模板编写和维护,这是其他模板引擎所不具有的。2、非常简单:类似Javascript语法和习俗,只要半小时就能通过半学半猜完全掌握用法。拒绝其他模板引擎那种非人性化的语法和习俗。3...

  • smarty4Js:一个最像 smarty 的 JavaScript 模板

    JavaScript 模板引擎 支持smarty模板语法 在 nodejs 中使用 创建和渲染模板的简单而强大的方法 为什么? 强大的 不想在您的项目中有两个或多个模板。 深爱聪明 什么时候? 当您的同步模板为 Smarty 时,您的 ...

  • javascript模板引擎artTemplate.zip

    artTemplate 是新一代 javascript 模板引擎,它采用预编译方式让性能有了质的飞跃,并且充分利用 javascript 引擎特性,使得其性能无论在前端还是后端都有极其出色的表现。在 chrome 下渲染效率测试中分别是知名引擎...

  • JavaScript模板引擎template.js.zip

    template.js 一款 JavaScript 模板引擎,简单,好用。提供一套模板语法,用户可以写一个模板区块,每次根据传入的数据,生成对应数据产生的HTML片段,渲染不同的效果。特性:模版编译,渲染支持所有主流浏览器及Node...

  • mustache.js v2.2.1强大的Javascript模板引擎

    mustache.js是一个简单强大的Javascript模板引擎,使用它可以简化在js代码中的html编写,压缩后只有9KB,非常值得在项目中使用。 本资源包含了mustache.js 、mustache.min.js包 版本号v2.2.1

  • pigeon-js:Pigeon是用Java编写HTML预处理器模板引擎

    Pigeon是用Javascript编写HTML预处理器/模板引擎。 安装 npm install pigeon-js 关于 Pigeon是HTML预处理器。 但是,您无需学习新语言-可以坚持使用Javascript。 Pigeon是AbsurdHTML预处理器的替代方案。 用法 var...

  • JavaScript模版引擎的基本实现方法浅析

    主要介绍了JavaScript模版引擎的基本实现方法,讲解利用function对象来一步步编写简单的模板,需要的朋友可以参考下

  • abell-renderer:模板引擎,可让您使用JavaScript语法在HTML中编写变量,循环和条件

    未准备好用于生产 模板解析器,使您可以使用JavaScript语法来呈现循环,条件,进行数学运算以及需要HTML中的JSON。 使用的低级库 :rocket: 安装及使用直接用执行npx abell-renderer build --input src/index.abell -...

  • JavaScript模板引擎初探 - HandleBars

    Handlebars是一个Javascript模板引擎,能让你轻松高效的编写语义化模板,能将Web前端的视图和数据分离,降低两者之间耦合。

Global site tag (gtag.js) - Google Analytics