Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 383 lines (252 sloc) 9.176 kb
f0857e5 Chris Wanstrath rtemplate => mustache
defunkt authored
1 Mustache
6ee6bcf Chris Wanstrath first draft
defunkt authored
2 =========
3
02edd2c Chris Wanstrath references make the first paragraph it read easier
defunkt authored
4 Inspired by [ctemplate][1] and [et][2], Mustache is a
5 framework-agnostic way to render logic-free views.
6ee6bcf Chris Wanstrath first draft
defunkt authored
6
b32c566 Chris Wanstrath quote ctemplates
defunkt authored
7 As ctemplates says, "It emphasizes separating logic from presentation:
8 it is impossible to embed application logic in this template language."
3aad2f3 Chris Wanstrath docs
defunkt authored
9
0b217cf Chris Wanstrath talk about tags first. they're important.
defunkt authored
10
3aad2f3 Chris Wanstrath docs
defunkt authored
11 Overview
12 --------
13
f0857e5 Chris Wanstrath rtemplate => mustache
defunkt authored
14 Think of Mustache as a replacement for your views. Instead of views
3aad2f3 Chris Wanstrath docs
defunkt authored
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
d5258f3 Chris Wanstrath whitespace
defunkt authored
24 but reference methods in your view.
3aad2f3 Chris Wanstrath docs
defunkt authored
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
0b217cf Chris Wanstrath talk about tags first. they're important.
defunkt authored
29
1d6dfee Chris Wanstrath why?
defunkt authored
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
3aad2f3 Chris Wanstrath docs
defunkt authored
39 Usage
40 -----
41
debca50 Quick example.
Francesc Esplugas authored
42 Quick example:
43
44 >> require 'mustache'
45 => true
46 >> Mustache.render("Hello {{planet}}", :planet => "World!")
47 => "Hello World!"
48
3aad2f3 Chris Wanstrath docs
defunkt authored
49 We've got an `examples` folder but here's the canonical one:
50
f0857e5 Chris Wanstrath rtemplate => mustache
defunkt authored
51 class Simple < Mustache
3aad2f3 Chris Wanstrath docs
defunkt authored
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
9b245dd Chris Wanstrath `render` is the new `to_html`
defunkt authored
83 Simple.render
3aad2f3 Chris Wanstrath docs
defunkt authored
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
0b217cf Chris Wanstrath talk about tags first. they're important.
defunkt authored
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
106 All variables are HTML escaped by default. If you want, for some
107 reason, to return unescaped HTML you can use the triple mustache:
d5258f3 Chris Wanstrath whitespace
defunkt authored
108 `{{{name}}}`.
0b217cf Chris Wanstrath talk about tags first. they're important.
defunkt authored
109
110 ### Boolean Sections
111
112 A section begins with a pound and ends with a slash. That is,
113 `{{#person}}` begins a "person" section while `{{/person}}` ends it.
114
115 If the `person` method exists and calling it returns false, the HTML
116 between the pound and slash will not be displayed.
117
118 If the `person` method exists and calling it returns true, the HTML
119 between the pound and slash will be rendered and displayed.
120
121 ### Enumerable Sections
122
123 Enumerable sections are syntactically identical to boolean sections in
124 that they begin with a pound and end with a slash. The difference,
125 however, is in the view: if the method called returns an enumerable,
d5258f3 Chris Wanstrath whitespace
defunkt authored
126 the section is repeated as the enumerable is iterated over.
0b217cf Chris Wanstrath talk about tags first. they're important.
defunkt authored
127
128 Each item in the enumerable is expected to be a hash which will then
129 become the context of the corresponding iteration. In this way we can
130 construct loops.
131
132 For example, imagine this template:
133
134 {{#repo}}
135 <b>{{name}}</b>
136 {{/repo}}
137
138 And this view code:
139
140 def repo
141 Repository.all.map { |r| { :name => r.to_s } }
142 end
143
144 When rendered, our view will contain a list of all repository names in
145 the database.
146
147 ### Comments
148
149 Comments begin with a bang and are ignored. The following template:
150
151 <h1>Today{{! ignore me }}.</h1>
d5258f3 Chris Wanstrath whitespace
defunkt authored
152
0b217cf Chris Wanstrath talk about tags first. they're important.
defunkt authored
153 Will render as follows:
154
155 <h1>Today.</h1>
156
157 ### Partials
158
159 Partials begin with a less than sign, like `{{< box}}`.
160
161 If a partial's view is loaded, we use that to render the HTML. If
162 nothing is loaded we render the template directly using our current context.
163
164 In this way partials can reference variables or sections the calling
165 view defines.
166
167
3e42d49 Chris Wanstrath document Set Delimiter
defunkt authored
168 ### Set Delimiter
169
170 Set Delimiter tags start with an equal sign and change the tag
171 delimiters from {{ and }} to custom strings.
172
173 Consider the following contrived example:
174
175 * {{ default_tags }}
176 {{=<% %>=}}
177 * <% erb_style_tags %>
178 <%={{ }}=%>
179 * {{ default_tags_again }}
180
181 Here we have a list with three items. The first item uses the default
182 tag style, the second uses erb style as defined by the Set Delimiter
183 tag, and the third returns to the default style after yet another Set
184 Delimiter declaration.
185
186 According to [ctemplates][3], this "is useful for languages like TeX, where
187 double-braces may occur in the text and are awkward to use for
188 markup."
189
190 Custom delimiters may not contain whitespace or the equals sign.
191
192
04e852b Chris Wanstrath explain the dict style
defunkt authored
193 Dict-Style Views
194 ----------------
195
196 ctemplate and friends want you to hand a dictionary to the template
515de91 Chris Wanstrath Dict example uses Winner to be more explicit, less confusing
defunkt authored
197 processor. Mustache supports a similar concept. Feel free to mix the
198 class-based and this more procedural style at your leisure.
04e852b Chris Wanstrath explain the dict style
defunkt authored
199
515de91 Chris Wanstrath Dict example uses Winner to be more explicit, less confusing
defunkt authored
200 Given this template (winner.html):
04e852b Chris Wanstrath explain the dict style
defunkt authored
201
202 Hello {{name}}
203 You have just won ${{value}}!
204
205 We can fill in the values at will:
d5258f3 Chris Wanstrath whitespace
defunkt authored
206
515de91 Chris Wanstrath Dict example uses Winner to be more explicit, less confusing
defunkt authored
207 view = Winner.new
208 view[:name] = 'George'
209 view[:value] = 100
210 view.render
04e852b Chris Wanstrath explain the dict style
defunkt authored
211
212 Which returns:
d5258f3 Chris Wanstrath whitespace
defunkt authored
213
04e852b Chris Wanstrath explain the dict style
defunkt authored
214 Hello George
215 You have just won $100!
216
217 We can re-use the same object, too:
218
515de91 Chris Wanstrath Dict example uses Winner to be more explicit, less confusing
defunkt authored
219 view[:name] = 'Tony'
220 view.render
04e852b Chris Wanstrath explain the dict style
defunkt authored
221 Hello Tony
222 You have just won $100!
223
0b217cf Chris Wanstrath talk about tags first. they're important.
defunkt authored
224
671f6aa Chris Wanstrath document template options and make template_file configurable
defunkt authored
225 Templates
226 ---------
227
228 A word on templates. By default, a view will try to find its template
229 on disk by searching for an HTML file in the current directory that
230 follows the classic Ruby naming convention.
231
232 TemplatePartial => ./template_partial.html
d5258f3 Chris Wanstrath whitespace
defunkt authored
233
3291a2d Chris Wanstrath document template_extension in the README
defunkt authored
234 You can set the search path using `Mustache.template_path`. It can be set on a
671f6aa Chris Wanstrath document template options and make template_file configurable
defunkt authored
235 class by class basis:
236
f0857e5 Chris Wanstrath rtemplate => mustache
defunkt authored
237 class Simple < Mustache
3291a2d Chris Wanstrath document template_extension in the README
defunkt authored
238 self.template_path = File.dirname(__FILE__)
671f6aa Chris Wanstrath document template options and make template_file configurable
defunkt authored
239 ... etc ...
240 end
241
242 Now `Simple` will look for `simple.html` in the directory it resides
243 in, no matter the cwd.
244
245 If you want to just change what template is used you can set
5b3b4c3 Magnus Holm Compile into a Proc (for speed). This required more changes:
judofyr authored
246 `Mustache.template_file` directly:
671f6aa Chris Wanstrath document template options and make template_file configurable
defunkt authored
247
5b3b4c3 Magnus Holm Compile into a Proc (for speed). This required more changes:
judofyr authored
248 Simple.template_file = './blah.html'
d5258f3 Chris Wanstrath whitespace
defunkt authored
249
3291a2d Chris Wanstrath document template_extension in the README
defunkt authored
250 Mustache also allows you to define the extension it'll use.
251
252 Simple.template_extension = 'xml'
253
254 Given all other defaults, the above line will cause Mustache to look
255 for './blah.xml'
256
257 Feel free to set the template directly:
671f6aa Chris Wanstrath document template options and make template_file configurable
defunkt authored
258
5b3b4c3 Magnus Holm Compile into a Proc (for speed). This required more changes:
judofyr authored
259 Simple.template = 'Hi {{person}}!'
260
3291a2d Chris Wanstrath document template_extension in the README
defunkt authored
261 Or set a different template for a single instance:
5b3b4c3 Magnus Holm Compile into a Proc (for speed). This required more changes:
judofyr authored
262
671f6aa Chris Wanstrath document template options and make template_file configurable
defunkt authored
263 Simple.new.template = 'Hi {{person}}!'
264
265 Whatever works.
266
0b217cf Chris Wanstrath talk about tags first. they're important.
defunkt authored
267
70af848 Chris Wanstrath helpers?!
defunkt authored
268 Helpers
269 -------
270
271 What about global helpers? Maybe you have a nifty `gravatar` function
d5258f3 Chris Wanstrath whitespace
defunkt authored
272 you want to use in all your views? No problem.
70af848 Chris Wanstrath helpers?!
defunkt authored
273
274 This is just Ruby, after all.
275
276 module ViewHelpers
277 def gravatar(email, size = 30)
278 gravatar_id = Digest::MD5.hexdigest(email.to_s.strip.downcase)
279 gravatar_for_id(gravatar_id, size)
280 end
281
282 def gravatar_for_id(gid, size = 30)
283 "#{gravatar_host}/avatar/#{gid}?s=#{size}"
284 end
285
286 def gravatar_host
287 @ssl ? 'https://secure.gravatar.com' : 'http://www.gravatar.com'
288 end
289 end
290
d5258f3 Chris Wanstrath whitespace
defunkt authored
291 Then just include it:
70af848 Chris Wanstrath helpers?!
defunkt authored
292
f0857e5 Chris Wanstrath rtemplate => mustache
defunkt authored
293 class Simple < Mustache
70af848 Chris Wanstrath helpers?!
defunkt authored
294 include ViewHelpers
295
296 def name
297 "Chris"
298 end
299
300 def value
301 10_000
302 end
303
304 def taxed_value
305 value - (value * 0.4)
306 end
307
308 def in_ca
309 true
310 end
311 end
312
313 Great, but what about that `@ssl` ivar in `gravatar_host`? There are
314 many ways we can go about setting it.
315
f0857e5 Chris Wanstrath rtemplate => mustache
defunkt authored
316 Here's on example which illustrates a key feature of Mustache: you
70af848 Chris Wanstrath helpers?!
defunkt authored
317 are free to use the `initialize` method just as you would in any
318 normal class.
319
f0857e5 Chris Wanstrath rtemplate => mustache
defunkt authored
320 class Simple < Mustache
70af848 Chris Wanstrath helpers?!
defunkt authored
321 include ViewHelpers
322
323 def initialize(ssl = false)
324 @ssl = ssl
325 end
326
327 ... etc ...
328 end
329
330 Now:
331
9b245dd Chris Wanstrath `render` is the new `to_html`
defunkt authored
332 Simple.new(request.ssl?).render
70af848 Chris Wanstrath helpers?!
defunkt authored
333
334 Convoluted but you get the idea.
335
336
d7d6f66 Chris Wanstrath mention sinatra integration in README
defunkt authored
337 Sinatra
338 -------
339
340 Mustache ships with Sinatra integration. Please see
341 `lib/mustache/sinatra.rb` or
342 <http://defunkt.github.com/mustache/classes/Mustache/Sinatra.html> for
343 complete documentation.
344
ca40124 Chris Wanstrath reference the mustache-sinatra-example
defunkt authored
345 An example Sinatra application is also provided:
346 <http://github.com/defunkt/mustache-sinatra-example>
347
d7d6f66 Chris Wanstrath mention sinatra integration in README
defunkt authored
348
b6e396f Chris Wanstrath add installation and docs
defunkt authored
349 Installation
350 ------------
351
352 ### [Gemcutter](http://gemcutter.org/)
353
354 $ gem install mustache
d5258f3 Chris Wanstrath whitespace
defunkt authored
355
b6e396f Chris Wanstrath add installation and docs
defunkt authored
356 ### [Rip](http://hellorip.com)
357
358 $ rip install git://github.com/defunkt/mustache.git
359
360
05bedeb Chris Wanstrath acknowledgements
defunkt authored
361 Acknowledgements
362 ----------------
363
364 Thanks to [Tom Preston-Werner](http://github.com/mojombo) for showing
365 me ctemplate and [Leah Culver](http://github.com/leah) for the name "Mustache."
366
367
190b84d Chris Wanstrath project meta info in the readme (issue tracker, mailing list, etc)
defunkt authored
368 Meta
369 ----
141fa9a Chris Wanstrath partials docs
defunkt authored
370
190b84d Chris Wanstrath project meta info in the readme (issue tracker, mailing list, etc)
defunkt authored
371 * Code: `git clone git://github.com/defunkt/mustache.git`
a289c2b Chris Wanstrath add Home link
defunkt authored
372 * Home: <http://github.com/defunkt/mustache>
b6e396f Chris Wanstrath add installation and docs
defunkt authored
373 * Docs: <http://defunkt.github.com/mustache>
190b84d Chris Wanstrath project meta info in the readme (issue tracker, mailing list, etc)
defunkt authored
374 * Bugs: <http://github.com/defunkt/mustache/issues>
375 * List: <http://groups.google.com/group/mustache-rb>
ff3cb6d Chris Wanstrath add runcoderun link
defunkt authored
376 * Test: <http://runcoderun.com/defunkt/mustache>
48b933c Chris Wanstrath add Gems link
defunkt authored
377 * Gems: <http://gemcutter.org/gems/mustache>
190b84d Chris Wanstrath project meta info in the readme (issue tracker, mailing list, etc)
defunkt authored
378 * Boss: Chris Wanstrath :: <http://github.com/defunkt>
02edd2c Chris Wanstrath references make the first paragraph it read easier
defunkt authored
379
380 [1]: http://code.google.com/p/google-ctemplate/
381 [2]: http://www.ivan.fomichev.name/2008/05/erlang-template-engine-prototype.html
3e42d49 Chris Wanstrath document Set Delimiter
defunkt authored
382 [3]: http://google-ctemplate.googlecode.com/svn/trunk/doc/howto.html
Something went wrong with that request. Please try again.