Skip to content

Commit bf44d30

Browse files
committed
Merge pull request #1 from zpbx/master
First release.
2 parents 712002f + e409433 commit bf44d30

6 files changed

Lines changed: 597 additions & 2 deletions

File tree

.gitignore

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
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/

README.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
underscore.template
2-
===================
1+
# Underscore.template
32

43
More APIs for Underscore's template engine.
4+
5+
***
6+
7+
## License
8+
9+
[MIT License](http://www.opensource.org/licenses/mit-license.php)

bower.json

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{
2+
"name": "underscore.template",
3+
"version": "0.1.0",
4+
"homepage": "https://github.com/cssmagic/underscore.template",
5+
"authors": [
6+
"cssmagic"
7+
],
8+
"description": "More APIs for Underscore's template engine.",
9+
"main": "src/action.js",
10+
"moduleType": [
11+
"globals"
12+
],
13+
"keywords": [
14+
"underscore",
15+
"template"
16+
],
17+
"license": "MIT",
18+
"ignore": [
19+
"**/.*",
20+
"**.sh",
21+
"**.min.js",
22+
"package.json",
23+
"node_modules",
24+
"bower_components",
25+
"test",
26+
"demo"
27+
],
28+
"dependencies": {
29+
"underscore.string": "*",
30+
"underscore": "^1.3.3"
31+
},
32+
"devDependencies": {
33+
"jquery": "*",
34+
"mocha.css": "0.1.0",
35+
"mocha": "*",
36+
"chai": "*"
37+
}
38+
}

src/underscore.template.js

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
/**
2+
* Underscore.template - More APIs for Underscore's template engine.
3+
* Released under the MIT license.
4+
* https://github.com/cssmagic/underscore.template
5+
*/
6+
var template = function () {
7+
'use strict'
8+
9+
//namespace
10+
var template = {}
11+
12+
//config
13+
var ELEM_ID_PREFIX = 'template-'
14+
15+
//cache
16+
var _cacheTemplate = {}
17+
var _cacheCompiledTemplate = {}
18+
19+
//util
20+
function _toTemplateId(id) {
21+
//`#template-my-tpl-001` -> `my-tpl-001`
22+
// `template-my-tpl-001` -> `my-tpl-001`
23+
// `my-tpl-001` -> `my-tpl-001`
24+
id = id ? _.str.trim(id).replace(/^[#!]+/, '') : ''
25+
return _.str.trim(id).replace(ELEM_ID_PREFIX, '')
26+
}
27+
function _toElementId(id) {
28+
//`template-my-tpl-001` -> `template-my-tpl-001`
29+
// `my-tpl-001` -> `template-my-tpl-001`
30+
id = id ? _.str.trim(id) : ''
31+
return _.str.startsWith(id, ELEM_ID_PREFIX) ? id : ELEM_ID_PREFIX + id
32+
}
33+
function _stripCommentTag(str) {
34+
str = String(str)
35+
if (_.str.startsWith(str, '<!' + '--') && _.str.endsWith(str, '-->')) {
36+
str = str.replace(/^<!\-\-/, '').replace(/\-\->$/, '')
37+
str = _.str.trim(str)
38+
}
39+
return str
40+
}
41+
//get template by id (of dummy script element in html)
42+
function _getTemplateById(id) {
43+
if (!id) return false
44+
var result
45+
var elementId = _toElementId(String(id))
46+
var elem = document.getElementById(elementId)
47+
if (elem) {
48+
var str = _.str.trim(elem.innerHTML)
49+
if (str) {
50+
//strip html comment tag wrapping template code
51+
//especially for jedi 1.0 (https://github.com/baixing/jedi)
52+
if (_.templateSettings.shouldUnwrapCommentTag) str = _stripCommentTag(str)
53+
54+
if (_isTemplateCode(str)) {
55+
result = str
56+
} else {
57+
/** DEBUG_INFO_START **/
58+
console.warn('[Template] Template code in element "#' + elementId + '" is invalid!')
59+
/** DEBUG_INFO_END **/
60+
}
61+
} else {
62+
/** DEBUG_INFO_START **/
63+
console.warn('[Template] Element "#' + elementId + '" is empty!')
64+
/** DEBUG_INFO_END **/
65+
}
66+
} else {
67+
/** DEBUG_INFO_START **/
68+
console.warn('[Template] Element "#' + elementId + '" not found!')
69+
/** DEBUG_INFO_END **/
70+
}
71+
return result || false
72+
}
73+
function _isTemplateCode(s) {
74+
var code = String(s)
75+
return _.str.include(code, '<%') && _.str.include(code, '%>') && /\bdata\b/.test(code)
76+
}
77+
78+
//fn
79+
function add(id, templateCode) {
80+
//todo: accept second param as a function, to support pre-compiled template.
81+
if (arguments.length < 2) return false
82+
83+
var result
84+
if (templateCode) {
85+
var templateId = _toTemplateId(id)
86+
/** DEBUG_INFO_START **/
87+
if (_cacheTemplate[templateId]) {
88+
console.warn('[Template] Template id "' + templateId + '" already existed.')
89+
}
90+
/** DEBUG_INFO_END **/
91+
result = _cacheTemplate[templateId] = templateCode
92+
} else {
93+
//todo: support `_.template.add(id)` to add from dummy script element
94+
//console.error('Missing template code to add to cache.')
95+
}
96+
return !!result
97+
}
98+
99+
//api
100+
template.remove = function (/* id */) {
101+
//todo: remove template from cache (both str and fn)
102+
//todo: remove dummy script element
103+
}
104+
template.add = add
105+
template.render = function (id, data) {
106+
//todo: support _.template.render(templateCode, templateData)
107+
if (arguments.length < 2) {
108+
console.error('Missing data to render template: "' + id + '"')
109+
return false
110+
}
111+
var result
112+
var templateId = _toTemplateId(id)
113+
114+
//todo: refactor: use recursion to simplify these codes
115+
//search in _cacheCompiledTemplate
116+
var fn = _cacheCompiledTemplate[templateId]
117+
var templateCode = _cacheTemplate[templateId]
118+
if (_.isFunction(fn)) {
119+
result = fn(data)
120+
}
121+
//search in _cacheTemplate
122+
else if (_.isString(templateCode)) {
123+
fn = _.template(templateCode)
124+
_cacheCompiledTemplate[templateId] = fn
125+
result = fn(data)
126+
}
127+
//get template code from dom
128+
else {
129+
templateCode = _getTemplateById(templateId)
130+
if (templateCode) {
131+
_cacheTemplate[templateId] = templateCode
132+
fn = _.template(templateCode)
133+
_cacheCompiledTemplate[templateId] = fn
134+
result = fn(data)
135+
}
136+
}
137+
return result || ''
138+
}
139+
140+
/** DEBUG_INFO_START **/
141+
//exports for unit test
142+
template.__toTemplateId = _toTemplateId
143+
template.__toElementId = _toElementId
144+
template.__isTemplateCode = _isTemplateCode
145+
template.__stripCommentTag = _stripCommentTag
146+
template.__cacheTemplate = _cacheTemplate
147+
template.__cacheCompiledTemplate = _cacheCompiledTemplate
148+
/** DEBUG_INFO_END **/
149+
150+
//exports
151+
return template
152+
153+
}()

test/test.html

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="UTF-8">
5+
<title>UT - Underscore.template</title>
6+
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">
7+
<link rel="stylesheet" href="../bower_components/mocha/mocha.css">
8+
<link rel="stylesheet" href="../bower_components/mocha.css/src/mocha.css">
9+
</head>
10+
<body>
11+
<header>
12+
<h1>UT - Underscore.template</h1>
13+
<p><a href="https://github.com/cssmagic/underscore.template">View on GitHub</a></p>
14+
</header>
15+
<div id="mocha"></div>
16+
<!-- deps -->
17+
<script src="../bower_components/jquery/dist/jquery.js"></script>
18+
<script src="../bower_components/underscore/underscore.js"></script>
19+
<script src="../bower_components/underscore.string/lib/underscore.string.js"></script>
20+
<!-- testing framework -->
21+
<script src="../bower_components/mocha/mocha.js"></script>
22+
<script src="../bower_components/chai/chai.js"></script>
23+
<script>
24+
mocha.setup('bdd')
25+
mocha.checkLeaks()
26+
var expect = chai.expect
27+
</script>
28+
<!-- source code -->
29+
<script src="../src/underscore.template.js"></script>
30+
<!-- test-case -->
31+
<script src="test.js"></script>
32+
<!-- init -->
33+
<script>mocha.run()</script>
34+
</body>
35+
</html>

0 commit comments

Comments
 (0)