mustache 0.9.2 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
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://defunkt.github.com/mustache/>.
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://defunkt.github.com/mustache/mustache.5.html>.
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://defunkt.github.com/mustache/mustache.1.html>
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://defunkt.github.com/mustache>
390
+ * Home: <http://mustache.github.com>
370
391
  * Bugs: <http://github.com/defunkt/mustache/issues>
371
- * List: <http://groups.google.com/group/mustache-rb>
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 gh-pages`
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 origin gh-pages`
105
+ `git push site site:master`
106
106
  `git checkout master`
107
107
  puts :done
108
108
  end
data/bin/mustache CHANGED
@@ -23,7 +23,7 @@ class Mustache
23
23
  opts.separator " "
24
24
 
25
25
  opts.separator " See mustache(1) or " +
26
- "http://defunkt.github.com/mustache/mustache.1.html"
26
+ "http://mustache.github.com/mustache.1.html"
27
27
  opts.separator " for more details."
28
28
 
29
29
  opts.separator " "
@@ -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.
@@ -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
 
@@ -70,7 +70,7 @@ class Mustache
70
70
 
71
71
  # If it's just an anonymous subclass then don't bother, otherwise
72
72
  # give us a layout instance.
73
- if layout.name.empty?
73
+ if layout.name && layout.name.empty?
74
74
  layout = nil
75
75
  else
76
76
  layout = layout.new
@@ -15,6 +15,8 @@ class Mustache
15
15
  #
16
16
  # >> Mustache.render(template, hash)
17
17
  class Template
18
+ attr_reader :source
19
+
18
20
  # Expects a Mustache template as a string along with a template
19
21
  # path, which it uses to find partials.
20
22
  def initialize(source)
@@ -1,3 +1,3 @@
1
1
  class Mustache
2
- Version = '0.9.2'
2
+ Version = '0.10.0'
3
3
  end
data/man/mustache.1.ron CHANGED
@@ -124,4 +124,4 @@ Original CTemplate by Google
124
124
  ## SEE ALSO
125
125
 
126
126
  mustache(5), mustache(7), gem(1),
127
- <http://defunkt.github.com/mustache/>
127
+ <http://mustache.github.com/>
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 call the \fBname\fR method on your view. If there is
74
- no \fBname\fR method, an exception will be raised.
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 "Boolean Sections"
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, the HTML
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 true, the HTML
142
- between the pound and slash will be rendered and displayed.
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 "Enumerable Sections"
188
- Enumerable sections are syntactically identical to boolean sections in
189
- that they begin with a pound and end with a slash. The difference,
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
- Each item in the enumerable is expected to be a hash which will then
195
- become the context of the corresponding iteration. In this way we can
196
- construct loops.
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
- <b>resque</b>
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
- It is useful to think of partials as a "template expansion" \- that is,
273
- the actual partial tag will be replaced with the content of the
274
- partial. Therefor partials share the current context.
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. Let's
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 call the <code>name</code> method on your view. If there is
116
- no <code>name</code> method, an exception will be raised.</p>
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.</p>
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
  * &lt;b&gt;GitHub&lt;/b&gt;
149
150
  </code></pre>
150
151
 
151
- <h3>Boolean Sections</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, the HTML
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 true, the HTML
160
- between the pound and slash will be rendered and displayed.</p>
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
+ &lt;b&gt;{{name}}&lt;/b&gt;
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
+ &lt;b&gt;resque&lt;/b&gt;
202
+ &lt;b&gt;hub&lt;/b&gt;
203
+ &lt;b&gt;rip&lt;/b&gt;
182
204
  </code></pre>
183
205
 
184
- <h3>Enumerable Sections</h3>
206
+ <h3>Inverted Sections</h3>
185
207
 
186
- <p>Enumerable sections are syntactically identical to boolean sections in
187
- that they begin with a pound and end with a slash. The difference,
188
- however, is in the view: if the method called returns an enumerable,
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>Each item in the enumerable is expected to be a hash which will then
192
- become the context of the corresponding iteration. In this way we can
193
- construct loops.</p>
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
  &lt;b&gt;{{name}}&lt;/b&gt;
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>&lt;b&gt;resque&lt;/b&gt;
216
- &lt;b&gt;hub&lt;/b&gt;
217
- &lt;b&gt;rip&lt;/b&gt;
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>{{&gt; box}}</code>.</p>
235
254
 
236
- <p>It is useful to think of partials as a "template expansion" - that is,
237
- the actual partial tag will be replaced with the content of the
238
- partial. Therefor partials share the current context.</p>
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>&lt;%= partial :next_more, :start =&gt; start, :size =&gt; size %&gt;
262
+ </code></pre>
263
+
264
+ <p>Mustache requires only this:</p>
265
+
266
+ <pre><code>{{&gt; 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. Let's
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 call the `name` method on your view. If there is
52
- no `name` method, an exception will be raised.
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
  * &lt;b&gt;GitHub&lt;/b&gt;
82
83
  * <b>GitHub</b>
83
84
 
84
- ### Boolean Sections
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, the HTML
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, the HTML
93
- between the pound and slash will be rendered and displayed.
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
- ### Enumerable Sections
138
+ ### Inverted Sections
115
139
 
116
- Enumerable sections are syntactically identical to boolean sections in
117
- that they begin with a pound and end with a slash. The difference,
118
- however, is in the view: if the method called returns an enumerable,
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
- Each item in the enumerable is expected to be a hash which will then
122
- become the context of the corresponding iteration. In this way we can
123
- construct loops.
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
- <b>resque</b>
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
- It is useful to think of partials as a "template expansion" - that is,
164
- the actual partial tag will be replaced with the content of the
165
- partial. Therefor partials share the current context.
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://defunkt.github.com/mustache/>
258
+ <http://mustache.github.com/>
@@ -11,6 +11,7 @@
11
11
  {{/item}}
12
12
  </ul>
13
13
  {{/list}}
14
- {{#empty}}
14
+
15
+ {{^list}}
15
16
  <p>The list is empty.</p>
16
- {{/empty}}
17
+ {{/list}}
@@ -0,0 +1,7 @@
1
+ {{^t}}
2
+ * first
3
+ {{/t}}
4
+ * {{two}}
5
+ {{^t}}
6
+ * third
7
+ {{/t}}
@@ -0,0 +1,14 @@
1
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
2
+ require 'mustache'
3
+
4
+ class InvertedSection < Mustache
5
+ self.path = File.dirname(__FILE__)
6
+
7
+ def t
8
+ false
9
+ end
10
+
11
+ def two
12
+ "second"
13
+ end
14
+ end
@@ -11,6 +11,7 @@
11
11
  {{/item}}
12
12
  </ul>
13
13
  {{/list}}
14
- {{#empty}}
14
+
15
+ {{^list}}
15
16
  <p>The list is empty.</p>
16
- {{/empty}}
17
+ {{/list}}
@@ -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.9.2
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-03-29 00:00:00 -07:00
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