Code Monkey home page Code Monkey logo

underscore-template's Introduction

Underscore-template

More APIs for Underscore's template engine - template fetching, rendering and caching.

简介

著名的 JavaScript 工具库 Underscore 内置了一个小巧而完备的前端模板引擎,而 Underscore-template 对它进行了封装和增强,将它更好地融入了开发流程:

  • 提供简洁易用的 API,使用者不需要操心底层细节
  • 为各个模板命名,纳入统一的模板库,以便管理和调用
  • 可在 JS 中编写模板,也可以在 HTML 中编写模板;且两种方案可平滑切换
  • 通过两级缓存来优化性能,避免模板的重复获取和重复编译

兼容性

依赖以下类库:

  • Underscore

支持以下浏览器:

  • Chrome / Firefox / Safari 等现代浏览器
  • IE 6+

安装

  1. 通过 Bower 安装:

    $ bower install underscore-template
  2. 在页面中加载 Underscore-template 的脚本文件及必要的依赖:

    <script src="bower_components/underscore/underscore.js"></script>
    <script src="bower_components/underscore-template/src/underscore-template.js"></script>

API 文档

  • Underscore-template 提供了简洁易用的 API,详见此文档
  • 此外,建议阅读 Wiki 来获取更多信息。

单元测试

  1. 把本项目的代码 fork 并 clone 到本地。
  2. 在本项目的根目录运行 bower install,安装必要的依赖。
  3. 在浏览器中打开 test/test.html 即可运行单元测试。

谁在用?

移动 UI 框架 CMUI 采用 Underscore-template 作为轻量的前端模板解决方案,因此所有 CMUI 用户都在使用它:


License

MIT License

underscore-template's People

Contributors

blueeye1015 avatar cssmagic avatar zpbx avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

underscore-template's Issues

如何在 Jedi 中编写模板?

方法一

把模板代码写入注释区块中,以避免被转义。

script @type="text/template"
    !
        <ul class="my-list">
        <% _.each(data.list, function (item) { %>
            <li><%= item %><li>
        <% }) %>
        </ul>

方法二

利用 Jedi 来生成结构,使用 :unsafe 来插入模板逻辑和变量。

script @type="text/template"
    ul.list
        :unsafe '<% _.each(data.list, function (item) { %>'
        li
            :unsafe '<%= item %>'
        :unsafe '<% }) %>'

API 文档

导言  

模板引擎  

模板引擎的作用是将数据渲染成为 HTML 代码片断,它将生成 HTML 代码的工作分解为“准备数据”和“编写模板”两个步骤,将开发者从繁重的字符串拼接任务中解脱出来。

Underscore 的模板引擎  

Underscore 内置了一个小巧而完备的前端模板引擎(_.template()),而 Underscore-template 这个库则将它更好地融入了开发流程。

因此,在使用这个库之前,你需要了解 Underscore 的模板引擎。推荐资源如下:

功能简介  

这个库的主要作用是建立一个模板库,把页面中需要前端模板管理起来,以便在需要的时候调用。

同时,它在内部做了一些性能优化,通过缓存来避免模板的重复编译。但这些优化对使用者来说是透明的,不需要特别操心。

JavaScript 接口  

template.add(id, template)

定义一个模板,即将该模板纳入模板库,以便稍后使用。每个模板都需要有一个独一无二的 ID。

参数

  • id -- 字符串。模板名。
  • template -- 字符串。模板代码。

返回值

布尔值。定义模板成功时为 true,失败时为 false

示例

以下代码定义了一个名为 my-list 的模板,我们可以在后面使用它来渲染数据。

template.add('my-list', [
    '<ul class="my-list">',
    '<% _.each(data.list, function (item) { %>',
        '<li><%= item %></li>',
    '<% }) %>',
    '</ul>'
].join('\n'))

template.render(id, data)

使用指定模板来渲染数据,得到 HTML 代码片断。

参数

  • id -- 字符串。模板名。
  • data -- 对象(或数组等)。待渲染的数据。

返回值

字符串。渲染生成的 HTML 代码片断。如果出现参数缺失或模板不存在等错误,则返回空字符串。

示例

假设我们有以下数据:

var todoList = {
    list: [
        '买一台新手机',
        '吃一顿大餐',
        '来一次说走就走的旅行'
    ]
}

以下代码即调用名为 my-list 的模板(上面已定义)来渲染上述数据:

var html = template.render('my-list', todoList)

我们会得到如下 HTML 代码片断:

<ul class="my-list">
    <li>买一台新手机</li>
    <li>吃一顿大餐</li>
    <li>来一次说走就走的旅行</li>
</ul>

开发流程  

开发阶段  

由于 JS 长期缺乏原生的多行字符串功能,在 JS 文件中编辑模板很不方便。因此,在实践中,开发者们普遍将模板代码写在 HTML 中。(如下所示,我们使用一个 <script> 标签来存放模板代码,并设置了一个非标准的 type 值来避免浏览器把它当作脚本执行。)

<script type="text/template">
<ul class="my-list">
<% _.each(data.list, function (item) { %>
    <li><%= item %></li>
<% }) %>
</ul>
</script>

值得高兴的是,上面提到的 .render() 方法也接受以这种方式编写的模板。为了让它能认出这个模板,你需要为这个 <script> 标签添加一个 ID,且值为模板名加上 template- 前缀:

<script type="text/template" id="template-my-list">
...
</script>

然后,我们就可以在 JS 中直接使用这个模板了:

var html = template.render('my-list', todoList)

部署到生产环境  

把模板代码写在 HTML 中,意味着这部分代码会随着 HTML 页面的多次加载而重复加载,且各页面不能共享相同的模板,导致不必要的流量消耗;而把模板代码存放在 JS 文件中,则可以充分利用客户端缓存。

因此,在开发阶段,我们在 HTML 中编写并修改模板代码,直至完成功能开发;在准备部署到生产环境时,我们可以按照如下步骤把模板代码从 HTML 中转移到 JS 文件中:

  1. 将 HTML 中的模板代码复制出来,转换为 JS 可用的多行字符串。
  2. .add() 方法来定义模板。
  3. 在 HTML 中删除那些用于存放模板代码的 <script> 标签。

有一个 在线的模板代码转换工具 可以帮助我们实现多行字符串的转换。如果你在部署阶段使用一个自动化构建程序来完成的模板提取和转换就更好了。

需要增加一个 API 来输出推荐的模板设置

var templateConfig = {
	//compatible with ejs
	interpolate : /<%-([\s\S]+?)%>/g,
	escape      : /<%=([\s\S]+?)%>/g,

	//to avoid use `with` in compiled templates
	//see: https://github.com/cssmagic/blog/issues/4
	variable: 'data',
}
_.extend(_.templateSettings, templateConfig)

需要移除对 underscore.string 的依赖

作为一个独立项目,外部依赖当然越小越好。

引入 underscore.string 是为了处理字符串,用的最多的是它的 .trim().include() API。这两者可以很容易地自己实现。

为了处理 Jedi 在 <script> 标签内加的一层注释,又用到了 .startsWith().endsWith()。自己实现也不难。希望 Jedi 2.0 出来以后可以完全去掉内部的 _stripCommentTag() 方法。

`.add()` 在某些时候无法覆盖同名模板

.add() 这个 API 被设计为可以覆盖已经添加过的同名模板。但在目前的实现中,它只把模板添加到二级缓存中,并不会清除一级缓存中的同名模板,因此可能出现无法覆盖同名模板的情况。

需要让 `.add()` API 支持预编译的模板函数

目前 .add() API 只能定义模板字符串。当后端提供模板的预编译服务时,就需要 .add() 方法接受以模板函数的方式来定义模板。

不过与此同时,需要把后端的预编译服务写出来,以配合测试。

同一模板会存在于两级缓存中,是否可优化为只存一处

“两级缓存” 分别是指:

  • 二级缓存:模板代码缓存
  • 一级缓存:模板函数(已编译模板)缓存

根据目前的实现,同一模板的模板代码和模板函数会同时存在于这两级缓存,但这样做似乎是不必要的——当模板函数已经存在于一级缓存时,是不会再用到二级缓存了。

因此,可考虑:

  • 是否可优化为同一模板只存在某一处缓存中?
  • 这样优化有何风险?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.