Skip to content
This repository
Newer
Older
100644 496 lines (329 sloc) 12.03 kb
f0857e5c »
2009-10-03 rtemplate => mustache
1 Mustache
6ee6bcf2 »
2009-09-24 first draft
2 =========
3
02edd2cf »
2009-10-10 references make the first paragraph it read easier
4 Inspired by [ctemplate][1] and [et][2], Mustache is a
5 framework-agnostic way to render logic-free views.
6ee6bcf2 »
2009-09-24 first draft
6
b32c566b »
2009-10-05 quote ctemplates
7 As ctemplates says, "It emphasizes separating logic from presentation:
8 it is impossible to embed application logic in this template language."
3aad2f34 »
2009-09-24 docs
9
0b217cfe »
2009-09-24 talk about tags first. they're important.
10
3aad2f34 »
2009-09-24 docs
11 Overview
12 --------
13
f0857e5c »
2009-10-03 rtemplate => mustache
14 Think of Mustache as a replacement for your views. Instead of views
3aad2f34 »
2009-09-24 docs
15 consisting of ERB or HAML with random helpers and arbitrary logic,
16 your views are broken into two parts: a Ruby class and an HTML
17 template.
18
19 We call the Ruby class the "view" and the HTML template the
20 "template."
21
22 All your logic, decisions, and code is contained in your view. All
23 your markup is contained in your template. The template does nothing
d5258f36 »
2009-10-06 whitespace
24 but reference methods in your view.
3aad2f34 »
2009-09-24 docs
25
26 This strict separation makes it easier to write clean templates,
27 easier to test your views, and more fun to work on your app's front end.
28
0b217cfe »
2009-09-24 talk about tags first. they're important.
29
1d6dfeed »
2009-09-25 why?
30 Why?
31 ----
32
33 I like writing Ruby. I like writing HTML. I like writing JavaScript.
34
35 I don't like writing ERB, Haml, Liquid, Django Templates, putting Ruby
36 in my HTML, or putting JavaScript in my HTML.
37
38
3aad2f34 »
2009-09-24 docs
39 Usage
40 -----
41
debca50f »
2009-10-08 Quick example.
42 Quick example:
43
44 >> require 'mustache'
45 => true
46 >> Mustache.render("Hello {{planet}}", :planet => "World!")
47 => "Hello World!"
48
3aad2f34 »
2009-09-24 docs
49 We've got an `examples` folder but here's the canonical one:
50
f0857e5c »
2009-10-03 rtemplate => mustache
51 class Simple < Mustache
3aad2f34 »
2009-09-24 docs
52 def name
53 "Chris"
54 end
55
56 def value
57 10_000
58 end
59
60 def taxed_value
61 value - (value * 0.4)
62 end
63
64 def in_ca
65 true
66 end
67 end
68
69 We simply create a normal Ruby class and define methods. Some methods
70 reference others, some return values, some return only booleans.
71
72 Now let's write the template:
73
74 Hello {{name}}
75 You have just won ${{value}}!
76 {{#in_ca}}
77 Well, ${{taxed_value}}, after taxes.
78 {{/in_ca}}
79
80 This template references our view methods. To bring it all together,
81 here's the code to render actual HTML;
82
9b245dd2 »
2009-10-10 `render` is the new `to_html`
83 Simple.render
3aad2f34 »
2009-09-24 docs
84
85 Which returns the following:
86
87 Hello Chris
88 You have just won $10000!
89 Well, $6000.0, after taxes.
90
91 Simple.
92
0b217cfe »
2009-09-24 talk about tags first. they're important.
93
94 Tag Types
95 ---------
96
97 Tags are indicated by the double mustaches. `{{name}}` is a tag. Let's
98 talk about the different types of tags.
99
100 ### Variables
101
102 The most basic tag is the variable. A `{{name}}` tag in a basic
103 template will try to call the `name` method on your view. If there is
104 no `name` method, an exception will be raised.
105
6f73fdf4 »
2009-10-16 Add a note in the README about raise_on_context_miss
106 All variables are HTML escaped by default. If you want to return
107 unescaped HTML, use the triple mustache: `{{{name}}}`.
108
109 By default a variable "miss" returns an empty string. You can
110 configure this by setting `Mustache.raise_on_context_miss` to true.
0b217cfe »
2009-09-24 talk about tags first. they're important.
111
112 ### Boolean Sections
113
114 A section begins with a pound and ends with a slash. That is,
115 `{{#person}}` begins a "person" section while `{{/person}}` ends it.
116
117 If the `person` method exists and calling it returns false, the HTML
118 between the pound and slash will not be displayed.
119
120 If the `person` method exists and calling it returns true, the HTML
121 between the pound and slash will be rendered and displayed.
122
123 ### Enumerable Sections
124
125 Enumerable sections are syntactically identical to boolean sections in
126 that they begin with a pound and end with a slash. The difference,
127 however, is in the view: if the method called returns an enumerable,
d5258f36 »
2009-10-06 whitespace
128 the section is repeated as the enumerable is iterated over.
0b217cfe »
2009-09-24 talk about tags first. they're important.
129
130 Each item in the enumerable is expected to be a hash which will then
131 become the context of the corresponding iteration. In this way we can
132 construct loops.
133
134 For example, imagine this template:
135
136 {{#repo}}
137 <b>{{name}}</b>
138 {{/repo}}
139
140 And this view code:
141
142 def repo
143 Repository.all.map { |r| { :name => r.to_s } }
144 end
145
146 When rendered, our view will contain a list of all repository names in
147 the database.
148
4f195418 »
2009-10-11 document hash shortcut
149 As a convenience, if a section returns a hash (as opposed to an array
150 or a boolean) it will be treated as a single item array.
151
152 With the above template, we could use this Ruby code for a single
153 iteration:
154
155 def repo
156 { :name => Repository.first.to_s }
157 end
158
159 This would be treated by Mustache as functionally equivalent to the
160 following:
161
162 def repo
163 [ { :name => Repository.first.to_s } ]
164 end
165
166
0b217cfe »
2009-09-24 talk about tags first. they're important.
167 ### Comments
168
169 Comments begin with a bang and are ignored. The following template:
170
171 <h1>Today{{! ignore me }}.</h1>
d5258f36 »
2009-10-06 whitespace
172
0b217cfe »
2009-09-24 talk about tags first. they're important.
173 Will render as follows:
174
175 <h1>Today.</h1>
176
177 ### Partials
178
bc104d17 »
2009-10-28 ctemplate compat: Partials are indicated by >, not <
179 Partials begin with a greater than sign, like `{{> box}}`.
0b217cfe »
2009-09-24 talk about tags first. they're important.
180
181 If a partial's view is loaded, we use that to render the HTML. If
182 nothing is loaded we render the template directly using our current context.
183
184 In this way partials can reference variables or sections the calling
185 view defines.
186
187
3e42d49b »
2009-10-11 document Set Delimiter
188 ### Set Delimiter
189
190 Set Delimiter tags start with an equal sign and change the tag
191 delimiters from {{ and }} to custom strings.
192
193 Consider the following contrived example:
194
195 * {{ default_tags }}
196 {{=<% %>=}}
197 * <% erb_style_tags %>
198 <%={{ }}=%>
199 * {{ default_tags_again }}
200
201 Here we have a list with three items. The first item uses the default
202 tag style, the second uses erb style as defined by the Set Delimiter
203 tag, and the third returns to the default style after yet another Set
204 Delimiter declaration.
205
206 According to [ctemplates][3], this "is useful for languages like TeX, where
207 double-braces may occur in the text and are awkward to use for
208 markup."
209
210 Custom delimiters may not contain whitespace or the equals sign.
211
212
04e852b2 »
2009-09-24 explain the dict style
213 Dict-Style Views
214 ----------------
215
216 ctemplate and friends want you to hand a dictionary to the template
515de916 »
2009-10-11 Dict example uses Winner to be more explicit, less confusing
217 processor. Mustache supports a similar concept. Feel free to mix the
218 class-based and this more procedural style at your leisure.
04e852b2 »
2009-09-24 explain the dict style
219
07144e45 »
2009-10-27 Update readme with .html => .mustache change
220 Given this template (winner.mustache):
04e852b2 »
2009-09-24 explain the dict style
221
222 Hello {{name}}
223 You have just won ${{value}}!
224
225 We can fill in the values at will:
d5258f36 »
2009-10-06 whitespace
226
515de916 »
2009-10-11 Dict example uses Winner to be more explicit, less confusing
227 view = Winner.new
228 view[:name] = 'George'
229 view[:value] = 100
230 view.render
04e852b2 »
2009-09-24 explain the dict style
231
232 Which returns:
d5258f36 »
2009-10-06 whitespace
233
04e852b2 »
2009-09-24 explain the dict style
234 Hello George
235 You have just won $100!
236
237 We can re-use the same object, too:
238
515de916 »
2009-10-11 Dict example uses Winner to be more explicit, less confusing
239 view[:name] = 'Tony'
240 view.render
04e852b2 »
2009-09-24 explain the dict style
241 Hello Tony
242 You have just won $100!
243
0b217cfe »
2009-09-24 talk about tags first. they're important.
244
671f6aa3 »
2009-09-24 document template options and make template_file configurable
245 Templates
246 ---------
247
248 A word on templates. By default, a view will try to find its template
249 on disk by searching for an HTML file in the current directory that
250 follows the classic Ruby naming convention.
251
07144e45 »
2009-10-27 Update readme with .html => .mustache change
252 TemplatePartial => ./template_partial.mustache
d5258f36 »
2009-10-06 whitespace
253
3291a2d7 »
2009-10-11 document template_extension in the README
254 You can set the search path using `Mustache.template_path`. It can be set on a
671f6aa3 »
2009-09-24 document template options and make template_file configurable
255 class by class basis:
256
f0857e5c »
2009-10-03 rtemplate => mustache
257 class Simple < Mustache
3291a2d7 »
2009-10-11 document template_extension in the README
258 self.template_path = File.dirname(__FILE__)
671f6aa3 »
2009-09-24 document template options and make template_file configurable
259 ... etc ...
260 end
261
07144e45 »
2009-10-27 Update readme with .html => .mustache change
262 Now `Simple` will look for `simple.mustache` in the directory it resides
671f6aa3 »
2009-09-24 document template options and make template_file configurable
263 in, no matter the cwd.
264
265 If you want to just change what template is used you can set
5b3b4c34 »
2009-10-05 Compile into a Proc (for speed). This required more changes:
266 `Mustache.template_file` directly:
671f6aa3 »
2009-09-24 document template options and make template_file configurable
267
07144e45 »
2009-10-27 Update readme with .html => .mustache change
268 Simple.template_file = './blah.mustache'
d5258f36 »
2009-10-06 whitespace
269
3291a2d7 »
2009-10-11 document template_extension in the README
270 Mustache also allows you to define the extension it'll use.
271
272 Simple.template_extension = 'xml'
273
274 Given all other defaults, the above line will cause Mustache to look
275 for './blah.xml'
276
277 Feel free to set the template directly:
671f6aa3 »
2009-09-24 document template options and make template_file configurable
278
5b3b4c34 »
2009-10-05 Compile into a Proc (for speed). This required more changes:
279 Simple.template = 'Hi {{person}}!'
280
3291a2d7 »
2009-10-11 document template_extension in the README
281 Or set a different template for a single instance:
5b3b4c34 »
2009-10-05 Compile into a Proc (for speed). This required more changes:
282
671f6aa3 »
2009-09-24 document template options and make template_file configurable
283 Simple.new.template = 'Hi {{person}}!'
284
285 Whatever works.
286
0b217cfe »
2009-09-24 talk about tags first. they're important.
287
40313b95 »
2009-10-27 Added autoloading
288 Views
289 -----
290
291 Mustache supports a bit of magic when it comes to views. If you're
292 authoring a plugin or extension for a web framework (Sinatra, Rails,
293 etc), check out the `view_namespace` and `view_path` settings on the
294 `Mustache` class. They will surely provide needed assistance.
295
296
70af848e »
2009-09-24 helpers?!
297 Helpers
298 -------
299
300 What about global helpers? Maybe you have a nifty `gravatar` function
d5258f36 »
2009-10-06 whitespace
301 you want to use in all your views? No problem.
70af848e »
2009-09-24 helpers?!
302
303 This is just Ruby, after all.
304
305 module ViewHelpers
306 def gravatar(email, size = 30)
307 gravatar_id = Digest::MD5.hexdigest(email.to_s.strip.downcase)
308 gravatar_for_id(gravatar_id, size)
309 end
310
311 def gravatar_for_id(gid, size = 30)
312 "#{gravatar_host}/avatar/#{gid}?s=#{size}"
313 end
314
315 def gravatar_host
316 @ssl ? 'https://secure.gravatar.com' : 'http://www.gravatar.com'
317 end
318 end
319
d5258f36 »
2009-10-06 whitespace
320 Then just include it:
70af848e »
2009-09-24 helpers?!
321
f0857e5c »
2009-10-03 rtemplate => mustache
322 class Simple < Mustache
70af848e »
2009-09-24 helpers?!
323 include ViewHelpers
324
325 def name
326 "Chris"
327 end
328
329 def value
330 10_000
331 end
332
333 def taxed_value
334 value - (value * 0.4)
335 end
336
337 def in_ca
338 true
339 end
340 end
341
342 Great, but what about that `@ssl` ivar in `gravatar_host`? There are
343 many ways we can go about setting it.
344
f0857e5c »
2009-10-03 rtemplate => mustache
345 Here's on example which illustrates a key feature of Mustache: you
70af848e »
2009-09-24 helpers?!
346 are free to use the `initialize` method just as you would in any
347 normal class.
348
f0857e5c »
2009-10-03 rtemplate => mustache
349 class Simple < Mustache
70af848e »
2009-09-24 helpers?!
350 include ViewHelpers
351
352 def initialize(ssl = false)
353 @ssl = ssl
354 end
355
356 ... etc ...
357 end
358
359 Now:
360
9b245dd2 »
2009-10-10 `render` is the new `to_html`
361 Simple.new(request.ssl?).render
70af848e »
2009-09-24 helpers?!
362
363 Convoluted but you get the idea.
364
365
d7d6f662 »
2009-10-08 mention sinatra integration in README
366 Sinatra
367 -------
368
369 Mustache ships with Sinatra integration. Please see
370 `lib/mustache/sinatra.rb` or
371 <http://defunkt.github.com/mustache/classes/Mustache/Sinatra.html> for
372 complete documentation.
373
ca401249 »
2009-10-09 reference the mustache-sinatra-example
374 An example Sinatra application is also provided:
375 <http://github.com/defunkt/mustache-sinatra-example>
376
d7d6f662 »
2009-10-08 mention sinatra integration in README
377
50ec6b7a »
2009-10-27 Added Rack::Bug panel
378 [Rack::Bug][4]
48914790 »
2009-11-23 Added `mustache` script for rendering templates on the command line.
379 --------------
50ec6b7a »
2009-10-27 Added Rack::Bug panel
380
381 Mustache also ships with a `Rack::Bug` panel. In your `config.ru` add
382 the following code:
383
384 require 'rack/bug/panels/mustache_panel'
385 use Rack::Bug::MustachePanel
386
387 Using Rails? Add this to your initializer or environment file:
388
389 require 'rack/bug/panels/mustache_panel'
390 config.middleware.use "Rack::Bug::MustachePanel"
391
e5ae4624 »
2009-10-27 screenshot!
392 [![Rack::Bug](http://img.skitch.com/20091027-xyf4h1yxnefpp7usyddrcmc7dn.png)][5]
393
50ec6b7a »
2009-10-27 Added Rack::Bug panel
394
da44c7e3 »
2009-10-16 Add mustache.vim [Juvenn Woo]
395 Vim
396 ---
397
398 Thanks to [Juvenn Woo](http://github.com/juvenn) for mustache.vim. It
399 is included under the contrib/ directory.
400
401
13bd8ed4 »
2009-10-27 Added tpl-mode.el to contrib/ for us Emacs users
402 Emacs
6f04090d »
2009-11-12 Mention Tekkub's Mustache TextMate bundle
403 -----
13bd8ed4 »
2009-10-27 Added tpl-mode.el to contrib/ for us Emacs users
404
405 tpl-mode.el is included under the contrib/ directory for any Emacs users.
406 Based on Google's tpl-mode for ctemplates, it adds support for Mustache's
407 more lenient tag values and includes a few commands for your editing pleasure.
408
409
6f04090d »
2009-11-12 Mention Tekkub's Mustache TextMate bundle
410 TextMate
411 --------
412
48914790 »
2009-11-23 Added `mustache` script for rendering templates on the command line.
413 Check out Tekkub's
6f04090d »
2009-11-12 Mention Tekkub's Mustache TextMate bundle
414 [Mustache.tmbundle](http://github.com/tekkub/Mustache.tmbundle).
415
416
48914790 »
2009-11-23 Added `mustache` script for rendering templates on the command line.
417 Command Line
418 ------------
419
420 Mustache includes a `mustache` script for rendering templates on the
421 command line. This can be useful when designing HTML that will
422 eventually be included in a website: instead of having to format the
423 HTML as Mustache later, you can do it now!
424
425 The script expects a Mustache template on STDIN with YAML
426 frontmatter. An example looks like this:
427
428 $ cat complete.mustache
429 ---
430 names: [ {name: chris}, {name: mark}, {name: scott} ]
431 ---
432 {{#names}}
433 Hi {{name}}!
434 {{/names}}
435
436 $ cat complete.mustache | mustache
437 Hi chris!
438 Hi mark!
439 Hi scott!
440
441 It's probably more useful to keep the YAML and HTML in separate files,
442 though. Luckily `cat` works great for this, too:
443
444 $ cat data.yml
445 ---
446 names: [ {name: chris}, {name: mark}, {name: scott} ]
447 ---
448
449 $ cat template.mustache
450 {{#names}}
451 Hi {{name}}!
452 {{/names}}
453
454 $ cat data.yml template.mustache | ruby -I lib bin/mustache
455 Hi chris!
456 Hi mark!
457 Hi scott!
458
459
b6e396fc »
2009-10-05 add installation and docs
460 Installation
461 ------------
462
463 ### [Gemcutter](http://gemcutter.org/)
464
465 $ gem install mustache
d5258f36 »
2009-10-06 whitespace
466
b6e396fc »
2009-10-05 add installation and docs
467 ### [Rip](http://hellorip.com)
468
469 $ rip install git://github.com/defunkt/mustache.git
470
471
05bedebb »
2009-10-06 acknowledgements
472 Acknowledgements
473 ----------------
474
475 Thanks to [Tom Preston-Werner](http://github.com/mojombo) for showing
476 me ctemplate and [Leah Culver](http://github.com/leah) for the name "Mustache."
477
478
190b84d7 »
2009-10-04 project meta info in the readme (issue tracker, mailing list, etc)
479 Meta
480 ----
141fa9ad »
2009-09-24 partials docs
481
190b84d7 »
2009-10-04 project meta info in the readme (issue tracker, mailing list, etc)
482 * Code: `git clone git://github.com/defunkt/mustache.git`
a289c2bc »
2009-10-06 add Home link
483 * Home: <http://github.com/defunkt/mustache>
b6e396fc »
2009-10-05 add installation and docs
484 * Docs: <http://defunkt.github.com/mustache>
190b84d7 »
2009-10-04 project meta info in the readme (issue tracker, mailing list, etc)
485 * Bugs: <http://github.com/defunkt/mustache/issues>
486 * List: <http://groups.google.com/group/mustache-rb>
ff3cb6d9 »
2009-10-04 add runcoderun link
487 * Test: <http://runcoderun.com/defunkt/mustache>
48b933c7 »
2009-10-06 add Gems link
488 * Gems: <http://gemcutter.org/gems/mustache>
190b84d7 »
2009-10-04 project meta info in the readme (issue tracker, mailing list, etc)
489 * Boss: Chris Wanstrath :: <http://github.com/defunkt>
02edd2cf »
2009-10-10 references make the first paragraph it read easier
490
491 [1]: http://code.google.com/p/google-ctemplate/
492 [2]: http://www.ivan.fomichev.name/2008/05/erlang-template-engine-prototype.html
3e42d49b »
2009-10-11 document Set Delimiter
493 [3]: http://google-ctemplate.googlecode.com/svn/trunk/doc/howto.html
50ec6b7a »
2009-10-27 Added Rack::Bug panel
494 [4]: http://github.com/brynary/rack-bug/
e5ae4624 »
2009-10-27 screenshot!
495 [5]: http://img.skitch.com/20091027-n8pxwwx8r61tc318a15q1n6m14.png
Something went wrong with that request. Please try again.