Skip to content

Commit fef6094

Browse files
committed
Initial commit.
0 parents  commit fef6094

File tree

9 files changed

+875
-0
lines changed

9 files changed

+875
-0
lines changed

README.md

Lines changed: 301 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,301 @@
1+
# JavaScript Templates
2+
3+
## Demo
4+
[JavaScript Templates Demo](http://blueimp.github.com/JavaScript-Templates/)
5+
6+
## Usage
7+
8+
### Client-side
9+
Include the (minified) JavaScript Templates script in your HTML markup:
10+
11+
```html
12+
<script src="tmpl.min.js"></script>
13+
```
14+
15+
Add a script section with type **"text/html"** and your template definition as content:
16+
17+
```html
18+
<script type="text/html" id="tmpl-demo">
19+
<h3>{%=o.title%}</h3>
20+
<p>Released under the
21+
<a href="{%=o.license.url%}">{%=o.license.name%}</a>.</p>
22+
<h4>Features</h4>
23+
<ul>
24+
{% for (var i=0; i<o.features.length; i++) { %}
25+
<li>{%=o.features[i]%}</li>
26+
{% } %}
27+
</ul>
28+
</script>
29+
```
30+
31+
**"o"** (the lowercase letter) is a reference to the data parameter of the template function (see the API section on how to modify this identifier).
32+
33+
In your application code, create a JavaScript object to use as data for the template:
34+
35+
```js
36+
var data = {
37+
"title": "JavaScript Templates",
38+
"license": {
39+
"name": "MIT license",
40+
"url": "http://creativecommons.org/licenses/MIT/"
41+
},
42+
"features": [
43+
"lightweight & fast",
44+
"powerful",
45+
"zero dependencies"
46+
]
47+
};
48+
```
49+
50+
In a real application, this data could be the result of retrieving a [JSON](http://json.org/) resource.
51+
52+
Render the result by calling the **tmpl()** method with the id of the template and the data object as arguments:
53+
54+
```js
55+
document.getElementById("result").innerHTML = tmpl("tmpl-demo", data);
56+
```
57+
58+
### Server-side
59+
60+
The following is an example how to use the JavaScript Templates engine on the server-side with [node.js](http://nodejs.org/).
61+
62+
Create a new directory and add the **tmpl.js** file. Or alternatively, install the **blueimp-tmpl** package with [npm](http://npmjs.org/):
63+
64+
```sh
65+
npm install blueimp-tmpl
66+
```
67+
68+
Add a file **template.html** with the following content:
69+
70+
```html
71+
<!DOCTYPE HTML>
72+
<title>{%=o.title%}</title>
73+
<h3><a href="{%=o.url%}">{%=o.title%}</a></h3>
74+
<h4>Features</h4>
75+
<ul>
76+
{% for (var i=0; i<o.features.length; i++) { %}
77+
<li>{%=o.features[i]%}</li>
78+
{% } %}
79+
</ul>
80+
```
81+
82+
Add a file **server.js** with the following content:
83+
84+
```js
85+
require("http").createServer(function (req, res) {
86+
var fs = require("fs"),
87+
// The tmpl module exports the tmpl() function:
88+
tmpl = require("./tmpl").tmpl,
89+
// Use the following version if you installed the package with npm:
90+
// tmpl = require("blueimp-tmpl").tmpl,
91+
// Sample data:
92+
data = {
93+
"title": "JavaScript Templates",
94+
"url": "https://github.com/blueimp/JavaScript-Templates",
95+
"features": [
96+
"lightweight & fast",
97+
"powerful",
98+
"zero dependencies"
99+
]
100+
};
101+
// Override the template loading method:
102+
tmpl.load = function (id) {
103+
var filename = id + ".html";
104+
console.log("Loading " + filename);
105+
return fs.readFileSync(filename, "utf8");
106+
};
107+
res.writeHead(200, {"Content-Type": "text/html"});
108+
// Render the content:
109+
res.end(tmpl("template", data));
110+
}).listen(8080, "localhost");
111+
console.log("Server running at http://localhost:8080/");
112+
```
113+
114+
Run the application with the following command:
115+
116+
```sh
117+
node server.js
118+
```
119+
120+
## Requirements
121+
The JavaScript Templates script has zero dependencies.
122+
123+
## API
124+
125+
### tmpl() function
126+
The **tmpl()** function is added to the global **window** object and can be called as global function:
127+
128+
```js
129+
var result = tmpl("tmpl-demo", data);
130+
```
131+
132+
The **tmpl()** function can be called with the id of a template, or with a template string:
133+
134+
```js
135+
var result = tmpl("<h3>{%=o.title%}</h3>", data);
136+
```
137+
138+
If called without second argument, **tmpl()** returns a reusable template function:
139+
140+
```js
141+
var func = tmpl("<h3>{%=o.title%}</h3>");
142+
document.getElementById("result").innerHTML = func(data);
143+
```
144+
145+
### Templates cache
146+
Templates loaded by id are cached in the map **tmpl.cache**, which can be modified:
147+
148+
```js
149+
var func = tmpl("tmpl-demo");
150+
var cached = typeof tmpl.cache["tmpl-demo"] === "function"; // true
151+
152+
tmpl.cache["tmpl-demo"] = tmpl("<h3>{%=o.title%}</h3>");
153+
var result = tmpl("tmpl-demo", {title: "JS"}); // Renders "<h3>JS</h3>"
154+
```
155+
156+
### Output encoding
157+
The method **tmpl.encode** is used to escape HTML special characters in template output:
158+
159+
```js
160+
var output = tmpl.encode("<>&\"\x00"); // Renders "&lt;&gt;&amp;&quot;"
161+
```
162+
163+
**tmpl.encode** makes use of the regular expression **tmpl.encReg** and the encoding map **tmpl.encMap** to match and replace special characters, which can be modified to change the behavior of the output encoding:
164+
165+
```js
166+
// Add single quotes to the encoding rules:
167+
tmpl.encReg = /[<>&"'\x00]/g;
168+
tmpl.encMap["'"] = "&#39;";
169+
170+
var output = tmpl.encode("<>&\"'\x00"); // Renders "&lt;&gt;&amp;&quot;&#39;"
171+
```
172+
173+
### Local helper variables
174+
The local variables available inside the templates are the following:
175+
176+
* **o**: The data object given as parameter to the template function (see the next section on how to modify the parameter name).
177+
* **_s**: The string for the rendered result content.
178+
* **_t**: A reference to the **tmpl** function object.
179+
* **_e**: A reference to the **tmpl.encode** method.
180+
* **print**: Function to add content to the rendered result string.
181+
* **include**: Function to include the return value of a different template in the result.
182+
183+
To introduce additional local helper variables, the string **tmpl.helper** can be extended. The following adds a convenience function for *console.log* and a streaming function, that streams the template rendering result back to the callback argument (note the comma at the beginning of each variable declaration):
184+
185+
```js
186+
tmpl.helper += ",log=function(){console.log.apply(console, arguments)}" +
187+
",st='',stream=function(cb){var l=st.length;st=_s;cb( _s.slice(l));}";
188+
```
189+
190+
Those new helper functions could be used to stream the template contents to the console output:
191+
192+
```html
193+
<script type="text/html" id="tmpl-demo">
194+
<h3>{%=o.title%}</h3>
195+
{% stream(log); %}
196+
<p>Released under the
197+
<a href="{%=o.license.url%}">{%=o.license.name%}</a>.</p>
198+
{% stream(log); %}
199+
<h4>Features</h4>
200+
<ul>
201+
{% stream(log); %}
202+
{% for (var i=0; i<o.features.length; i++) { %}
203+
<li>{%=o.features[i]%}</li>
204+
{% stream(log); %}
205+
{% } %}
206+
</ul>
207+
{% stream(log); %}
208+
</script>
209+
```
210+
211+
### Template function argument
212+
The generated template functions accept one argument, which is the data object given to the **tmpl(id, data)** function. This argument is available inside the template definitions as parameter **o** (the lowercase letter).
213+
214+
The argument name can be modified by overriding **tmpl.arg**:
215+
216+
```js
217+
tmpl.arg = "p";
218+
219+
// Renders "<h3>JavaScript Templates</h3>":
220+
var result = tmpl("<h3>{%=p.title%}</h3>", {title: "JavaScript Templates"});
221+
```
222+
223+
### Template parsing
224+
The template contents are matched and replaced using the regular expression **tmpl.regexp** and the replacement function **tmpl.func**. The replacement function operates based on the [parenthesized submatch strings](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String/replace#Specifying_a_function_as_a_parameter).
225+
226+
To use different tags for the template syntax, override **tmpl.regexp** with a modified regular expression, by exchanging all occurrences of "**\\{%**" and "**%\\}**", e.g. with "**\\[%**" and "**%\\]**":
227+
228+
```js
229+
tmpl.regexp = /(\s+)|('|\\)(?![^%]*%\])|(?:\[%(=|!)(.+?)%\])|(\[%)|(%\])/g;
230+
```
231+
232+
## Templates syntax
233+
234+
### Interpolation
235+
Print variable with HTML special characters escaped:
236+
237+
```html
238+
<h3>{%=o.title%}</h3>
239+
```
240+
241+
Print variable without escaping:
242+
243+
```html
244+
<h3>{%!o.user_id%}</h3>
245+
```
246+
247+
Print output of function calls:
248+
249+
```html
250+
<a href="{%=encodeURI(o.url)%}">Website</a>
251+
```
252+
253+
Use dot notation to print nested properties:
254+
255+
```html
256+
<strong>{%=o.author.name%}</strong>
257+
```
258+
259+
### Evaluation
260+
Use **print(str)** to add escaped content to the output:
261+
262+
```html
263+
<span>Year: {% var d=new Date(); print(d.getFullYear()); %}</span>
264+
```
265+
266+
Use **print(str, true)** to add unescaped content to the output:
267+
268+
```html
269+
<span>{% print("Fast &amp; powerful", true); %}</span>
270+
```
271+
272+
Use **include(str, obj)** to include content from a different template:
273+
274+
```html
275+
<div>
276+
{% include('tmpl-link', {name: "Website", url: "http://example.org"}); %}
277+
</div>
278+
```
279+
280+
If else condition:
281+
282+
```html
283+
{% if (o.author.url) { %}
284+
<a href="{%=encodeURI(o.author.url)%}">{%=o.author.name%}</a>
285+
{% } else { %}
286+
<em>No author url.</em>
287+
{% } %}
288+
```
289+
290+
For loop:
291+
292+
```html
293+
<ul>
294+
{% for (var i=0; i<o.features.length; i++) { %}
295+
<li>{%=o.features[i]%}</li>
296+
{% } %}
297+
</ul>
298+
```
299+
300+
## License
301+
The JavaScript Templates script is released under the [MIT license](http://creativecommons.org/licenses/MIT/).

0 commit comments

Comments
 (0)