1 | [![Travis Build Status](https://img.shields.io/travis/wycats/handlebars.js/master.svg)](https://travis-ci.org/wycats/handlebars.js)
|
2 | [![Selenium Test Status](https://saucelabs.com/buildstatus/handlebars)](https://saucelabs.com/u/handlebars)
|
3 |
|
4 | Handlebars.js
|
5 | =============
|
6 |
|
7 | Handlebars.js is an extension to the [Mustache templating
|
8 | language](http://mustache.github.com/) created by Chris Wanstrath.
|
9 | Handlebars.js and Mustache are both logicless templating languages that
|
10 | keep the view and the code separated like we all know they should be.
|
11 |
|
12 | Checkout the official Handlebars docs site at
|
13 | [http://www.handlebarsjs.com](http://www.handlebarsjs.com) and the live demo at [http://tryhandlebarsjs.com/](http://tryhandlebarsjs.com/).
|
14 |
|
15 | Installing
|
16 | ----------
|
17 |
|
18 | See our [installation documentation](http://handlebarsjs.com/installation.html).
|
19 |
|
20 | Usage
|
21 | -----
|
22 | In general, the syntax of Handlebars.js templates is a superset
|
23 | of Mustache templates. For basic syntax, check out the [Mustache
|
24 | manpage](http://mustache.github.com/mustache.5.html).
|
25 |
|
26 | Once you have a template, use the `Handlebars.compile` method to compile
|
27 | the template into a function. The generated function takes a context
|
28 | argument, which will be used to render the template.
|
29 |
|
30 | ```js
|
31 | var source = "<p>Hello, my name is {{name}}. I am from {{hometown}}. I have " +
|
32 | "{{kids.length}} kids:</p>" +
|
33 | "<ul>{{#kids}}<li>{{name}} is {{age}}</li>{{/kids}}</ul>";
|
34 | var template = Handlebars.compile(source);
|
35 |
|
36 | var data = { "name": "Alan", "hometown": "Somewhere, TX",
|
37 | "kids": [{"name": "Jimmy", "age": "12"}, {"name": "Sally", "age": "4"}]};
|
38 | var result = template(data);
|
39 |
|
40 | // Would render:
|
41 | // <p>Hello, my name is Alan. I am from Somewhere, TX. I have 2 kids:</p>
|
42 | // <ul>
|
43 | // <li>Jimmy is 12</li>
|
44 | // <li>Sally is 4</li>
|
45 | // </ul>
|
46 | ```
|
47 |
|
48 | Full documentation and more examples are at [handlebarsjs.com](http://handlebarsjs.com/).
|
49 |
|
50 | Precompiling Templates
|
51 | ----------------------
|
52 |
|
53 | Handlebars allows templates to be precompiled and included as javascript code rather than the handlebars template allowing for faster startup time. Full details are located [here](http://handlebarsjs.com/precompilation.html).
|
54 |
|
55 | Differences Between Handlebars.js and Mustache
|
56 | ----------------------------------------------
|
57 | Handlebars.js adds a couple of additional features to make writing
|
58 | templates easier and also changes a tiny detail of how partials work.
|
59 |
|
60 | - [Nested Paths](http://handlebarsjs.com/#paths)
|
61 | - [Helpers](http://handlebarsjs.com/#helpers)
|
62 | - [Block Expressions](http://handlebarsjs.com/#block-expressions)
|
63 | - [Literal Values](http://handlebarsjs.com/#literals)
|
64 | - [Delimited Comments](http://handlebarsjs.com/#comments)
|
65 |
|
66 | Block expressions have the same syntax as mustache sections but should not be confused with one another. Sections are akin to an implicit `each` or `with` statement depending on the input data and helpers are explicit pieces of code that are free to implement whatever behavior they like. The [mustache spec](http://mustache.github.io/mustache.5.html) defines the exact behavior of sections. In the case of name conflicts, helpers are given priority.
|
67 |
|
68 | ### Compatibility
|
69 |
|
70 | There are a few Mustache behaviors that Handlebars does not implement.
|
71 | - Handlebars deviates from Mustache slightly in that it does not perform recursive lookup by default. The compile time `compat` flag must be set to enable this functionality. Users should note that there is a performance cost for enabling this flag. The exact cost varies by template, but it's recommended that performance sensitive operations should avoid this mode and instead opt for explicit path references.
|
72 | - The optional Mustache-style lambdas are not supported. Instead Handlebars provides its own lambda resolution that follows the behaviors of helpers.
|
73 | - Alternative delimiters are not supported.
|
74 |
|
75 |
|
76 | Supported Environments
|
77 | ----------------------
|
78 |
|
79 | Handlebars has been designed to work in any ECMAScript 3 environment. This includes
|
80 |
|
81 | - Node.js
|
82 | - Chrome
|
83 | - Firefox
|
84 | - Safari 5+
|
85 | - Opera 11+
|
86 | - IE 6+
|
87 |
|
88 | Older versions and other runtimes are likely to work but have not been formally
|
89 | tested. The compiler requires `JSON.stringify` to be implemented natively or via a polyfill. If using the precompiler this is not necessary.
|
90 |
|
91 | [![Selenium Test Status](https://saucelabs.com/browser-matrix/handlebars.svg)](https://saucelabs.com/u/handlebars)
|
92 |
|
93 | Performance
|
94 | -----------
|
95 |
|
96 | In a rough performance test, precompiled Handlebars.js templates (in
|
97 | the original version of Handlebars.js) rendered in about half the
|
98 | time of Mustache templates. It would be a shame if it were any other
|
99 | way, since they were precompiled, but the difference in architecture
|
100 | does have some big performance advantages. Justin Marney, a.k.a.
|
101 | [gotascii](http://github.com/gotascii), confirmed that with an
|
102 | [independent test](http://sorescode.com/2010/09/12/benchmarks.html). The
|
103 | rewritten Handlebars (current version) is faster than the old version,
|
104 | with many [performance tests](https://travis-ci.org/wycats/handlebars.js/builds/33392182#L538) being 5 to 7 times faster than the Mustache equivalent.
|
105 |
|
106 |
|
107 | Upgrading
|
108 | ---------
|
109 |
|
110 | See [release-notes.md](https://github.com/wycats/handlebars.js/blob/master/release-notes.md) for upgrade notes.
|
111 |
|
112 | Known Issues
|
113 | ------------
|
114 |
|
115 | See [FAQ.md](https://github.com/wycats/handlebars.js/blob/master/FAQ.md) for known issues and common pitfalls.
|
116 |
|
117 |
|
118 | Handlebars in the Wild
|
119 | ----------------------
|
120 |
|
121 | * [Assemble](http://assemble.io), by [@jonschlinkert](https://github.com/jonschlinkert)
|
122 | and [@doowb](https://github.com/doowb), is a static site generator that uses Handlebars.js
|
123 | as its template engine.
|
124 | * [CoSchedule](http://coschedule.com) An editorial calendar for WordPress that uses Handlebars.js
|
125 | * [dashbars](https://github.com/pismute/dashbars) A modern helper library for Handlebars.js.
|
126 | * [Ember.js](http://www.emberjs.com) makes Handlebars.js the primary way to
|
127 | structure your views, also with automatic data binding support.
|
128 | * [Ghost](https://ghost.org/) Just a blogging platform.
|
129 | * [handlebars_assets](http://github.com/leshill/handlebars_assets): A Rails Asset Pipeline gem
|
130 | from Les Hill (@leshill).
|
131 | * [handlebars-helpers](https://github.com/assemble/handlebars-helpers) is an extensive library
|
132 | with 100+ handlebars helpers.
|
133 | * [handlebars-layouts](https://github.com/shannonmoeller/handlebars-layouts) is a set of helpers which implement extendible and embeddable layout blocks as seen in other popular templating languages.
|
134 | * [hbs](http://github.com/donpark/hbs): An Express.js view engine adapter for Handlebars.js,
|
135 | from Don Park.
|
136 | * [koa-hbs](https://github.com/jwilm/koa-hbs): [koa](https://github.com/koajs/koa) generator based
|
137 | renderer for Handlebars.js.
|
138 | * [jblotus](http://github.com/jblotus) created [http://tryhandlebarsjs.com](http://tryhandlebarsjs.com)
|
139 | for anyone who would like to try out Handlebars.js in their browser.
|
140 | * [jQuery plugin](http://71104.github.io/jquery-handlebars/): allows you to use
|
141 | Handlebars.js with [jQuery](http://jquery.com/).
|
142 | * [Lumbar](http://walmartlabs.github.io/lumbar) provides easy module-based template management for
|
143 | handlebars projects.
|
144 | * [Marionette.Handlebars](https://github.com/hashchange/marionette.handlebars) adds support for Handlebars and Mustache templates to Marionette.
|
145 | * [sammy.js](http://github.com/quirkey/sammy) by Aaron Quint, a.k.a. quirkey,
|
146 | supports Handlebars.js as one of its template plugins.
|
147 | * [SproutCore](http://www.sproutcore.com) uses Handlebars.js as its main
|
148 | templating engine, extending it with automatic data binding support.
|
149 | * [YUI](http://yuilibrary.com/yui/docs/handlebars/) implements a port of handlebars
|
150 | * [Swag](https://github.com/elving/swag) by [@elving](https://github.com/elving) is a growing collection of helpers for handlebars.js. Give your handlebars.js templates some swag son!
|
151 | * [DOMBars](https://github.com/blakeembrey/dombars) is a DOM-based templating engine built on the Handlebars parser and runtime **DEPRECATED**
|
152 | * [promised-handlebars](https://github.com/nknapp/promised-handlebars) is a wrapper for Handlebars that allows helpers to return Promises.
|
153 |
|
154 | External Resources
|
155 | ------------------
|
156 |
|
157 | * [Gist about Synchronous and asynchronous loading of external handlebars templates](https://gist.github.com/2287070)
|
158 |
|
159 | Have a project using Handlebars? Send us a [pull request][pull-request]!
|
160 |
|
161 | License
|
162 | -------
|
163 | Handlebars.js is released under the MIT license.
|
164 |
|
165 | [pull-request]: https://github.com/wycats/handlebars.js/pull/new/master
|