1 | Express Handlebars
|
2 | ==================
|
3 |
|
4 | A [Handlebars][] view engine for [Express][] which doesn't suck.
|
5 |
|
6 | [![npm version][npm-badge]][npm]
|
7 | [![dependency status][dep-badge]][dep-status]
|
8 |
|
9 | **This package used to be named `express3-handlebars`. The previous `express-handlebars` package by @jneen can be found [here][jneen-exphbs].**
|
10 |
|
11 |
|
12 | [Express]: https://github.com/visionmedia/express
|
13 | [Handlebars]: https://github.com/wycats/handlebars.js
|
14 | [npm]: https://www.npmjs.org/package/express-handlebars
|
15 | [npm-badge]: https://img.shields.io/npm/v/express-handlebars.svg?style=flat-square
|
16 | [dep-status]: https://david-dm.org/express-handlebars/express-handlebars
|
17 | [dep-badge]: https://img.shields.io/david/express-handlebars/express-handlebars.svg?style=flat-square
|
18 | [jneen-exphbs]: https://github.com/jneen/express-handlebars
|
19 |
|
20 |
|
21 | ## Goals & Design
|
22 |
|
23 | I created this project out of frustration with the existing Handlebars view engines for Express. As of version 3.x, Express got out of the business of being a generic view engine — this was a great decision — leaving developers to implement the concepts of layouts, partials, and doing file I/O for their template engines of choice.
|
24 |
|
25 | ### Goals and Features
|
26 |
|
27 | After building a half-dozen Express apps, I developed requirements and opinions about what a Handlebars view engine should provide and how it should be implemented. The following is that list:
|
28 |
|
29 | * Add back the concept of "layout", which was removed in Express 3.x.
|
30 |
|
31 | * Add back the concept of "partials" via Handlebars' partials mechanism.
|
32 |
|
33 | * Support a directory of partials; e.g., `{{> foo/bar}}` which exists on the file system at `views/partials/foo/bar.handlebars`, by default.
|
34 |
|
35 | * Smart file system I/O and template caching. When in development, templates are always loaded from disk. In production, raw files and compiled templates are cached, including partials.
|
36 |
|
37 | * All async and non-blocking. File system I/O is slow and servers should not be blocked from handling requests while reading from disk. I/O queuing is used to avoid doing unnecessary work.
|
38 |
|
39 | * Ability to easily precompile templates and partials for use on the client, enabling template sharing and reuse.
|
40 |
|
41 | * Ability to use a different Handlebars module/implementation other than the Handlebars npm package.
|
42 |
|
43 | ### Package Design
|
44 |
|
45 | This package was designed to work great for both the simple and complex use cases. I _intentionally_ made sure the full implementation is exposed and is easily overridable.
|
46 |
|
47 | The package exports a function which can be invoked with no arguments or with a `config` object and it will return a function (closed over sensible defaults) which can be registered with an Express app. It's an engine factory function.
|
48 |
|
49 | This exported engine factory has two properties which expose the underlying implementation:
|
50 |
|
51 | * `ExpressHandlebars()`: The constructor function which holds the internal implementation on its `prototype`. This produces instance objects which store their configuration, `compiled` and `precompiled` templates, and expose an `engine()` function which can be registered with an Express app.
|
52 |
|
53 | * `create()`: A convenience factory function for creating `ExpressHandlebars` instances.
|
54 |
|
55 | An instance-based approach is used so that multiple `ExpressHandlebars` instances can be created with their own configuration, templates, partials, and helpers.
|
56 |
|
57 |
|
58 | ## Installation
|
59 |
|
60 | Install using npm:
|
61 |
|
62 | ```shell
|
63 | $ npm install express-handlebars
|
64 | ```
|
65 |
|
66 |
|
67 | ## Usage
|
68 |
|
69 | This view engine uses sensible defaults that leverage the "Express-way" of structuring an app's views. This makes it trivial to use in basic apps:
|
70 |
|
71 | ### Basic Usage
|
72 |
|
73 | **Directory Structure:**
|
74 |
|
75 | ```
|
76 | .
|
77 | ├── app.js
|
78 | └── views
|
79 | ├── home.handlebars
|
80 | └── layouts
|
81 | └── main.handlebars
|
82 |
|
83 | 2 directories, 3 files
|
84 | ```
|
85 |
|
86 | **app.js:**
|
87 |
|
88 | Creates a super simple Express app which shows the basic way to register a Handlebars view engine using this package.
|
89 |
|
90 | ```javascript
|
91 | var express = require('express');
|
92 | var exphbs = require('express-handlebars');
|
93 |
|
94 | var app = express();
|
95 |
|
96 | app.engine('handlebars', exphbs());
|
97 | app.set('view engine', 'handlebars');
|
98 |
|
99 | app.get('/', function (req, res) {
|
100 | res.render('home');
|
101 | });
|
102 |
|
103 | app.listen(3000);
|
104 | ```
|
105 |
|
106 | **views/layouts/main.handlebars:**
|
107 |
|
108 | The main layout is the HTML page wrapper which can be reused for the different views of the app. `{{{body}}}` is used as a placeholder for where the main content should be rendered.
|
109 |
|
110 | ```handlebars
|
111 | <!DOCTYPE html>
|
112 | <html>
|
113 | <head>
|
114 | <meta charset="utf-8">
|
115 | <title>Example App</title>
|
116 | </head>
|
117 | <body>
|
118 |
|
119 | {{{body}}}
|
120 |
|
121 | </body>
|
122 | </html>
|
123 | ```
|
124 |
|
125 | **views/home.handlebars:**
|
126 |
|
127 | The content for the app's home view which will be rendered into the layout's `{{{body}}}`.
|
128 |
|
129 | ```handlebars
|
130 | <h1>Example App: Home</h1>
|
131 | ```
|
132 |
|
133 | #### Running the Example
|
134 |
|
135 | The above example is bundled in this package's [examples directory][], where it can be run by:
|
136 |
|
137 | ```shell
|
138 | $ cd examples/basic/
|
139 | $ npm install
|
140 | $ npm start
|
141 | ```
|
142 |
|
143 | ### Using Instances
|
144 |
|
145 | Another way to use this view engine is to create an instance(s) of `ExpressHandlebars`, allowing access to the full API:
|
146 |
|
147 | ```javascript
|
148 | var express = require('express');
|
149 | var exphbs = require('express-handlebars');
|
150 |
|
151 | var app = express();
|
152 | var hbs = exphbs.create({ /* config */ });
|
153 |
|
154 | // Register `hbs.engine` with the Express app.
|
155 | app.engine('handlebars', hbs.engine);
|
156 | app.set('view engine', 'handlebars');
|
157 |
|
158 | // ...still have a reference to `hbs`, on which methods like `loadPartials()`
|
159 | // can be called.
|
160 | ```
|
161 |
|
162 | **Note:** The [Advanced Usage][] example demonstrates how `ExpressHandlebars` instances can be leveraged.
|
163 |
|
164 | ### Template Caching
|
165 |
|
166 | This view engine uses a smart template caching strategy. In development, templates will always be loaded from disk, i.e., no caching. In production, raw files and compiled Handlebars templates are aggressively cached.
|
167 |
|
168 | The easiest way to control template/view caching is through Express' [view cache setting][]:
|
169 |
|
170 | ```javascript
|
171 | app.enable('view cache');
|
172 | ```
|
173 |
|
174 | Express enables this setting by default when in production mode, i.e.:
|
175 |
|
176 | ```
|
177 | process.env.NODE_ENV === "production"
|
178 | ```
|
179 |
|
180 | **Note:** All of the public API methods accept `options.cache`, which gives control over caching when calling these methods directly.
|
181 |
|
182 | ### Layouts
|
183 |
|
184 | A layout is simply a Handlebars template with a `{{{body}}}` placeholder. Usually it will be an HTML page wrapper into which views will be rendered.
|
185 |
|
186 | This view engine adds back the concept of "layout", which was removed in Express 3.x. It can be configured with a path to the layouts directory, by default it's set to relative to `express settings.view` + `layouts/`
|
187 |
|
188 | There are two ways to set a default layout: configuring the view engine's `defaultLayout` property, or setting [Express locals][] `app.locals.layout`.
|
189 |
|
190 | The layout into which a view should be rendered can be overridden per-request by assigning a different value to the `layout` request local. The following will render the "home" view with no layout:
|
191 |
|
192 | ```javascript
|
193 | app.get('/', function (req, res, next) {
|
194 | res.render('home', {layout: false});
|
195 | });
|
196 | ```
|
197 |
|
198 | ### Helpers
|
199 |
|
200 | Helper functions, or "helpers" are functions that can be [registered with Handlebars][] and can be called within a template. Helpers can be used for transforming output, iterating over data, etc. To keep with the spirit of *logic-less* templates, helpers are the place where logic should be defined.
|
201 |
|
202 | Handlebars ships with some [built-in helpers][], such as: `with`, `if`, `each`, etc. Most application will need to extend this set of helpers to include app-specific logic and transformations. Beyond defining global helpers on `Handlebars`, this view engine supports `ExpressHandlebars` instance-level helpers via the `helpers` configuration property, and render-level helpers via `options.helpers` when calling the `render()` and `renderView()` methods.
|
203 |
|
204 | The following example shows helpers being specified at each level:
|
205 |
|
206 | **app.js:**
|
207 |
|
208 | Creates a super simple Express app which shows the basic way to register `ExpressHandlebars` instance-level helpers, and override one at the render-level.
|
209 |
|
210 | ```javascript
|
211 | var express = require('express');
|
212 | var exphbs = require('express-handlebars');
|
213 |
|
214 | var app = express();
|
215 |
|
216 | var hbs = exphbs.create({
|
217 | // Specify helpers which are only registered on this instance.
|
218 | helpers: {
|
219 | foo: function () { return 'FOO!'; },
|
220 | bar: function () { return 'BAR!'; }
|
221 | }
|
222 | });
|
223 |
|
224 | app.engine('handlebars', hbs.engine);
|
225 | app.set('view engine', 'handlebars');
|
226 |
|
227 | app.get('/', function (req, res, next) {
|
228 | res.render('home', {
|
229 | showTitle: true,
|
230 |
|
231 | // Override `foo` helper only for this rendering.
|
232 | helpers: {
|
233 | foo: function () { return 'foo.'; }
|
234 | }
|
235 | });
|
236 | });
|
237 |
|
238 | app.listen(3000);
|
239 | ```
|
240 |
|
241 | **views/home.handlebars:**
|
242 |
|
243 | The app's home view which uses helper functions to help render the contents.
|
244 |
|
245 | ```handlebars
|
246 | <!DOCTYPE html>
|
247 | <html>
|
248 | <head>
|
249 | <meta charset="utf-8">
|
250 | <title>Example App - Home</title>
|
251 | </head>
|
252 | <body>
|
253 |
|
254 | <!-- Uses built-in `if` helper. -->
|
255 | {{#if showTitle}}
|
256 | <h1>Home</h1>
|
257 | {{/if}}
|
258 |
|
259 | <!-- Calls `foo` helper, overridden at render-level. -->
|
260 | <p>{{foo}}</p>
|
261 |
|
262 | <!-- Calls `bar` helper, defined at instance-level. -->
|
263 | <p>{{bar}}</p>
|
264 |
|
265 | </body>
|
266 | </html>
|
267 | ```
|
268 |
|
269 | #### More on Helpers
|
270 |
|
271 | Refer to the [Handlebars website][] for more information on defining helpers:
|
272 |
|
273 | * [Expression Helpers][]
|
274 | * [Block Helpers][]
|
275 |
|
276 | ### Metadata
|
277 |
|
278 | Handlebars has a data channel feature that propagates data through all scopes, including helpers and partials. Values in the data channel can be accessed via the `{{@variable}}` syntax. Express Handlebars provides metadata about a template it renders on a `{{@exphbs}}` object allowing access to things like the view name passed to `res.render()` via `{{@exphbs.view}}`.
|
279 |
|
280 | The following is the list of metadata that's accessible on the `{{@exphbs}}` data object:
|
281 |
|
282 | * `cache`: Boolean whether or not the template is cached.
|
283 | * `view`: String name of the view passed to `res.render()`.
|
284 | * `layout`: String name of the layout view.
|
285 | * `data`: Original data object passed when rendering the template.
|
286 | * `helpers`: Collection of helpers used when rendering the template.
|
287 | * `partials`: Collection of partials used when rendering the template.
|
288 |
|
289 |
|
290 | [examples directory]: https://github.com/express-handlebars/express-handlebars/tree/master/examples
|
291 | [view cache setting]: http://expressjs.com/api.html#app-settings
|
292 | [Express locals]: http://expressjs.com/api.html#app.locals
|
293 | [registered with Handlebars]: https://github.com/wycats/handlebars.js/#registering-helpers
|
294 | [built-in helpers]: http://handlebarsjs.com/#builtins
|
295 | [Handlebars website]: http://handlebarsjs.com/
|
296 | [Expression Helpers]: http://handlebarsjs.com/expressions.html#helpers
|
297 | [Block Helpers]: http://handlebarsjs.com/block_helpers.html
|
298 |
|
299 |
|
300 | ## API
|
301 |
|
302 | ### Configuration and Defaults
|
303 |
|
304 | There are two main ways to use this package: via its engine factory function, or creating `ExpressHandlebars` instances; both use the same configuration properties and defaults.
|
305 |
|
306 | ```javascript
|
307 | var exphbs = require('express-handlebars');
|
308 |
|
309 | // Using the engine factory:
|
310 | exphbs({ /* config */ });
|
311 |
|
312 | // Create an instance:
|
313 | exphbs.create({ /* config */ });
|
314 | ```
|
315 |
|
316 | The following is the list of configuration properties and their default values (if any):
|
317 |
|
318 | #### `handlebars=require('handlebars')`
|
319 | The Handlebars module/implementation. This allows for the `ExpressHandlebars` instance to use a different Handlebars module/implementation than that provided by the Handlebars npm package.
|
320 |
|
321 | #### `extname=".handlebars"`
|
322 | The string name of the file extension used by the templates. This value should correspond with the `extname` under which this view engine is registered with Express when calling `app.engine()`.
|
323 |
|
324 | The following example sets up an Express app to use `.hbs` as the file extension for views:
|
325 |
|
326 | ```javascript
|
327 | var express = require('express');
|
328 | var exphbs = require('express-handlebars');
|
329 |
|
330 | var app = express();
|
331 |
|
332 | app.engine('.hbs', exphbs({extname: '.hbs'}));
|
333 | app.set('view engine', '.hbs');
|
334 | ```
|
335 |
|
336 | **Note:** Setting the app's `"view engine"` setting will make that value the default file extension used for looking up views.
|
337 |
|
338 | #### `layoutsDir`
|
339 | Default layouts directory is relative to `express settings.view` + `layouts/`
|
340 | The string path to the directory where the layout templates reside.
|
341 |
|
342 | **Note:** If you configure Express to look for views in a custom location (e.g., `app.set('views', 'some/path/')`), and if your `partialsDir` is not relative to `express settings.view` + `layouts/`, you will need to reflect that by passing an updated path as the `layoutsDir` property in your configuration.
|
343 |
|
344 | #### `partialsDir`
|
345 | Default partials directory is relative to `express settings.view` + `partials/`
|
346 | The string path to the directory where the partials templates reside or object with the following properties:
|
347 |
|
348 | * `dir`: The string path to the directory where the partials templates reside.
|
349 | * `namespace`: Optional string namespace to prefix the partial names.
|
350 | * `templates`: Optional collection (or promise of a collection) of templates in the form: `{filename: template}`.
|
351 |
|
352 | **Note:** If you configure Express to look for views in a custom location (e.g., `app.set('views', 'some/path/')`), and if your `partialsDir` is not relative to `express settings.view` + `partials/`, you will need to reflect that by passing an updated path as the `partialsDir` property in your configuration.
|
353 |
|
354 | **Note:** Multiple partials dirs can be used by making `partialsDir` an array of strings, and/or config objects as described above. The namespacing feature is useful if multiple partials dirs are used and their file paths might clash.
|
355 |
|
356 | #### `defaultLayout`
|
357 | The string name or path of a template in the `layoutsDir` to use as the default layout. `main` is used as the default. This is overridden by a `layout` specified in the app or response `locals`. **Note:** A falsy value will render without a layout; e.g., `res.render('home', {layout: false});`.
|
358 |
|
359 | #### `helpers`
|
360 | An object which holds the helper functions used when rendering templates with this `ExpressHandlebars` instance. When rendering a template, a collection of helpers will be generated by merging: `handlebars.helpers` (global), `helpers` (instance), and `options.helpers` (render-level). This allows Handlebars' `registerHelper()` function to operate as expected, will providing two extra levels over helper overrides.
|
361 |
|
362 | #### `compilerOptions`
|
363 | An object which holds options that will be passed along to the Handlebars compiler functions: `Handlebars.compile()` and `Handlebars.precompile()`.
|
364 |
|
365 | ### Properties
|
366 |
|
367 | The public API properties are provided via `ExpressHandlebars` instances. In additional to the properties listed in the **Configuration and Defaults** section, the following are additional public properties:
|
368 |
|
369 | #### `engine`
|
370 | A function reference to the `renderView()` method which is bound to `this` `ExpressHandlebars` instance. This bound function should be used when registering this view engine with an Express app.
|
371 |
|
372 | #### `extname`
|
373 | The normalized `extname` which will _always_ start with `.` and defaults to `.handlebars`.
|
374 |
|
375 | #### `compiled`
|
376 | An object cache which holds compiled Handlebars template functions in the format: `{"path/to/template": [Function]}`.
|
377 |
|
378 | #### `precompiled`
|
379 | An object cache which holds precompiled Handlebars template strings in the format: `{"path/to/template": [String]}`.
|
380 |
|
381 | ### Methods
|
382 |
|
383 | The following is the list of public API methods provided via `ExpressHandlebars` instances:
|
384 |
|
385 | **Note:** All of the public methods return a [`Promise`][promise] (with the exception of `renderView()` which is the interface with Express.)
|
386 |
|
387 | #### `getPartials([options])`
|
388 | Retrieves the partials in the `partialsDir` and returns a Promise for an object mapping the partials in the form `{name: partial}`.
|
389 |
|
390 | By default each partial will be a compiled Handlebars template function. Use `options.precompiled` to receive the partials as precompiled templates — this is useful for sharing templates with client code.
|
391 |
|
392 | **Parameters:**
|
393 |
|
394 | * `[options]`: Optional object containing any of the following properties:
|
395 |
|
396 | * `[cache]`: Whether cached templates can be used if they have already been requested. This is recommended for production to avoid unnecessary file I/O.
|
397 |
|
398 | * `[precompiled=false]`: Whether precompiled templates should be provided, instead of compiled Handlebars template functions.
|
399 |
|
400 | The name of each partial corresponds to its location in `partialsDir`. For example, consider the following directory structure:
|
401 |
|
402 | ```
|
403 | views
|
404 | └── partials
|
405 | ├── foo
|
406 | │ └── bar.handlebars
|
407 | └── title.handlebars
|
408 |
|
409 | 2 directories, 2 files
|
410 | ```
|
411 |
|
412 | `getPartials()` would produce the following result:
|
413 |
|
414 | ```javascript
|
415 | var hbs = require('express-handlebars').create();
|
416 |
|
417 | hbs.getPartials().then(function (partials) {
|
418 | console.log(partials);
|
419 | // => { 'foo/bar': [Function],
|
420 | // => title: [Function] }
|
421 | });
|
422 | ```
|
423 |
|
424 | #### `getTemplate(filePath, [options])`
|
425 | Retrieves the template at the specified `filePath` and returns a Promise for the compiled Handlebars template function.
|
426 |
|
427 | Use `options.precompiled` to receive a precompiled Handlebars template.
|
428 |
|
429 | **Parameters:**
|
430 |
|
431 | * `filePath`: String path to the Handlebars template file.
|
432 |
|
433 | * `[options]`: Optional object containing any of the following properties:
|
434 |
|
435 | * `[cache]`: Whether a cached template can be used if it have already been requested. This is recommended for production to avoid necessary file I/O.
|
436 |
|
437 | * `[precompiled=false]`: Whether a precompiled template should be provided, instead of a compiled Handlebars template function.
|
438 |
|
439 | #### `getTemplates(dirPath, [options])`
|
440 | Retrieves all the templates in the specified `dirPath` and returns a Promise for an object mapping the compiled templates in the form `{filename: template}`.
|
441 |
|
442 | Use `options.precompiled` to receive precompiled Handlebars templates — this is useful for sharing templates with client code.
|
443 |
|
444 | **Parameters:**
|
445 |
|
446 | * `dirPath`: String path to the directory containing Handlebars template files.
|
447 |
|
448 | * `[options]`: Optional object containing any of the following properties:
|
449 |
|
450 | * `[cache]`: Whether cached templates can be used if it have already been requested. This is recommended for production to avoid necessary file I/O.
|
451 |
|
452 | * `[precompiled=false]`: Whether precompiled templates should be provided, instead of a compiled Handlebars template function.
|
453 |
|
454 | #### `render(filePath, context, [options])`
|
455 | Renders the template at the specified `filePath` with the `context`, using this instance's `helpers` and partials by default, and returns a Promise for the resulting string.
|
456 |
|
457 | **Parameters:**
|
458 |
|
459 | * `filePath`: String path to the Handlebars template file.
|
460 |
|
461 | * `context`: Object in which the template will be executed. This contains all of the values to fill into the template.
|
462 |
|
463 | * `[options]`: Optional object which can contain any of the following properties which affect this view engine's behavior:
|
464 |
|
465 | * `[cache]`: Whether a cached template can be used if it have already been requested. This is recommended for production to avoid unnecessary file I/O.
|
466 |
|
467 | * `[data]`: Optional object which can contain any data that Handlebars will pipe through the template, all helpers, and all partials. This is a side data channel.
|
468 |
|
469 | * `[helpers]`: Render-level helpers that will be used instead of any instance-level helpers; these will be merged with (and will override) any global Handlebars helper functions.
|
470 |
|
471 | * `[partials]`: Render-level partials that will be used instead of any instance-level partials. This is used internally as an optimization to avoid re-loading all the partials.
|
472 |
|
473 | #### `renderView(viewPath, options|callback, [callback])`
|
474 | Renders the template at the specified `viewPath` as the `{{{body}}}` within the layout specified by the `defaultLayout` or `options.layout`. Rendering will use this instance's `helpers` and partials, and passes the resulting string to the `callback`.
|
475 |
|
476 | This method is called by Express and is the main entry point into this Express view engine implementation. It adds the concept of a "layout" and delegates rendering to the `render()` method.
|
477 |
|
478 | The `options` will be used both as the context in which the Handlebars templates are rendered, and to signal this view engine on how it should behave, e.g., `options.cache=false` will load _always_ load the templates from disk.
|
479 |
|
480 | **Parameters:**
|
481 |
|
482 | * `viewPath`: String path to the Handlebars template file which should serve as the `{{{body}}}` when using a layout.
|
483 |
|
484 | * `[options]`: Optional object which will serve as the context in which the Handlebars templates are rendered. It may also contain any of the following properties which affect this view engine's behavior:
|
485 |
|
486 | * `[cache]`: Whether cached templates can be used if they have already been requested. This is recommended for production to avoid unnecessary file I/O.
|
487 |
|
488 | * `[data]`: Optional object which can contain any data that Handlebars will pipe through the template, all helpers, and all partials. This is a side data channel.
|
489 |
|
490 | * `[helpers]`: Render-level helpers that will be merged with (and will override) instance and global helper functions.
|
491 |
|
492 | * `[partials]`: Render-level partials will be merged with (and will override) instance and global partials. This should be a `{partialName: fn}` hash or a Promise of an object with this shape.
|
493 |
|
494 | * `[layout]`: Optional string path to the Handlebars template file to be used as the "layout". This overrides any `defaultLayout` value. Passing a falsy value will render with no layout (even if a `defaultLayout` is defined).
|
495 |
|
496 | * `callback`: Function to call once the template is retrieved.
|
497 |
|
498 | ### Hooks
|
499 |
|
500 | The following is the list of protected methods that are called internally and serve as _hooks_ to override functionality of `ExpressHandlebars` instances. A value or a promise can be returned from these methods which allows them to perform async operations.
|
501 |
|
502 | #### `_compileTemplate(template, options)`
|
503 | This hook will be called when a Handlebars template needs to be compiled. This function needs to return a compiled Handlebars template function, or a promise for one.
|
504 |
|
505 | By default this hook calls `Handlebars.compile()`, but it can be overridden to preform operations before and/or after Handlebars compiles the template. This is useful if you wanted to first process Markdown within a Handlebars template.
|
506 |
|
507 | **Parameters:**
|
508 |
|
509 | * `template`: String Handlebars template that needs to be compiled.
|
510 |
|
511 | * `options`: Object `compilerOptions` that were specified when the `ExpressHandlebars` instance as created. This object should be passed along to the `Handlebars.compile()` function.
|
512 |
|
513 | #### `_precompileTemplate(template, options)`
|
514 | This hook will be called when a Handlebars template needs to be precompiled. This function needs to return a serialized Handlebars template spec. string, or a promise for one.
|
515 |
|
516 | By default this hook calls `Handlebars.precompile()`, but it can be overridden to preform operations before and/or after Handlebars precompiles the template. This is useful if you wanted to first process Markdown within a Handlebars template.
|
517 |
|
518 | **Parameters:**
|
519 |
|
520 | * `template`: String Handlebars template that needs to be precompiled.
|
521 |
|
522 | * `options`: Object `compilerOptions` that were specified when the `ExpressHandlebars` instance as created. This object should be passed along to the `Handlebars.compile()` function.
|
523 |
|
524 | #### `_renderTemplate(template, context, options)`
|
525 | This hook will be called when a compiled Handlebars template needs to be rendered. This function needs to returned the rendered output string, or a promise for one.
|
526 |
|
527 | By default this hook simply calls the passed-in `template` with the `context` and `options` arguments, but it can be overridden to perform operations before and/or after rendering the template.
|
528 |
|
529 | **Parameters:**
|
530 |
|
531 | * `template`: Compiled Handlebars template function to call.
|
532 |
|
533 | * `context`: The context object in which to render the `template`.
|
534 |
|
535 | * `options`: Object that contains options and metadata for rendering the template:
|
536 |
|
537 | * `data`: Object to define custom `@variable` private variables.
|
538 |
|
539 | * `helpers`: Object to provide custom helpers in addition to the globally defined helpers.
|
540 |
|
541 | * `partials`: Object to provide custom partials in addition to the globally defined partials.
|
542 |
|
543 |
|
544 | [promise]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
|
545 |
|
546 |
|
547 | ## Examples
|
548 |
|
549 | ### [Basic Usage][]
|
550 |
|
551 | This example shows the most basic way to use this view engine.
|
552 |
|
553 | ### [Advanced Usage][]
|
554 |
|
555 | This example is more comprehensive and shows how to use many of the features of this view engine, including helpers, partials, multiple layouts, etc.
|
556 |
|
557 | As noted in the **Package Design** section, this view engine's implementation is instance-based, and more advanced usages can take advantage of this. The Advanced Usage example demonstrates how to use an `ExpressHandlebars` instance to share templates with the client, among other features.
|
558 |
|
559 |
|
560 | [Basic Usage]: https://github.com/express-handlebars/express-handlebars/tree/master/examples/basic
|
561 | [Advanced Usage]: https://github.com/express-handlebars/express-handlebars/tree/master/examples/advanced
|
562 |
|
563 |
|
564 | License
|
565 | -------
|
566 |
|
567 | This software is free to use under the Yahoo! Inc. BSD license. See the [LICENSE file][] for license text and copyright information.
|
568 |
|
569 |
|
570 | [LICENSE file]: https://github.com/express-handlebars/express-handlebars/blob/master/LICENSE
|