1 | # ECT
|
2 |
|
3 | [Performance focused](http://ectjs.com/#benchmark) JavaScript template engine with embedded CoffeeScript syntax.
|
4 |
|
5 | [Just try demo](http://ectjs.com) to check all features.
|
6 |
|
7 | ## Installation
|
8 |
|
9 | npm install ect
|
10 |
|
11 | ## Features
|
12 |
|
13 | * Excellent performance
|
14 | * Templates caching
|
15 | * Automatic reloading of changed templates
|
16 | * CoffeeScript code in templates
|
17 | * Multi-line expressions support
|
18 | * Tag customization support
|
19 | * Node.JS and client-side support
|
20 | * Powerful but simple syntax
|
21 | * Inheritance, partials, blocks
|
22 | * Compatible with `express`
|
23 | * Compatible with `RequireJS`
|
24 | * Backward compatible with `eco`
|
25 | * [Syntax highlighting for Sublime Text 2](https://github.com/TurtlePie/Sublime-ECT) by [TurtlePie](https://github.com/TurtlePie)
|
26 |
|
27 | ## Usage
|
28 |
|
29 | ```js
|
30 | var ECT = require('ect');
|
31 |
|
32 | var renderer = ECT({ root : __dirname + '/views', ext : '.ect' });
|
33 | var html = renderer.render('page', { title: 'Hello, World!' });
|
34 | ```
|
35 |
|
36 | or
|
37 |
|
38 | ```js
|
39 | var ECT = require('ect');
|
40 |
|
41 | var renderer = ECT({ root : __dirname + '/views', ext : '.ect' });
|
42 |
|
43 | renderer.render('page', { title: 'Hello, World!' }, function (error, html) {
|
44 | console.log(error);
|
45 | console.log(html);
|
46 | });
|
47 | ```
|
48 |
|
49 | You may use JavaScript object as root.
|
50 |
|
51 | ```js
|
52 | var ECT = require('ect');
|
53 |
|
54 | var renderer = ECT({ root : {
|
55 | layout: '<html><head><title><%- title %></title></head><body><% content %></body></html>',
|
56 | page: '<% extend "layout" %><p>Page content</p>'
|
57 | }
|
58 | });
|
59 |
|
60 | var html = renderer.render('page', { title: 'Hello, World!' });
|
61 | ```
|
62 |
|
63 | ### With express
|
64 |
|
65 | app.js
|
66 | ```js
|
67 | var express = require('express');
|
68 | var app = express();
|
69 | var ECT = require('ect');
|
70 | var ectRenderer = ECT({ watch: true, root: __dirname + '/views' });
|
71 |
|
72 | app.engine('.ect', ectRenderer.render);
|
73 |
|
74 | app.get('/', function (req, res){
|
75 | res.render('index.ect');
|
76 | });
|
77 |
|
78 | app.listen(3000);
|
79 | console.log('Listening on port 3000');
|
80 | ```
|
81 |
|
82 | views/index.ect
|
83 | ```html
|
84 | <% extend 'layout.ect' %>
|
85 | <div>Hello, World!</div>
|
86 | ```
|
87 |
|
88 | views/layout.ect
|
89 | ```html
|
90 | <html>
|
91 | <body>
|
92 | <% content %>
|
93 | </body>
|
94 | </html>
|
95 | ```
|
96 |
|
97 | ## Syntax
|
98 |
|
99 | ### Unescaped output
|
100 |
|
101 | ```
|
102 | <%- someVar %>
|
103 | ```
|
104 |
|
105 | ### Escaped output
|
106 |
|
107 | ```
|
108 | <%= someVar %>
|
109 | ```
|
110 |
|
111 | ### CoffeeScript code
|
112 |
|
113 | ```
|
114 | <% for article in @articles : %>
|
115 | <% include 'article', article %>
|
116 | <% end %>
|
117 | ```
|
118 |
|
119 | or
|
120 |
|
121 | ```
|
122 | <% if @user?.authenticated : %>
|
123 | <% include 'partials/user' %>
|
124 | <% else : %>
|
125 | <% include 'partials/auth' %>
|
126 | <% end %>
|
127 | ```
|
128 |
|
129 | ### Inheritance
|
130 |
|
131 | ```
|
132 | <% extend 'layout' %>
|
133 | ```
|
134 |
|
135 | Use
|
136 |
|
137 |
|
138 | ```
|
139 | <% content %>
|
140 | ```
|
141 |
|
142 | in parent template to define the insertion point.
|
143 |
|
144 | ### Partials
|
145 |
|
146 | ```
|
147 | <% include 'partial' %>
|
148 | ```
|
149 |
|
150 | You can redefine data context of partial
|
151 |
|
152 | ```
|
153 | <% include 'partial', { customVar: 'Hello, World!' } %>
|
154 | ```
|
155 |
|
156 | ### Blocks
|
157 |
|
158 | ```
|
159 | <% block 'blockName' : %>
|
160 | <p>This is block content</p>
|
161 | <% end %>
|
162 | ```
|
163 |
|
164 | Use
|
165 |
|
166 |
|
167 | ```
|
168 | <% content 'blockName' %>
|
169 | ```
|
170 |
|
171 | in parent template to define the insertion point.
|
172 |
|
173 | Blocks supports more than one level of inheritance and may be redefined.
|
174 |
|
175 | ## Options
|
176 |
|
177 | ### Renderer
|
178 |
|
179 | - `root` — Templates root folder or JavaScript object containing templates
|
180 | - `ext` — Extension of templates, defaulting to `''` (not used for JavaScript objects as root)
|
181 | - `cache` — Compiled functions are cached, defaulting to `true`
|
182 | - `watch` — Automatic reloading of changed templates, defaulting to `false` (useful for debugging with enabled cache, not supported for client-side)
|
183 | - `open` — Open tag, defaulting to `<%`
|
184 | - `close` — Closing tag, defaulting to `%>`
|
185 |
|
186 | ### Compiler middleware
|
187 |
|
188 | - `root` — Base url, defaulting to `/` (should be equal to `root` option on the client side)
|
189 | - `gzip` — Compressing templates with gzip, defaulting to `false`
|
190 |
|
191 | ## Client-side support
|
192 |
|
193 | Download and include [coffee-script.js](https://github.com/jashkenas/coffee-script/blob/master/extras/coffee-script.js) and [ect.min.js](https://github.com/baryshev/ect/tree/master/ect.min.js).
|
194 |
|
195 | ```html
|
196 | <script src="/path/coffee-script.js"></script>
|
197 | <script src="/path/ect.min.js"></script>
|
198 | ```
|
199 |
|
200 | Use it.
|
201 |
|
202 | ```js
|
203 | var renderer = ECT({ root : '/views' });
|
204 | var data = { title : 'Hello, World!' };
|
205 | var html = renderer.render('template.ect', data);
|
206 | ```
|
207 |
|
208 | ### With server side compiler middleware
|
209 |
|
210 | Download and include [ect.min.js](https://github.com/baryshev/ect/tree/master/ect.min.js). You don't need to include CoffeeScript compiler, because templates are served already compiled by server side compiler middleware.
|
211 |
|
212 | ```html
|
213 | <script src="/path/ect.min.js"></script>
|
214 | ```
|
215 |
|
216 | Setup server side compiler middleware.
|
217 |
|
218 | ```js
|
219 | var connect = require('connect');
|
220 | var ECT = require('ect');
|
221 |
|
222 | var renderer = ECT({ root : __dirname + '/views', ext : '.ect' });
|
223 |
|
224 | var app = connect()
|
225 | .use(renderer.compiler({ root: '/views', gzip: true }))
|
226 | .use(function(err, req, res, next) {
|
227 | res.end(err.message);
|
228 | });
|
229 |
|
230 | app.listen(3000);
|
231 | ```
|
232 |
|
233 | Use it.
|
234 |
|
235 | ```js
|
236 | var renderer = ECT({ root : '/views', ext : '.ect' });
|
237 | var data = { title : 'Hello, World!' };
|
238 | var html = renderer.render('template', data);
|
239 | ```
|
240 |
|
241 | Note: root folder must be on the same domain to avoid cross-domain restrictions.
|
242 |
|
243 | ## License
|
244 |
|
245 | (The MIT License)
|
246 |
|
247 | Copyright (c) 2012 Vadim M. Baryshev <vadimbaryshev@gmail.com>
|
248 |
|
249 | Permission is hereby granted, free of charge, to any person obtaining
|
250 | a copy of this software and associated documentation files (the
|
251 | 'Software'), to deal in the Software without restriction, including
|
252 | without limitation the rights to use, copy, modify, merge, publish,
|
253 | distribute, sublicense, and/or sell copies of the Software, and to
|
254 | permit persons to whom the Software is furnished to do so, subject to
|
255 | the following conditions:
|
256 |
|
257 | The above copyright notice and this permission notice shall be
|
258 | included in all copies or substantial portions of the Software.
|
259 |
|
260 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
261 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
262 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
263 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
264 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
265 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
266 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|