mustache 0.9.2 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +33 -9
- data/Rakefile +2 -2
- data/bin/mustache +1 -1
- data/lib/mustache/generator.rb +17 -0
- data/lib/mustache/parser.rb +16 -2
- data/lib/mustache/sinatra.rb +1 -1
- data/lib/mustache/template.rb +2 -0
- data/lib/mustache/version.rb +1 -1
- data/man/mustache.1.ron +1 -1
- data/man/mustache.5 +79 -30
- data/man/mustache.5.html +65 -30
- data/man/mustache.5.ron +66 -31
- data/test/fixtures/complex_view.mustache +3 -2
- data/test/fixtures/inverted_section.mustache +7 -0
- data/test/fixtures/inverted_section.rb +14 -0
- data/test/fixtures/nested_objects.mustache +3 -2
- data/test/mustache_test.rb +35 -0
- metadata +4 -2
data/README.md
CHANGED
@@ -8,7 +8,7 @@ As ctemplates says, "It emphasizes separating logic from presentation:
|
|
8
8
|
it is impossible to embed application logic in this template language."
|
9
9
|
|
10
10
|
For a list of implementations (other than Ruby) and tips, see
|
11
|
-
<http://
|
11
|
+
<http://mustache.github.com/>.
|
12
12
|
|
13
13
|
|
14
14
|
Overview
|
@@ -99,7 +99,7 @@ Tag Types
|
|
99
99
|
|
100
100
|
For a language-agnostic overview of Mustache's template syntax, see
|
101
101
|
the `mustache(5)` manpage or
|
102
|
-
<http://
|
102
|
+
<http://mustache.github.com/mustache.5.html>.
|
103
103
|
|
104
104
|
|
105
105
|
Escaping
|
@@ -336,7 +336,7 @@ Command Line
|
|
336
336
|
------------
|
337
337
|
|
338
338
|
See `mustache(1)` man page or
|
339
|
-
<http://
|
339
|
+
<http://mustache.github.com/mustache.1.html>
|
340
340
|
for command line docs.
|
341
341
|
|
342
342
|
|
@@ -347,10 +347,6 @@ Installation
|
|
347
347
|
|
348
348
|
$ gem install mustache
|
349
349
|
|
350
|
-
### [Rip](http://hellorip.com)
|
351
|
-
|
352
|
-
$ rip install git://github.com/defunkt/mustache.git
|
353
|
-
|
354
350
|
|
355
351
|
Acknowledgements
|
356
352
|
----------------
|
@@ -362,13 +358,38 @@ Special thanks to [Magnus Holm](http://judofyr.net/) for all his
|
|
362
358
|
awesome work on Mustache's parser.
|
363
359
|
|
364
360
|
|
361
|
+
Contributing
|
362
|
+
------------
|
363
|
+
|
364
|
+
Once you've made your great commits:
|
365
|
+
|
366
|
+
1. [Fork][fk] Mustache
|
367
|
+
2. Create a topic branch - `git checkout -b my_branch`
|
368
|
+
3. Push to your branch - `git push origin my_branch`
|
369
|
+
4. Create an [Issue][is] with a link to your branch
|
370
|
+
5. That's it!
|
371
|
+
|
372
|
+
You might want to checkout Resque's [Contributing][cb] wiki page for information
|
373
|
+
on coding standards, new features, etc.
|
374
|
+
|
375
|
+
|
376
|
+
Mailing List
|
377
|
+
------------
|
378
|
+
|
379
|
+
To join the list simply send an email to <mustache@librelist.com>. This
|
380
|
+
will subscribe you and send you information about your subscription,
|
381
|
+
including unsubscribe information.
|
382
|
+
|
383
|
+
The archive can be found at <http://librelist.com/browser/>.
|
384
|
+
|
385
|
+
|
365
386
|
Meta
|
366
387
|
----
|
367
388
|
|
368
389
|
* Code: `git clone git://github.com/defunkt/mustache.git`
|
369
|
-
* Home: <http://
|
390
|
+
* Home: <http://mustache.github.com>
|
370
391
|
* Bugs: <http://github.com/defunkt/mustache/issues>
|
371
|
-
* List: <
|
392
|
+
* List: <mustache@librelist.com>
|
372
393
|
* Test: <http://runcoderun.com/defunkt/mustache>
|
373
394
|
* Gems: <http://rubygems.org/gems/mustache>
|
374
395
|
|
@@ -379,3 +400,6 @@ You can also find us in `#{` on irc.freenode.net.
|
|
379
400
|
[3]: http://google-ctemplate.googlecode.com/svn/trunk/doc/howto.html
|
380
401
|
[4]: http://github.com/brynary/rack-bug/
|
381
402
|
[5]: http://img.skitch.com/20091027-n8pxwwx8r61tc318a15q1n6m14.png
|
403
|
+
[cb]: http://wiki.github.com/defunkt/resque/contributing
|
404
|
+
[fk]: http://help.github.com/forking/
|
405
|
+
[is]: http://github.com/defunkt/mustache/issues
|
data/Rakefile
CHANGED
@@ -94,7 +94,7 @@ task :pages => [ "man:build" ] do
|
|
94
94
|
end
|
95
95
|
|
96
96
|
`git commit -am 'generated manual'`
|
97
|
-
`git checkout
|
97
|
+
`git checkout site`
|
98
98
|
|
99
99
|
Dir['*.newhtml'].each do |f|
|
100
100
|
mv f, f.sub('.newhtml', '.html')
|
@@ -102,7 +102,7 @@ task :pages => [ "man:build" ] do
|
|
102
102
|
|
103
103
|
`git add .`
|
104
104
|
`git commit -m updated`
|
105
|
-
`git push
|
105
|
+
`git push site site:master`
|
106
106
|
`git checkout master`
|
107
107
|
puts :done
|
108
108
|
end
|
data/bin/mustache
CHANGED
data/lib/mustache/generator.rb
CHANGED
@@ -109,6 +109,23 @@ class Mustache
|
|
109
109
|
compiled
|
110
110
|
end
|
111
111
|
|
112
|
+
# Fired when we find an inverted section. Just like `on_section`,
|
113
|
+
# we're passed the inverted section name and the array of tokens.
|
114
|
+
def on_inverted_section(name, content)
|
115
|
+
# Convert the tokenized content of this section into a Ruby
|
116
|
+
# string we can use.
|
117
|
+
code = compile(content)
|
118
|
+
|
119
|
+
# Compile the Ruby for this inverted section now that we know
|
120
|
+
# what's inside.
|
121
|
+
ev(<<-compiled)
|
122
|
+
v = ctx[#{name.to_sym.inspect}]
|
123
|
+
if v.nil? || v == false || v.respond_to?(:empty?) && v.empty?
|
124
|
+
#{code}
|
125
|
+
end
|
126
|
+
compiled
|
127
|
+
end
|
128
|
+
|
112
129
|
# Fired when the compiler finds a partial. We want to return code
|
113
130
|
# which calls a partial at runtime instead of expanding and
|
114
131
|
# including the partial's body to allow for recursive partials.
|
data/lib/mustache/parser.rb
CHANGED
@@ -45,7 +45,7 @@ EOF
|
|
45
45
|
end
|
46
46
|
|
47
47
|
# After these types of tags, all whitespace will be skipped.
|
48
|
-
SKIP_WHITESPACE = [ '#', '/' ]
|
48
|
+
SKIP_WHITESPACE = [ '#', '^', '/' ]
|
49
49
|
|
50
50
|
# The content allowed in a tag name.
|
51
51
|
ALLOWED_CONTENT = /(\w|[?!\/-])*/
|
@@ -75,6 +75,13 @@ EOF
|
|
75
75
|
|
76
76
|
# Given a string template, returns an array of tokens.
|
77
77
|
def compile(template)
|
78
|
+
if template.respond_to?(:encoding)
|
79
|
+
@encoding = template.encoding
|
80
|
+
template = template.dup.force_encoding("BINARY")
|
81
|
+
else
|
82
|
+
@encoding = nil
|
83
|
+
end
|
84
|
+
|
78
85
|
# Keeps information about opened sections.
|
79
86
|
@sections = []
|
80
87
|
@result = [:multi]
|
@@ -102,7 +109,7 @@ EOF
|
|
102
109
|
# Since {{= rewrites ctag, we store the ctag which should be used
|
103
110
|
# when parsing this specific tag.
|
104
111
|
current_ctag = self.ctag
|
105
|
-
type = @scanner.scan(
|
112
|
+
type = @scanner.scan(/#|\^|\/|=|!|<|>|&|\{/)
|
106
113
|
@scanner.skip(/\s*/)
|
107
114
|
|
108
115
|
# ANY_CONTENT tags allow any character inside of them, while
|
@@ -124,6 +131,11 @@ EOF
|
|
124
131
|
@result << [:mustache, :section, content, block]
|
125
132
|
@sections << [content, position, @result]
|
126
133
|
@result = block
|
134
|
+
when '^'
|
135
|
+
block = [:multi]
|
136
|
+
@result << [:mustache, :inverted_section, content, block]
|
137
|
+
@sections << [content, position, @result]
|
138
|
+
@result = block
|
127
139
|
when '/'
|
128
140
|
section, pos, result = @sections.pop
|
129
141
|
@result = result
|
@@ -173,6 +185,8 @@ EOF
|
|
173
185
|
@scanner.clear
|
174
186
|
end
|
175
187
|
|
188
|
+
text.force_encoding(@encoding) if @encoding
|
189
|
+
|
176
190
|
@result << [:static, text]
|
177
191
|
end
|
178
192
|
|
data/lib/mustache/sinatra.rb
CHANGED
data/lib/mustache/template.rb
CHANGED
data/lib/mustache/version.rb
CHANGED
data/man/mustache.1.ron
CHANGED
data/man/mustache.5
CHANGED
@@ -65,13 +65,12 @@ replaced with a value, some nothing, and others a series of
|
|
65
65
|
values. This document explains the different types of Mustache tags.
|
66
66
|
.
|
67
67
|
.SH "TAG TYPES"
|
68
|
-
Tags are indicated by the double mustaches. \fB{{name}}\fR is a tag. Let's
|
69
|
-
talk about the different types of tags.
|
68
|
+
Tags are indicated by the double mustaches. \fB{{name}}\fR is a tag, as is \fB{{#name}}\fR. Let's talk about the different types of tags.
|
70
69
|
.
|
71
70
|
.SS "Variables"
|
72
71
|
The most basic tag is the variable. A \fB{{name}}\fR tag in a basic
|
73
|
-
template will try to
|
74
|
-
no \fBname\fR method,
|
72
|
+
template will try to find the \fBname\fR key or method on your view. If
|
73
|
+
there is no \fBname\fR method, nothing will be rendered.
|
75
74
|
.
|
76
75
|
.P
|
77
76
|
All variables are HTML escaped by default. If you want to return
|
@@ -83,7 +82,8 @@ useful when changing delimiters (see "Set Delimter" below).
|
|
83
82
|
.
|
84
83
|
.P
|
85
84
|
By default a variable "miss" returns an empty string. This can usually
|
86
|
-
be configured in your Mustache library.
|
85
|
+
be configured in your Mustache library. The Ruby version of Mustache
|
86
|
+
supports raising an exception in this situation, for instance.
|
87
87
|
.
|
88
88
|
.P
|
89
89
|
Template:
|
@@ -130,16 +130,27 @@ Output:
|
|
130
130
|
.
|
131
131
|
.IP "" 0
|
132
132
|
.
|
133
|
-
.SS "
|
133
|
+
.SS "Sections"
|
134
|
+
Sections render blocks of text one or more times, depending on the
|
135
|
+
value of the referenced tag.
|
136
|
+
.
|
137
|
+
.P
|
134
138
|
A section begins with a pound and ends with a slash. That is,\fB{{#person}}\fR begins a "person" section while \fB{{/person}}\fR ends it.
|
135
139
|
.
|
136
140
|
.P
|
137
|
-
If the \fBperson\fR key exists and calling it returns false
|
138
|
-
between the pound and slash will not be displayed.
|
141
|
+
If the \fBperson\fR key exists and calling it returns false or an empty
|
142
|
+
list, the HTML between the pound and slash will not be displayed.
|
143
|
+
.
|
144
|
+
.P
|
145
|
+
If the \fBperson\fR method exists and calling it returns true or an
|
146
|
+
object, the HTML between the pound and slash will be rendered and
|
147
|
+
displayed exactly one time. The object that was returned by the \fBperson\fR method will become the context of the block, as well.
|
139
148
|
.
|
140
149
|
.P
|
141
|
-
If the \fBperson\fR method exists and calling it returns
|
142
|
-
|
150
|
+
If the \fBperson\fR method exists and calling it returns a non\-empty list,
|
151
|
+
the text in the block will be displayed once for each item in the
|
152
|
+
list. The context of the block will be set to the current item for
|
153
|
+
each iteration. In this way we can loop over collections.
|
143
154
|
.
|
144
155
|
.P
|
145
156
|
Template:
|
@@ -153,6 +164,9 @@ Template:
|
|
153
164
|
{{#anything_else}}
|
154
165
|
Never shown!
|
155
166
|
{{/anything_else}}
|
167
|
+
{{#repo}}
|
168
|
+
<b>{{name}}</b>
|
169
|
+
{{/repo}}
|
156
170
|
.
|
157
171
|
.fi
|
158
172
|
.
|
@@ -165,7 +179,12 @@ Hash:
|
|
165
179
|
.
|
166
180
|
.nf
|
167
181
|
{
|
168
|
-
"person": true
|
182
|
+
"person": true,
|
183
|
+
"repo": [
|
184
|
+
{ "name": "resque" },
|
185
|
+
{ "name": "hub" },
|
186
|
+
{ "name": "rip" },
|
187
|
+
]
|
169
188
|
}
|
170
189
|
.
|
171
190
|
.fi
|
@@ -179,21 +198,23 @@ Output:
|
|
179
198
|
.
|
180
199
|
.nf
|
181
200
|
Shown!
|
201
|
+
<b>resque</b>
|
202
|
+
<b>hub</b>
|
203
|
+
<b>rip</b>
|
182
204
|
.
|
183
205
|
.fi
|
184
206
|
.
|
185
207
|
.IP "" 0
|
186
208
|
.
|
187
|
-
.SS "
|
188
|
-
|
189
|
-
|
190
|
-
however, is in the view: if the method called returns an enumerable,
|
191
|
-
the section is repeated as the enumerable is iterated over.
|
209
|
+
.SS "Inverted Sections"
|
210
|
+
An inverted section begins with a caret (hat) and ends with a
|
211
|
+
slash. That is \fB{{^person}}\fR begins a "person" inverted section while \fB{{/person}}\fR ends it.
|
192
212
|
.
|
193
213
|
.P
|
194
|
-
|
195
|
-
|
196
|
-
|
214
|
+
While sections can be used to render text one or more times based on the
|
215
|
+
value of the key given, inverted sections may render text once based
|
216
|
+
on the inverse value of the key given. That is, they will be rendered
|
217
|
+
if the key doesn't exist, is false, or is an empty list.
|
197
218
|
.
|
198
219
|
.P
|
199
220
|
Template:
|
@@ -204,6 +225,9 @@ Template:
|
|
204
225
|
{{#repo}}
|
205
226
|
<b>{{name}}</b>
|
206
227
|
{{/repo}}
|
228
|
+
{{^repo}}
|
229
|
+
No repos :(
|
230
|
+
{{/repo}}
|
207
231
|
.
|
208
232
|
.fi
|
209
233
|
.
|
@@ -216,11 +240,7 @@ Hash:
|
|
216
240
|
.
|
217
241
|
.nf
|
218
242
|
{
|
219
|
-
"repo": [
|
220
|
-
{ "name": "resque" },
|
221
|
-
{ "name": "hub" },
|
222
|
-
{ "name": "rip" },
|
223
|
-
]
|
243
|
+
"repo": []
|
224
244
|
}
|
225
245
|
.
|
226
246
|
.fi
|
@@ -233,9 +253,7 @@ Output:
|
|
233
253
|
.IP "" 4
|
234
254
|
.
|
235
255
|
.nf
|
236
|
-
|
237
|
-
<b>hub</b>
|
238
|
-
<b>rip</b>
|
256
|
+
No repos :(
|
239
257
|
.
|
240
258
|
.fi
|
241
259
|
.
|
@@ -269,9 +287,40 @@ Will render as follows:
|
|
269
287
|
Partials begin with a greater than sign, like \fB{{> box}}\fR.
|
270
288
|
.
|
271
289
|
.P
|
272
|
-
|
273
|
-
|
274
|
-
|
290
|
+
Partials are rendered at runtime (as opposed to compile time), so
|
291
|
+
recursive partials are possible. Just avoid infinite loops.
|
292
|
+
.
|
293
|
+
.P
|
294
|
+
They also inherit the calling context. Whereas in ERB you may have
|
295
|
+
this:
|
296
|
+
.
|
297
|
+
.IP "" 4
|
298
|
+
.
|
299
|
+
.nf
|
300
|
+
<%= partial :next_more, :start => start, :size => size %>
|
301
|
+
.
|
302
|
+
.fi
|
303
|
+
.
|
304
|
+
.IP "" 0
|
305
|
+
.
|
306
|
+
.P
|
307
|
+
Mustache requires only this:
|
308
|
+
.
|
309
|
+
.IP "" 4
|
310
|
+
.
|
311
|
+
.nf
|
312
|
+
{{> next_more}}
|
313
|
+
.
|
314
|
+
.fi
|
315
|
+
.
|
316
|
+
.IP "" 0
|
317
|
+
.
|
318
|
+
.P
|
319
|
+
Why? Because the \fBnext_more.mustache\fR file will inherit the \fBsize\fR and \fBstart\fR methods from the calling context.
|
320
|
+
.
|
321
|
+
.P
|
322
|
+
In this way you may want to think of partials as includes, or template
|
323
|
+
expansion, even though it's not literally true.
|
275
324
|
.
|
276
325
|
.P
|
277
326
|
For example, this template and partial:
|
data/man/mustache.5.html
CHANGED
@@ -106,14 +106,14 @@ values. This document explains the different types of Mustache tags.</p>
|
|
106
106
|
|
107
107
|
<h2>TAG TYPES</h2>
|
108
108
|
|
109
|
-
<p>Tags are indicated by the double mustaches. <code>{{name}}</code> is a tag
|
110
|
-
talk about the different types of tags.</p>
|
109
|
+
<p>Tags are indicated by the double mustaches. <code>{{name}}</code> is a tag, as is
|
110
|
+
<code>{{#name}}</code>. Let's talk about the different types of tags.</p>
|
111
111
|
|
112
112
|
<h3>Variables</h3>
|
113
113
|
|
114
114
|
<p>The most basic tag is the variable. A <code>{{name}}</code> tag in a basic
|
115
|
-
template will try to
|
116
|
-
no <code>name</code> method,
|
115
|
+
template will try to find the <code>name</code> key or method on your view. If
|
116
|
+
there is no <code>name</code> method, nothing will be rendered.</p>
|
117
117
|
|
118
118
|
<p>All variables are HTML escaped by default. If you want to return
|
119
119
|
unescaped HTML, use the triple mustache: <code>{{{name}}}</code>.</p>
|
@@ -122,7 +122,8 @@ unescaped HTML, use the triple mustache: <code>{{{name}}}</code>.</p>
|
|
122
122
|
useful when changing delimiters (see "Set Delimter" below).</p>
|
123
123
|
|
124
124
|
<p>By default a variable "miss" returns an empty string. This can usually
|
125
|
-
be configured in your Mustache library
|
125
|
+
be configured in your Mustache library. The Ruby version of Mustache
|
126
|
+
supports raising an exception in this situation, for instance.</p>
|
126
127
|
|
127
128
|
<p>Template:</p>
|
128
129
|
|
@@ -148,16 +149,26 @@ be configured in your Mustache library.</p>
|
|
148
149
|
* <b>GitHub</b>
|
149
150
|
</code></pre>
|
150
151
|
|
151
|
-
<h3>
|
152
|
+
<h3>Sections</h3>
|
153
|
+
|
154
|
+
<p>Sections render blocks of text one or more times, depending on the
|
155
|
+
value of the referenced tag.</p>
|
152
156
|
|
153
157
|
<p>A section begins with a pound and ends with a slash. That is,
|
154
158
|
<code>{{#person}}</code> begins a "person" section while <code>{{/person}}</code> ends it.</p>
|
155
159
|
|
156
|
-
<p>If the <code>person</code> key exists and calling it returns false
|
157
|
-
between the pound and slash will not be displayed.</p>
|
160
|
+
<p>If the <code>person</code> key exists and calling it returns false or an empty
|
161
|
+
list, the HTML between the pound and slash will not be displayed.</p>
|
162
|
+
|
163
|
+
<p>If the <code>person</code> method exists and calling it returns true or an
|
164
|
+
object, the HTML between the pound and slash will be rendered and
|
165
|
+
displayed exactly one time. The object that was returned by the
|
166
|
+
<code>person</code> method will become the context of the block, as well.</p>
|
158
167
|
|
159
|
-
<p>If the <code>person</code> method exists and calling it returns
|
160
|
-
|
168
|
+
<p>If the <code>person</code> method exists and calling it returns a non-empty list,
|
169
|
+
the text in the block will be displayed once for each item in the
|
170
|
+
list. The context of the block will be set to the current item for
|
171
|
+
each iteration. In this way we can loop over collections.</p>
|
161
172
|
|
162
173
|
<p>Template:</p>
|
163
174
|
|
@@ -167,54 +178,62 @@ between the pound and slash will be rendered and displayed.</p>
|
|
167
178
|
{{#anything_else}}
|
168
179
|
Never shown!
|
169
180
|
{{/anything_else}}
|
181
|
+
{{#repo}}
|
182
|
+
<b>{{name}}</b>
|
183
|
+
{{/repo}}
|
170
184
|
</code></pre>
|
171
185
|
|
172
186
|
<p>Hash:</p>
|
173
187
|
|
174
188
|
<pre><code>{
|
175
|
-
"person": true
|
189
|
+
"person": true,
|
190
|
+
"repo": [
|
191
|
+
{ "name": "resque" },
|
192
|
+
{ "name": "hub" },
|
193
|
+
{ "name": "rip" },
|
194
|
+
]
|
176
195
|
}
|
177
196
|
</code></pre>
|
178
197
|
|
179
198
|
<p>Output:</p>
|
180
199
|
|
181
200
|
<pre><code>Shown!
|
201
|
+
<b>resque</b>
|
202
|
+
<b>hub</b>
|
203
|
+
<b>rip</b>
|
182
204
|
</code></pre>
|
183
205
|
|
184
|
-
<h3>
|
206
|
+
<h3>Inverted Sections</h3>
|
185
207
|
|
186
|
-
<p>
|
187
|
-
|
188
|
-
|
189
|
-
the section is repeated as the enumerable is iterated over.</p>
|
208
|
+
<p>An inverted section begins with a caret (hat) and ends with a
|
209
|
+
slash. That is <code>{{^person}}</code> begins a "person" inverted section while
|
210
|
+
<code>{{/person}}</code> ends it.</p>
|
190
211
|
|
191
|
-
<p>
|
192
|
-
|
193
|
-
|
212
|
+
<p>While sections can be used to render text one or more times based on the
|
213
|
+
value of the key given, inverted sections may render text once based
|
214
|
+
on the inverse value of the key given. That is, they will be rendered
|
215
|
+
if the key doesn't exist, is false, or is an empty list.</p>
|
194
216
|
|
195
217
|
<p>Template:</p>
|
196
218
|
|
197
219
|
<pre><code>{{#repo}}
|
198
220
|
<b>{{name}}</b>
|
199
221
|
{{/repo}}
|
222
|
+
{{^repo}}
|
223
|
+
No repos :(
|
224
|
+
{{/repo}}
|
200
225
|
</code></pre>
|
201
226
|
|
202
227
|
<p>Hash:</p>
|
203
228
|
|
204
229
|
<pre><code>{
|
205
|
-
"repo": [
|
206
|
-
{ "name": "resque" },
|
207
|
-
{ "name": "hub" },
|
208
|
-
{ "name": "rip" },
|
209
|
-
]
|
230
|
+
"repo": []
|
210
231
|
}
|
211
232
|
</code></pre>
|
212
233
|
|
213
234
|
<p>Output:</p>
|
214
235
|
|
215
|
-
<pre><code
|
216
|
-
<b>hub</b>
|
217
|
-
<b>rip</b>
|
236
|
+
<pre><code>No repos :(
|
218
237
|
</code></pre>
|
219
238
|
|
220
239
|
<h3>Comments</h3>
|
@@ -233,9 +252,25 @@ construct loops.</p>
|
|
233
252
|
|
234
253
|
<p>Partials begin with a greater than sign, like <code>{{> box}}</code>.</p>
|
235
254
|
|
236
|
-
<p>
|
237
|
-
|
238
|
-
|
255
|
+
<p>Partials are rendered at runtime (as opposed to compile time), so
|
256
|
+
recursive partials are possible. Just avoid infinite loops.</p>
|
257
|
+
|
258
|
+
<p>They also inherit the calling context. Whereas in ERB you may have
|
259
|
+
this:</p>
|
260
|
+
|
261
|
+
<pre><code><%= partial :next_more, :start => start, :size => size %>
|
262
|
+
</code></pre>
|
263
|
+
|
264
|
+
<p>Mustache requires only this:</p>
|
265
|
+
|
266
|
+
<pre><code>{{> next_more}}
|
267
|
+
</code></pre>
|
268
|
+
|
269
|
+
<p>Why? Because the <code>next_more.mustache</code> file will inherit the <code>size</code> and
|
270
|
+
<code>start</code> methods from the calling context.</p>
|
271
|
+
|
272
|
+
<p>In this way you may want to think of partials as includes, or template
|
273
|
+
expansion, even though it's not literally true.</p>
|
239
274
|
|
240
275
|
<p>For example, this template and partial:</p>
|
241
276
|
|
data/man/mustache.5.ron
CHANGED
@@ -41,15 +41,15 @@ values. This document explains the different types of Mustache tags.
|
|
41
41
|
|
42
42
|
## TAG TYPES
|
43
43
|
|
44
|
-
Tags are indicated by the double mustaches. `{{name}}` is a tag
|
45
|
-
talk about the different types of tags.
|
44
|
+
Tags are indicated by the double mustaches. `{{name}}` is a tag, as is
|
45
|
+
`{{#name}}`. Let's talk about the different types of tags.
|
46
46
|
|
47
47
|
|
48
48
|
### Variables
|
49
49
|
|
50
50
|
The most basic tag is the variable. A `{{name}}` tag in a basic
|
51
|
-
template will try to
|
52
|
-
no `name` method,
|
51
|
+
template will try to find the `name` key or method on your view. If
|
52
|
+
there is no `name` method, nothing will be rendered.
|
53
53
|
|
54
54
|
All variables are HTML escaped by default. If you want to return
|
55
55
|
unescaped HTML, use the triple mustache: `{{{name}}}`.
|
@@ -58,7 +58,8 @@ You can also use `&` to unescape a variable: `{{& name}}`. This may be
|
|
58
58
|
useful when changing delimiters (see "Set Delimter" below).
|
59
59
|
|
60
60
|
By default a variable "miss" returns an empty string. This can usually
|
61
|
-
be configured in your Mustache library.
|
61
|
+
be configured in your Mustache library. The Ruby version of Mustache
|
62
|
+
supports raising an exception in this situation, for instance.
|
62
63
|
|
63
64
|
Template:
|
64
65
|
|
@@ -81,16 +82,27 @@ Output:
|
|
81
82
|
* <b>GitHub</b>
|
82
83
|
* <b>GitHub</b>
|
83
84
|
|
84
|
-
|
85
|
+
|
86
|
+
### Sections
|
87
|
+
|
88
|
+
Sections render blocks of text one or more times, depending on the
|
89
|
+
value of the referenced tag.
|
85
90
|
|
86
91
|
A section begins with a pound and ends with a slash. That is,
|
87
92
|
`{{#person}}` begins a "person" section while `{{/person}}` ends it.
|
88
93
|
|
89
|
-
If the `person` key exists and calling it returns false
|
90
|
-
between the pound and slash will not be displayed.
|
94
|
+
If the `person` key exists and calling it returns false or an empty
|
95
|
+
list, the HTML between the pound and slash will not be displayed.
|
91
96
|
|
92
|
-
If the `person` method exists and calling it returns true
|
93
|
-
between the pound and slash will be rendered and
|
97
|
+
If the `person` method exists and calling it returns true or an
|
98
|
+
object, the HTML between the pound and slash will be rendered and
|
99
|
+
displayed exactly one time. The object that was returned by the
|
100
|
+
`person` method will become the context of the block, as well.
|
101
|
+
|
102
|
+
If the `person` method exists and calling it returns a non-empty list,
|
103
|
+
the text in the block will be displayed once for each item in the
|
104
|
+
list. The context of the block will be set to the current item for
|
105
|
+
each iteration. In this way we can loop over collections.
|
94
106
|
|
95
107
|
Template:
|
96
108
|
|
@@ -100,49 +112,58 @@ Template:
|
|
100
112
|
{{#anything_else}}
|
101
113
|
Never shown!
|
102
114
|
{{/anything_else}}
|
115
|
+
{{#repo}}
|
116
|
+
<b>{{name}}</b>
|
117
|
+
{{/repo}}
|
103
118
|
|
104
119
|
Hash:
|
105
120
|
|
106
121
|
{
|
107
|
-
"person": true
|
122
|
+
"person": true,
|
123
|
+
"repo": [
|
124
|
+
{ "name": "resque" },
|
125
|
+
{ "name": "hub" },
|
126
|
+
{ "name": "rip" },
|
127
|
+
]
|
108
128
|
}
|
109
129
|
|
110
130
|
Output:
|
111
131
|
|
112
132
|
Shown!
|
133
|
+
<b>resque</b>
|
134
|
+
<b>hub</b>
|
135
|
+
<b>rip</b>
|
136
|
+
|
113
137
|
|
114
|
-
###
|
138
|
+
### Inverted Sections
|
115
139
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
the section is repeated as the enumerable is iterated over.
|
140
|
+
An inverted section begins with a caret (hat) and ends with a
|
141
|
+
slash. That is `{{^person}}` begins a "person" inverted section while
|
142
|
+
`{{/person}}` ends it.
|
120
143
|
|
121
|
-
|
122
|
-
|
123
|
-
|
144
|
+
While sections can be used to render text one or more times based on the
|
145
|
+
value of the key given, inverted sections may render text once based
|
146
|
+
on the inverse value of the key given. That is, they will be rendered
|
147
|
+
if the key doesn't exist, is false, or is an empty list.
|
124
148
|
|
125
149
|
Template:
|
126
150
|
|
127
151
|
{{#repo}}
|
128
152
|
<b>{{name}}</b>
|
129
153
|
{{/repo}}
|
154
|
+
{{^repo}}
|
155
|
+
No repos :(
|
156
|
+
{{/repo}}
|
130
157
|
|
131
158
|
Hash:
|
132
159
|
|
133
160
|
{
|
134
|
-
"repo": [
|
135
|
-
{ "name": "resque" },
|
136
|
-
{ "name": "hub" },
|
137
|
-
{ "name": "rip" },
|
138
|
-
]
|
161
|
+
"repo": []
|
139
162
|
}
|
140
163
|
|
141
164
|
Output:
|
142
165
|
|
143
|
-
|
144
|
-
<b>hub</b>
|
145
|
-
<b>rip</b>
|
166
|
+
No repos :(
|
146
167
|
|
147
168
|
|
148
169
|
### Comments
|
@@ -160,9 +181,23 @@ Will render as follows:
|
|
160
181
|
|
161
182
|
Partials begin with a greater than sign, like `{{> box}}`.
|
162
183
|
|
163
|
-
|
164
|
-
|
165
|
-
|
184
|
+
Partials are rendered at runtime (as opposed to compile time), so
|
185
|
+
recursive partials are possible. Just avoid infinite loops.
|
186
|
+
|
187
|
+
They also inherit the calling context. Whereas in ERB you may have
|
188
|
+
this:
|
189
|
+
|
190
|
+
<%= partial :next_more, :start => start, :size => size %>
|
191
|
+
|
192
|
+
Mustache requires only this:
|
193
|
+
|
194
|
+
{{> next_more}}
|
195
|
+
|
196
|
+
Why? Because the `next_more.mustache` file will inherit the `size` and
|
197
|
+
`start` methods from the calling context.
|
198
|
+
|
199
|
+
In this way you may want to think of partials as includes, or template
|
200
|
+
expansion, even though it's not literally true.
|
166
201
|
|
167
202
|
For example, this template and partial:
|
168
203
|
|
@@ -220,4 +255,4 @@ Original CTemplate by Google
|
|
220
255
|
## SEE ALSO
|
221
256
|
|
222
257
|
mustache(1), mustache(7), gem(1),
|
223
|
-
<http://
|
258
|
+
<http://mustache.github.com/>
|
data/test/mustache_test.rb
CHANGED
@@ -57,6 +57,16 @@ rendered
|
|
57
57
|
rendered
|
58
58
|
end
|
59
59
|
|
60
|
+
def test_single_line_inverted_sections
|
61
|
+
html = %(<p class="flash-notice" {{^ flash }}style="display: none;"{{/ flash }}>)
|
62
|
+
|
63
|
+
instance = Mustache.new
|
64
|
+
instance.template = html
|
65
|
+
assert_equal <<-rendered.strip, instance.render
|
66
|
+
<p class="flash-notice" style="display: none;">
|
67
|
+
rendered
|
68
|
+
end
|
69
|
+
|
60
70
|
def test_simple
|
61
71
|
assert_equal <<-end_simple, Simple.render
|
62
72
|
Hello Chris
|
@@ -123,6 +133,14 @@ end_template
|
|
123
133
|
end_section
|
124
134
|
end
|
125
135
|
|
136
|
+
def test_inverted_section
|
137
|
+
assert_equal <<-end_section.strip, InvertedSection.render.strip
|
138
|
+
* first
|
139
|
+
* second
|
140
|
+
* third
|
141
|
+
end_section
|
142
|
+
end
|
143
|
+
|
126
144
|
def test_comments
|
127
145
|
assert_equal "<h1>A Comedy of Errors</h1>\n", Comments.render
|
128
146
|
end
|
@@ -393,4 +411,21 @@ rendered
|
|
393
411
|
<h2>中文又来啦</h2>
|
394
412
|
rendered
|
395
413
|
end
|
414
|
+
|
415
|
+
def test_indentation
|
416
|
+
view = Mustache.new
|
417
|
+
view[:name] = 'indent'
|
418
|
+
view[:text] = 'puts :indented!'
|
419
|
+
view.template = <<template
|
420
|
+
def {{name}}
|
421
|
+
{{text}}
|
422
|
+
end
|
423
|
+
template
|
424
|
+
|
425
|
+
assert_equal <<template, view.render
|
426
|
+
def indent
|
427
|
+
puts :indented!
|
428
|
+
end
|
429
|
+
template
|
430
|
+
end
|
396
431
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mustache
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Wanstrath
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-
|
12
|
+
date: 2010-04-02 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -69,6 +69,8 @@ files:
|
|
69
69
|
- test/fixtures/escaped.rb
|
70
70
|
- test/fixtures/inner_partial.mustache
|
71
71
|
- test/fixtures/inner_partial.txt
|
72
|
+
- test/fixtures/inverted_section.mustache
|
73
|
+
- test/fixtures/inverted_section.rb
|
72
74
|
- test/fixtures/namespaced.mustache
|
73
75
|
- test/fixtures/namespaced.rb
|
74
76
|
- test/fixtures/nested_objects.mustache
|