├── .gitignore
├── README.md
├── bower.json
├── doc
└── api.zh.md
├── src
└── underscore-template.js
└── test
├── test.html
└── test.js
/.gitignore:
--------------------------------------------------------------------------------
1 | Thumbs.db
2 | ehthumbs.db
3 | [Dd]esktop.ini
4 | $RECYCLE.BIN/
5 | .DS_Store
6 | .klive
7 | .dropbox.cache
8 |
9 | *.tmp
10 | *.bak
11 | *.swp
12 | *.lnk
13 |
14 | .svn
15 | .idea
16 |
17 | node_modules/
18 | bower_components/
19 | npm-debug.log
20 |
21 | *.zip
22 | *.gz
23 |
24 | demo/
25 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Underscore-template
2 |
3 | > More APIs for Underscore's template engine - template fetching, rendering and caching.
4 |
5 | ## 简介
6 |
7 | 著名的 JavaScript 工具库 Underscore 内置了一个小巧而完备的前端模板引擎,而 Underscore-template 对它进行了封装和增强,将它更好地融入了开发流程:
8 |
9 | * 提供简洁易用的 API,使用者不需要操心底层细节
10 | * 为各个模板命名,纳入统一的模板库,以便管理和调用
11 | * 可在 JS 中编写模板,也可以在 HTML 中编写模板;且两种方案可平滑切换
12 | * 通过两级缓存来优化性能,避免模板的重复获取和重复编译
13 |
14 | ## 兼容性
15 |
16 | 依赖以下类库:
17 |
18 | * Underscore
19 |
20 | 支持以下浏览器:
21 |
22 | * Chrome / Firefox / Safari 等现代浏览器
23 | * IE 6+
24 |
25 | ## 安装
26 |
27 | 0. 通过 Bower 安装:
28 |
29 | ```sh
30 | $ bower install underscore-template
31 | ```
32 |
33 | 0. 在页面中加载 Underscore-template 的脚本文件及必要的依赖:
34 |
35 | ```html
36 |
37 |
38 | ```
39 |
40 | ## API 文档
41 |
42 | * Underscore-template 提供了简洁易用的 API,[详见此文档](https://github.com/cssmagic/underscore-template/issues/5)。
43 | * 此外,建议阅读 [Wiki](https://github.com/cssmagic/underscore-template/wiki) 来获取更多信息。
44 |
45 | ## 单元测试
46 |
47 | 0. 把本项目的代码 fork 并 clone 到本地。
48 | 0. 在本项目的根目录运行 `bower install`,安装必要的依赖。
49 | 0. 在浏览器中打开 `test/test.html` 即可运行单元测试。
50 |
51 | ## 谁在用?
52 |
53 | 移动 UI 框架 [CMUI](https://github.com/CMUI/CMUI) 采用 Underscore-template 作为轻量的前端模板解决方案,因此所有 CMUI 用户都在使用它:
54 |
55 | * [百姓网 - 手机版](http://m.baixing.com/)
56 | * [薇姿官方电子商城 - 手机版](http://m.vichy.com.cn/)
57 | * [优e网 - 手机版](http://m.uemall.com/)
58 |
59 | ***
60 |
61 | ## License
62 |
63 | [MIT License](http://www.opensource.org/licenses/mit-license.php)
64 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "underscore-template",
3 | "homepage": "https://github.com/cssmagic/underscore-template",
4 | "authors": [
5 | "cssmagic "
6 | ],
7 | "description": "More APIs for Underscore's template engine.",
8 | "main": "src/underscore-template.js",
9 | "moduleType": [
10 | "globals"
11 | ],
12 | "keywords": [
13 | "underscore",
14 | "template"
15 | ],
16 | "license": "MIT",
17 | "ignore": [
18 | "**/.*",
19 | "**.sh",
20 | "**.min.js",
21 | "package.json",
22 | "node_modules",
23 | "bower_components",
24 | "test",
25 | "doc",
26 | "demo"
27 | ],
28 | "dependencies": {
29 | "underscore": "1.*"
30 | },
31 | "devDependencies": {
32 | "jquery": "*",
33 | "mocha.css": "0.1.0",
34 | "mocha": "1.*",
35 | "chai": "1.*"
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/doc/api.zh.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "API 文档"
3 | ---
4 |
5 | ## 导言
6 |
7 | #### 模板引擎
8 |
9 | 模板引擎的作用是将数据渲染成为 HTML 代码片断,它将生成 HTML 代码的工作分解为“准备数据”和“编写模板”两个步骤,将开发者从繁重的字符串拼接任务中解脱出来。
10 |
11 | #### Underscore 的模板引擎
12 |
13 | Underscore 内置了一个小巧而完备的前端模板引擎(`_.template()`),而 Underscore-template 这个库则将它更好地融入了开发流程。
14 |
15 | 因此,在使用这个库之前,你需要了解 Underscore 的模板引擎。推荐资源如下:
16 |
17 | * [Underscore 模板引擎 API 官方文档](http://underscorejs.org/#template)
18 | * [中文注解](https://github.com/cssmagic/blog/issues/4)
19 |
20 | #### 功能简介
21 |
22 | 这个库的主要作用是建立一个模板库,把页面中需要前端模板管理起来,以便在需要的时候调用。
23 |
24 | 同时,它在内部做了一些性能优化,通过缓存来避免模板的重复编译。但这些优化对使用者来说是透明的,不需要特别操心。
25 |
26 | ## JavaScript 接口
27 |
28 | ### `template.add(id, template)`
29 |
30 | 定义一个模板,即将该模板纳入模板库,以便稍后使用。每个模板都需要有一个独一无二的 ID。
31 |
32 | #### 参数
33 |
34 | * `id` -- 字符串。模板名。
35 | * `template` -- 字符串。模板代码。
36 |
37 | #### 返回值
38 |
39 | 布尔值。定义模板成功时为 `true`,失败时为 `false`。
40 |
41 | #### 示例
42 |
43 | 以下代码定义了一个名为 `my-list` 的模板,我们可以在后面使用它来渲染数据。
44 |
45 | ```js
46 | template.add('my-list', [
47 | '',
48 | '<% _.each(data.list, function (item) { %>',
49 | '- <%= item %>
',
50 | '<% }) %>',
51 | '
'
52 | ].join('\n'))
53 | ```
54 |
55 | ***
56 |
57 | ### `template.render(id, data)`
58 |
59 | 使用指定模板来渲染数据,得到 HTML 代码片断。
60 |
61 | #### 参数
62 |
63 | * `id` -- 字符串。模板名。
64 | * `data` -- 对象(或数组等)。待渲染的数据。
65 |
66 | #### 返回值
67 |
68 | 字符串。渲染生成的 HTML 代码片断。如果出现参数缺失或模板不存在等错误,则返回空字符串。
69 |
70 | #### 示例
71 |
72 | 假设我们有以下数据:
73 |
74 | ```js
75 | var todoList = {
76 | list: [
77 | '买一台新手机',
78 | '吃一顿大餐',
79 | '来一次说走就走的旅行'
80 | ]
81 | }
82 | ```
83 |
84 | 以下代码即调用名为 `my-list` 的模板(上面已定义)来渲染上述数据:
85 |
86 | ```js
87 | var html = template.render('my-list', todoList)
88 | ```
89 |
90 | 我们会得到如下 HTML 代码片断:
91 |
92 | ```html
93 |
94 | - 买一台新手机
95 | - 吃一顿大餐
96 | - 来一次说走就走的旅行
97 |
98 | ```
99 |
100 | ## 开发流程
101 |
102 | #### 开发阶段
103 |
104 | 由于 JS 长期缺乏原生的多行字符串功能,在 JS 文件中编辑模板很不方便。因此,在实践中,开发者们普遍将模板代码写在 HTML 中。(如下所示,我们使用一个 `
114 | ```
115 |
116 | 值得高兴的是,上面提到的 `.render()` 方法也接受以这种方式编写的模板。为了让它能认出这个模板,你需要为这个 `
122 | ```
123 |
124 | 然后,我们就可以在 JS 中直接使用这个模板了:
125 |
126 | ```js
127 | var html = template.render('my-list', todoList)
128 | ```
129 |
130 | #### 部署到生产环境
131 |
132 | 把模板代码写在 HTML 中,意味着这部分代码会随着 HTML 页面的多次加载而重复加载,且各页面不能共享相同的模板,导致不必要的流量消耗;而把模板代码存放在 JS 文件中,则可以充分利用客户端缓存。
133 |
134 | 因此,在开发阶段,我们在 HTML 中编写并修改模板代码,直至完成功能开发;在准备部署到生产环境时,我们可以按照如下步骤把模板代码从 HTML 中转移到 JS 文件中:
135 |
136 | 0. 将 HTML 中的模板代码复制出来,转换为 JS 可用的多行字符串。
137 | 0. 用 `.add()` 方法来定义模板。
138 | 0. 在 HTML 中删除那些用于存放模板代码的 `
18 |
19 |
20 |
21 |
22 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |