mustache 0.99.4 → 1.1.3
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.
- checksums.yaml +7 -0
- data/README.md +183 -183
- data/Rakefile +6 -14
- data/bin/mustache +28 -14
- data/lib/mustache/context.rb +98 -46
- data/lib/mustache/context_miss.rb +55 -0
- data/lib/mustache/enumerable.rb +3 -0
- data/lib/mustache/generator.rb +63 -42
- data/lib/mustache/parser.rb +173 -65
- data/lib/mustache/settings.rb +84 -24
- data/lib/mustache/template.rb +74 -4
- data/lib/mustache/utils.rb +31 -0
- data/lib/mustache/version.rb +1 -1
- data/lib/mustache.rb +116 -96
- data/man/mustache.1 +25 -40
- data/man/mustache.1.html +90 -81
- data/man/mustache.1.ron +6 -6
- data/man/mustache.5 +338 -298
- data/man/mustache.5.html +400 -115
- data/man/mustache.5.ron +292 -32
- data/test/autoloading_test.rb +7 -3
- data/test/fixtures/comments.rb +0 -1
- data/test/fixtures/complex_view.rb +0 -1
- data/test/fixtures/crazy_recursive.rb +0 -1
- data/test/fixtures/delimiters.rb +0 -1
- data/test/fixtures/dot_notation.rb +0 -1
- data/test/fixtures/double_section.rb +0 -1
- data/test/fixtures/inverted_section.rb +0 -1
- data/test/fixtures/lambda.rb +0 -1
- data/test/fixtures/liberal.mustache +1 -0
- data/test/fixtures/liberal.rb +25 -0
- data/test/fixtures/method_missing.rb +0 -1
- data/test/fixtures/namespaced.rb +0 -1
- data/test/fixtures/nested_objects.rb +0 -1
- data/test/fixtures/override/passenger.conf +6 -0
- data/test/fixtures/partial_with_module.rb +0 -1
- data/test/fixtures/passenger.rb +0 -1
- data/test/fixtures/recursive.rb +0 -1
- data/test/fixtures/simple.rb +0 -1
- data/test/fixtures/simply_complicated.mustache +25 -0
- data/test/fixtures/template_partial.rb +0 -1
- data/test/fixtures/unescaped.rb +0 -1
- data/test/helper.rb +5 -2
- data/test/mustache_test.rb +210 -25
- data/test/parser_test.rb +90 -7
- data/test/partial_test.rb +16 -4
- data/test/path_test.rb +49 -0
- data/test/spec_test.rb +5 -5
- data/test/template_test.rb +35 -3
- metadata +37 -59
- data/lib/mustache/sinatra.rb +0 -186
- data/lib/rack/bug/panels/mustache_panel/mustache_extension.rb +0 -27
- data/lib/rack/bug/panels/mustache_panel/view.mustache +0 -46
- data/lib/rack/bug/panels/mustache_panel.rb +0 -81
data/man/mustache.5
CHANGED
|
@@ -1,576 +1,616 @@
|
|
|
1
|
-
.\" generated with Ronn/v0.
|
|
2
|
-
.\" http://github.com/
|
|
3
|
-
.
|
|
4
|
-
.TH "MUSTACHE" "5" "May 2010" "DEFUNKT" "Mustache Manual"
|
|
5
|
-
.
|
|
1
|
+
.\" generated with Ronn-NG/v0.9.1
|
|
2
|
+
.\" http://github.com/apjanke/ronn-ng/tree/0.9.1
|
|
3
|
+
.TH "MUSTACHE" "5" "September 2022" "DEFUNKT" "Mustache Manual"
|
|
6
4
|
.SH "NAME"
|
|
7
|
-
\fBmustache\fR
|
|
8
|
-
.
|
|
5
|
+
\fBmustache\fR \- Logic\-less templates\.
|
|
9
6
|
.SH "SYNOPSIS"
|
|
10
7
|
A typical Mustache template:
|
|
11
|
-
.
|
|
12
8
|
.IP "" 4
|
|
13
|
-
.
|
|
14
9
|
.nf
|
|
15
|
-
|
|
16
10
|
Hello {{name}}
|
|
17
11
|
You have just won {{value}} dollars!
|
|
18
12
|
{{#in_ca}}
|
|
19
|
-
Well, {{taxed_value}} dollars, after taxes
|
|
13
|
+
Well, {{taxed_value}} dollars, after taxes\.
|
|
20
14
|
{{/in_ca}}
|
|
21
|
-
.
|
|
22
15
|
.fi
|
|
23
|
-
.
|
|
24
16
|
.IP "" 0
|
|
25
|
-
.
|
|
26
17
|
.P
|
|
27
18
|
Given the following hash:
|
|
28
|
-
.
|
|
29
19
|
.IP "" 4
|
|
30
|
-
.
|
|
31
20
|
.nf
|
|
32
|
-
|
|
33
21
|
{
|
|
34
22
|
"name": "Chris",
|
|
35
23
|
"value": 10000,
|
|
36
|
-
"taxed_value": 10000 \- (10000 * 0
|
|
24
|
+
"taxed_value": 10000 \- (10000 * 0\.4),
|
|
37
25
|
"in_ca": true
|
|
38
26
|
}
|
|
39
|
-
.
|
|
40
27
|
.fi
|
|
41
|
-
.
|
|
42
28
|
.IP "" 0
|
|
43
|
-
.
|
|
44
29
|
.P
|
|
45
30
|
Will produce the following:
|
|
46
|
-
.
|
|
47
31
|
.IP "" 4
|
|
48
|
-
.
|
|
49
32
|
.nf
|
|
50
|
-
|
|
51
33
|
Hello Chris
|
|
52
34
|
You have just won 10000 dollars!
|
|
53
|
-
Well, 6000
|
|
54
|
-
.
|
|
35
|
+
Well, 6000\.0 dollars, after taxes\.
|
|
55
36
|
.fi
|
|
56
|
-
.
|
|
57
37
|
.IP "" 0
|
|
58
|
-
.
|
|
59
38
|
.SH "DESCRIPTION"
|
|
60
|
-
Mustache can be used for HTML, config files, source code \-
|
|
61
|
-
anything. It works by expanding tags in a template using values
|
|
62
|
-
provided in a hash or object.
|
|
63
|
-
.
|
|
39
|
+
Mustache can be used for HTML, config files, source code \- anything\. It works by expanding tags in a template using values provided in a hash or object\.
|
|
64
40
|
.P
|
|
65
|
-
We call it "logic\-less" because there are no if statements, else
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
values. This document explains the different types of Mustache tags.
|
|
69
|
-
.
|
|
41
|
+
We call it "logic\-less" because there are no if statements, else clauses, or for loops\. Instead there are only tags\. Some tags are replaced with a value, some nothing, and others a series of values\. This document explains the different types of Mustache tags\.
|
|
42
|
+
.P
|
|
43
|
+
The Mustache language has a formal specification \fIhttps://github\.com/mustache/spec\fR\. The current manpage reflects version 1\.3\.0 of the specification, including the official\-but\-optional extensions for lambdas and inheritance\.
|
|
70
44
|
.SH "TAG TYPES"
|
|
71
|
-
Tags are indicated by the double mustaches
|
|
72
|
-
is \fB{{#person}}\fR. In both examples, we'd refer to \fBperson\fR as the key
|
|
73
|
-
or tag key. Let's talk about the different types of tags.
|
|
74
|
-
.
|
|
45
|
+
Tags are indicated by the double mustaches\. \fB{{person}}\fR is a tag, as is \fB{{#person}}\fR\. In both examples, we'd refer to \fBperson\fR as the key or tag key\. Let's talk about the different types of tags\.
|
|
75
46
|
.SS "Variables"
|
|
76
|
-
The most basic tag type is the variable
|
|
77
|
-
template will try to find the \fBname\fR key in the current context. If
|
|
78
|
-
there is no \fBname\fR key, nothing will be rendered.
|
|
79
|
-
.
|
|
47
|
+
The most basic tag type is the variable\. A \fB{{name}}\fR tag in a basic template will try to find the \fBname\fR key in the current context\. If there is no \fBname\fR key, the parent contexts will be checked recursively\. If the top context is reached and the \fBname\fR key is still not found, nothing will be rendered\.
|
|
80
48
|
.P
|
|
81
|
-
All variables are HTML escaped by default
|
|
82
|
-
unescaped HTML, use the triple mustache: \fB{{{name}}}\fR.
|
|
83
|
-
.
|
|
49
|
+
All variables are HTML escaped by default\. If you want to return raw contents without escaping, use the triple mustache: \fB{{{name}}}\fR\.
|
|
84
50
|
.P
|
|
85
|
-
You can also use \fB&\fR to
|
|
86
|
-
useful when changing delimiters (see "Set Delimiter" below).
|
|
87
|
-
.
|
|
51
|
+
You can also use \fB&\fR to return its raw contents: \fB{{& name}}\fR\. This may be useful when changing delimiters (see "Set Delimiter" below)\.
|
|
88
52
|
.P
|
|
89
|
-
By default a variable "miss" returns an empty string
|
|
90
|
-
be configured in your Mustache library. The Ruby version of Mustache
|
|
91
|
-
supports raising an exception in this situation, for instance.
|
|
92
|
-
.
|
|
53
|
+
By default a variable "miss" returns an empty string\. This can usually be configured in your Mustache library\. The Ruby version of Mustache supports raising an exception in this situation, for instance\.
|
|
93
54
|
.P
|
|
94
55
|
Template:
|
|
95
|
-
.
|
|
96
56
|
.IP "" 4
|
|
97
|
-
.
|
|
98
57
|
.nf
|
|
99
|
-
|
|
100
58
|
* {{name}}
|
|
101
59
|
* {{age}}
|
|
102
60
|
* {{company}}
|
|
103
61
|
* {{{company}}}
|
|
104
|
-
.
|
|
105
62
|
.fi
|
|
106
|
-
.
|
|
107
63
|
.IP "" 0
|
|
108
|
-
.
|
|
109
64
|
.P
|
|
110
65
|
Hash:
|
|
111
|
-
.
|
|
112
66
|
.IP "" 4
|
|
113
|
-
.
|
|
114
67
|
.nf
|
|
115
|
-
|
|
116
68
|
{
|
|
117
69
|
"name": "Chris",
|
|
118
70
|
"company": "<b>GitHub</b>"
|
|
119
71
|
}
|
|
120
|
-
.
|
|
121
72
|
.fi
|
|
122
|
-
.
|
|
123
73
|
.IP "" 0
|
|
124
|
-
.
|
|
125
74
|
.P
|
|
126
75
|
Output:
|
|
127
|
-
.
|
|
128
76
|
.IP "" 4
|
|
129
|
-
.
|
|
130
77
|
.nf
|
|
131
|
-
|
|
132
78
|
* Chris
|
|
133
79
|
*
|
|
134
80
|
* <b>GitHub</b>
|
|
135
81
|
* <b>GitHub</b>
|
|
136
|
-
.
|
|
137
82
|
.fi
|
|
138
|
-
.
|
|
139
83
|
.IP "" 0
|
|
140
|
-
.
|
|
84
|
+
.P
|
|
85
|
+
\fBDotted Names\fR
|
|
86
|
+
.P
|
|
87
|
+
If the \fBname\fR contains dots, it is split on the dots to obtain multiple keys\. The first key is looked up in the context as described above\. If it is found, the next key is looked up within the previous result\. This is repeated until a key is not found or until the last key is found\. The final result is interpolated as above\.
|
|
88
|
+
.P
|
|
89
|
+
Template:
|
|
90
|
+
.IP "" 4
|
|
91
|
+
.nf
|
|
92
|
+
* {{client\.name}}
|
|
93
|
+
* {{age}}
|
|
94
|
+
* {{client\.company\.name}}
|
|
95
|
+
* {{{company\.name}}}
|
|
96
|
+
.fi
|
|
97
|
+
.IP "" 0
|
|
98
|
+
.P
|
|
99
|
+
Hash:
|
|
100
|
+
.IP "" 4
|
|
101
|
+
.nf
|
|
102
|
+
{
|
|
103
|
+
"client": {
|
|
104
|
+
"name": "Chris & Friends",
|
|
105
|
+
"age": 50
|
|
106
|
+
},
|
|
107
|
+
"company": {
|
|
108
|
+
"name": "<b>GitHub</b>"
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
.fi
|
|
112
|
+
.IP "" 0
|
|
113
|
+
.P
|
|
114
|
+
Output:
|
|
115
|
+
.IP "" 4
|
|
116
|
+
.nf
|
|
117
|
+
* Chris & Friends
|
|
118
|
+
*
|
|
119
|
+
*
|
|
120
|
+
* <b>GitHub</b>
|
|
121
|
+
.fi
|
|
122
|
+
.IP "" 0
|
|
123
|
+
.P
|
|
124
|
+
\fBImplicit Iterator\fR
|
|
125
|
+
.P
|
|
126
|
+
As a special case, if the \fBname\fR consists of only a dot and nothing else, the value that is the current context is interpolated as a whole\. This is especially useful if the parent context is a list; see \fBSections\fR below\.
|
|
127
|
+
.P
|
|
128
|
+
Template:
|
|
129
|
+
.IP "" 4
|
|
130
|
+
.nf
|
|
131
|
+
* {{\.}}
|
|
132
|
+
.fi
|
|
133
|
+
.IP "" 0
|
|
134
|
+
.P
|
|
135
|
+
Current context:
|
|
136
|
+
.IP "" 4
|
|
137
|
+
.nf
|
|
138
|
+
"Hello!"
|
|
139
|
+
.fi
|
|
140
|
+
.IP "" 0
|
|
141
|
+
.P
|
|
142
|
+
Output:
|
|
143
|
+
.IP "" 4
|
|
144
|
+
.nf
|
|
145
|
+
* Hello!
|
|
146
|
+
.fi
|
|
147
|
+
.IP "" 0
|
|
148
|
+
.P
|
|
149
|
+
\fBLambdas\fR
|
|
150
|
+
.P
|
|
151
|
+
If any value found during the lookup is a callable object, such as a function or lambda, this object will be invoked with zero arguments\. The value that is returned is then used instead of the callable object itself\.
|
|
152
|
+
.P
|
|
153
|
+
An \fBoptional\fR part of the specification states that if the final key in the \fBname\fR is a lambda that returns a string, then that string should be rendered as a Mustache template before interpolation\. It will be rendered using the default delimiters (see \fBSet Delimiter\fR below) against the current context\.
|
|
154
|
+
.P
|
|
155
|
+
Template:
|
|
156
|
+
.IP "" 4
|
|
157
|
+
.nf
|
|
158
|
+
* {{time\.hour}}
|
|
159
|
+
* {{today}}
|
|
160
|
+
.fi
|
|
161
|
+
.IP "" 0
|
|
162
|
+
.P
|
|
163
|
+
Hash:
|
|
164
|
+
.IP "" 4
|
|
165
|
+
.nf
|
|
166
|
+
{
|
|
167
|
+
"year": 1970,
|
|
168
|
+
"month": 1,
|
|
169
|
+
"day": 1,
|
|
170
|
+
"time": function() {
|
|
171
|
+
return {
|
|
172
|
+
"hour": 0,
|
|
173
|
+
"minute": 0,
|
|
174
|
+
"second": 0
|
|
175
|
+
}
|
|
176
|
+
},
|
|
177
|
+
"today": function() {
|
|
178
|
+
return "{{year}}\-{{month}}\-{{day}}"
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
.fi
|
|
182
|
+
.IP "" 0
|
|
183
|
+
.P
|
|
184
|
+
Output:
|
|
185
|
+
.IP "" 4
|
|
186
|
+
.nf
|
|
187
|
+
* 0
|
|
188
|
+
* 1970\-1\-1
|
|
189
|
+
.fi
|
|
190
|
+
.IP "" 0
|
|
141
191
|
.SS "Sections"
|
|
142
|
-
Sections render blocks of text
|
|
143
|
-
value of the key in the current context.
|
|
144
|
-
.
|
|
192
|
+
Sections render blocks of text zero or more times, depending on the value of the key in the current context\.
|
|
145
193
|
.P
|
|
146
|
-
|
|
147
|
-
.
|
|
194
|
+
Lookup of dotted names works in the same way as with variables, except for slightly different treatment of lambdas\. More on this below\.
|
|
148
195
|
.P
|
|
149
|
-
|
|
150
|
-
.
|
|
196
|
+
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\.
|
|
197
|
+
.P
|
|
198
|
+
The behavior of the section is determined by the final value of the key lookup\.
|
|
151
199
|
.P
|
|
152
200
|
\fBFalse Values or Empty Lists\fR
|
|
153
|
-
.
|
|
154
201
|
.P
|
|
155
|
-
If the \fBperson\fR key exists and has a value of false or an empty
|
|
156
|
-
list, the HTML between the pound and slash will not be displayed.
|
|
157
|
-
.
|
|
202
|
+
If the \fBperson\fR key exists and has a value of false or an empty list, the HTML between the pound and slash will not be displayed\.
|
|
158
203
|
.P
|
|
159
204
|
Template:
|
|
160
|
-
.
|
|
161
205
|
.IP "" 4
|
|
162
|
-
.
|
|
163
206
|
.nf
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
{{#nothin}}
|
|
207
|
+
Shown\.
|
|
208
|
+
{{#person}}
|
|
167
209
|
Never shown!
|
|
168
|
-
{{/
|
|
169
|
-
.
|
|
210
|
+
{{/person}}
|
|
170
211
|
.fi
|
|
171
|
-
.
|
|
172
212
|
.IP "" 0
|
|
173
|
-
.
|
|
174
213
|
.P
|
|
175
214
|
Hash:
|
|
176
|
-
.
|
|
177
215
|
.IP "" 4
|
|
178
|
-
.
|
|
179
216
|
.nf
|
|
180
|
-
|
|
181
217
|
{
|
|
182
|
-
"person":
|
|
218
|
+
"person": false
|
|
183
219
|
}
|
|
184
|
-
.
|
|
185
220
|
.fi
|
|
186
|
-
.
|
|
187
221
|
.IP "" 0
|
|
188
|
-
.
|
|
189
222
|
.P
|
|
190
223
|
Output:
|
|
191
|
-
.
|
|
192
224
|
.IP "" 4
|
|
193
|
-
.
|
|
194
225
|
.nf
|
|
195
|
-
|
|
196
|
-
Shown.
|
|
197
|
-
.
|
|
226
|
+
Shown\.
|
|
198
227
|
.fi
|
|
199
|
-
.
|
|
200
228
|
.IP "" 0
|
|
201
|
-
.
|
|
202
229
|
.P
|
|
203
230
|
\fBNon\-Empty Lists\fR
|
|
204
|
-
.
|
|
205
231
|
.P
|
|
206
|
-
If the \
|
|
207
|
-
the pound and slash will be rendered and displayed one or more times.
|
|
232
|
+
If the \fBrepo\fR key exists and has a non\-false value, the HTML between the pound and slash will be rendered and displayed one or more times\.
|
|
208
233
|
.
|
|
209
234
|
.P
|
|
210
|
-
When the value is a non\-empty list, the text in the block will be
|
|
211
|
-
displayed once for each item in the list. The context of the block
|
|
212
|
-
will be set to the current item for each iteration. In this way we can
|
|
213
|
-
loop over collections.
|
|
214
|
-
.
|
|
235
|
+
When the value is a non\-empty list, the text in the block will be displayed once for each item in the list\. The context of the block will be set to the current item for each iteration\. In this way we can loop over collections\.
|
|
215
236
|
.P
|
|
216
237
|
Template:
|
|
217
|
-
.
|
|
218
238
|
.IP "" 4
|
|
219
|
-
.
|
|
220
239
|
.nf
|
|
221
|
-
|
|
222
240
|
{{#repo}}
|
|
223
241
|
<b>{{name}}</b>
|
|
224
242
|
{{/repo}}
|
|
225
|
-
.
|
|
226
243
|
.fi
|
|
227
|
-
.
|
|
228
244
|
.IP "" 0
|
|
229
|
-
.
|
|
230
245
|
.P
|
|
231
246
|
Hash:
|
|
232
|
-
.
|
|
233
247
|
.IP "" 4
|
|
234
|
-
.
|
|
235
248
|
.nf
|
|
236
|
-
|
|
237
249
|
{
|
|
238
250
|
"repo": [
|
|
239
251
|
{ "name": "resque" },
|
|
240
252
|
{ "name": "hub" },
|
|
241
|
-
{ "name": "rip" }
|
|
253
|
+
{ "name": "rip" }
|
|
242
254
|
]
|
|
243
255
|
}
|
|
244
|
-
.
|
|
245
256
|
.fi
|
|
246
|
-
.
|
|
247
257
|
.IP "" 0
|
|
248
|
-
.
|
|
249
258
|
.P
|
|
250
259
|
Output:
|
|
251
|
-
.
|
|
252
260
|
.IP "" 4
|
|
253
|
-
.
|
|
254
261
|
.nf
|
|
255
|
-
|
|
256
|
-
<b>
|
|
257
|
-
<b>
|
|
258
|
-
|
|
259
|
-
.
|
|
262
|
+
<b>resque</b>
|
|
263
|
+
<b>hub</b>
|
|
264
|
+
<b>rip</b>
|
|
265
|
+
.fi
|
|
266
|
+
.IP "" 0
|
|
267
|
+
.P
|
|
268
|
+
The same effect as above can be obtained without nested objects, by using the implicit iterator (see \fBVariables\fR above)\.
|
|
269
|
+
.P
|
|
270
|
+
Template:
|
|
271
|
+
.IP "" 4
|
|
272
|
+
.nf
|
|
273
|
+
{{#repo}}
|
|
274
|
+
<b>{{\.}}</b>
|
|
275
|
+
{{/repo}}
|
|
276
|
+
.fi
|
|
277
|
+
.IP "" 0
|
|
278
|
+
.P
|
|
279
|
+
Hash:
|
|
280
|
+
.IP "" 4
|
|
281
|
+
.nf
|
|
282
|
+
{
|
|
283
|
+
"repo": ["resque", "hub", "rip"]
|
|
284
|
+
}
|
|
285
|
+
.fi
|
|
286
|
+
.IP "" 0
|
|
287
|
+
.P
|
|
288
|
+
Output:
|
|
289
|
+
.IP "" 4
|
|
290
|
+
.nf
|
|
291
|
+
<b>resque</b>
|
|
292
|
+
<b>hub</b>
|
|
293
|
+
<b>rip</b>
|
|
260
294
|
.fi
|
|
261
|
-
.
|
|
262
295
|
.IP "" 0
|
|
263
|
-
.
|
|
264
296
|
.P
|
|
265
297
|
\fBLambdas\fR
|
|
266
|
-
.
|
|
267
298
|
.P
|
|
268
|
-
When
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
\- the lambda should do that on its own. In this way you can implement
|
|
272
|
-
filters or caching.
|
|
273
|
-
.
|
|
299
|
+
When any value found during the lookup is a callable object, such as a function or lambda, the object will be invoked and passed the block of text\. The text passed is the literal block, unrendered\. \fB{{tags}}\fR will not have been expanded\.
|
|
300
|
+
.P
|
|
301
|
+
An \fBoptional\fR part of the specification states that if the final key in the \fBname\fR is a lambda that returns a string, then that string replaces the content of the section\. It will be rendered using the same delimiters (see \fBSet Delimiter\fR below) as the original section content\. In this way you can implement filters or caching\.
|
|
274
302
|
.P
|
|
275
303
|
Template:
|
|
276
|
-
.
|
|
277
304
|
.IP "" 4
|
|
278
|
-
.
|
|
279
305
|
.nf
|
|
280
|
-
|
|
281
|
-
{{#wrapped}}
|
|
282
|
-
{{name}} is awesome.
|
|
283
|
-
{{/wrapped}}
|
|
284
|
-
.
|
|
306
|
+
{{#wrapped}}{{name}} is awesome\.{{/wrapped}}
|
|
285
307
|
.fi
|
|
286
|
-
.
|
|
287
308
|
.IP "" 0
|
|
288
|
-
.
|
|
289
309
|
.P
|
|
290
310
|
Hash:
|
|
291
|
-
.
|
|
292
311
|
.IP "" 4
|
|
293
|
-
.
|
|
294
312
|
.nf
|
|
295
|
-
|
|
296
313
|
{
|
|
297
314
|
"name": "Willy",
|
|
298
|
-
"wrapped": function() {
|
|
299
|
-
return
|
|
300
|
-
return "<b>" + render(text) + "</b>"
|
|
301
|
-
}
|
|
315
|
+
"wrapped": function(text) {
|
|
316
|
+
return "<b>" + text + "</b>"
|
|
302
317
|
}
|
|
303
318
|
}
|
|
304
|
-
.
|
|
305
319
|
.fi
|
|
306
|
-
.
|
|
307
320
|
.IP "" 0
|
|
308
|
-
.
|
|
309
321
|
.P
|
|
310
322
|
Output:
|
|
311
|
-
.
|
|
312
323
|
.IP "" 4
|
|
313
|
-
.
|
|
314
324
|
.nf
|
|
315
|
-
|
|
316
|
-
<b>Willy is awesome.</b>
|
|
317
|
-
.
|
|
325
|
+
<b>Willy is awesome\.</b>
|
|
318
326
|
.fi
|
|
319
|
-
.
|
|
320
327
|
.IP "" 0
|
|
321
|
-
.
|
|
322
328
|
.P
|
|
323
329
|
\fBNon\-False Values\fR
|
|
324
|
-
.
|
|
325
330
|
.P
|
|
326
|
-
When the value is non\-false but not a list, it will be used as the
|
|
327
|
-
context for a single rendering of the block.
|
|
328
|
-
.
|
|
331
|
+
When the value is non\-false but not a list, it will be used as the context for a single rendering of the block\.
|
|
329
332
|
.P
|
|
330
333
|
Template:
|
|
331
|
-
.
|
|
332
334
|
.IP "" 4
|
|
333
|
-
.
|
|
334
335
|
.nf
|
|
335
|
-
|
|
336
336
|
{{#person?}}
|
|
337
337
|
Hi {{name}}!
|
|
338
338
|
{{/person?}}
|
|
339
|
-
.
|
|
340
339
|
.fi
|
|
341
|
-
.
|
|
342
340
|
.IP "" 0
|
|
343
|
-
.
|
|
344
341
|
.P
|
|
345
342
|
Hash:
|
|
346
|
-
.
|
|
347
343
|
.IP "" 4
|
|
348
|
-
.
|
|
349
344
|
.nf
|
|
350
|
-
|
|
351
345
|
{
|
|
352
346
|
"person?": { "name": "Jon" }
|
|
353
347
|
}
|
|
354
|
-
.
|
|
355
348
|
.fi
|
|
356
|
-
.
|
|
357
349
|
.IP "" 0
|
|
358
|
-
.
|
|
359
350
|
.P
|
|
360
351
|
Output:
|
|
361
|
-
.
|
|
362
352
|
.IP "" 4
|
|
363
|
-
.
|
|
364
353
|
.nf
|
|
365
|
-
|
|
366
|
-
Hi Jon!
|
|
367
|
-
.
|
|
354
|
+
Hi Jon!
|
|
368
355
|
.fi
|
|
369
|
-
.
|
|
370
356
|
.IP "" 0
|
|
371
|
-
.
|
|
372
357
|
.SS "Inverted Sections"
|
|
373
|
-
An inverted section begins with a caret (hat) and ends with a
|
|
374
|
-
slash. That is \fB{{^person}}\fR begins a "person" inverted section while \fB{{/person}}\fR ends it.
|
|
375
|
-
.
|
|
358
|
+
An inverted section begins with a caret (hat) and ends with a slash\. That is \fB{{^person}}\fR begins a "person" inverted section while \fB{{/person}}\fR ends it\.
|
|
376
359
|
.P
|
|
377
|
-
While sections can be used to render text
|
|
378
|
-
value of the key, inverted sections may render text once based
|
|
379
|
-
on the inverse value of the key. That is, they will be rendered
|
|
380
|
-
if the key doesn't exist, is false, or is an empty list.
|
|
381
|
-
.
|
|
360
|
+
While sections can be used to render text zero or more times based on the value of the key, inverted sections may render text once based on the inverse value of the key\. That is, they will be rendered if the key doesn't exist, is false, or is an empty list\.
|
|
382
361
|
.P
|
|
383
362
|
Template:
|
|
384
|
-
.
|
|
385
363
|
.IP "" 4
|
|
386
|
-
.
|
|
387
364
|
.nf
|
|
388
|
-
|
|
389
365
|
{{#repo}}
|
|
390
366
|
<b>{{name}}</b>
|
|
391
367
|
{{/repo}}
|
|
392
368
|
{{^repo}}
|
|
393
369
|
No repos :(
|
|
394
370
|
{{/repo}}
|
|
395
|
-
.
|
|
396
371
|
.fi
|
|
397
|
-
.
|
|
398
372
|
.IP "" 0
|
|
399
|
-
.
|
|
400
373
|
.P
|
|
401
374
|
Hash:
|
|
402
|
-
.
|
|
403
375
|
.IP "" 4
|
|
404
|
-
.
|
|
405
376
|
.nf
|
|
406
|
-
|
|
407
377
|
{
|
|
408
378
|
"repo": []
|
|
409
379
|
}
|
|
410
|
-
.
|
|
411
380
|
.fi
|
|
412
|
-
.
|
|
413
381
|
.IP "" 0
|
|
414
|
-
.
|
|
415
382
|
.P
|
|
416
383
|
Output:
|
|
417
|
-
.
|
|
418
384
|
.IP "" 4
|
|
419
|
-
.
|
|
420
385
|
.nf
|
|
421
|
-
|
|
422
|
-
No repos :(
|
|
423
|
-
.
|
|
386
|
+
No repos :(
|
|
424
387
|
.fi
|
|
425
|
-
.
|
|
426
388
|
.IP "" 0
|
|
427
|
-
.
|
|
428
389
|
.SS "Comments"
|
|
429
|
-
Comments begin with a bang and are ignored
|
|
430
|
-
.
|
|
390
|
+
Comments begin with a bang and are ignored\. The following template:
|
|
431
391
|
.IP "" 4
|
|
432
|
-
.
|
|
433
392
|
.nf
|
|
434
|
-
|
|
435
|
-
<h1>Today{{! ignore me }}.</h1>
|
|
436
|
-
.
|
|
393
|
+
<h1>Today{{! ignore me }}\.</h1>
|
|
437
394
|
.fi
|
|
438
|
-
.
|
|
439
395
|
.IP "" 0
|
|
440
|
-
.
|
|
441
396
|
.P
|
|
442
397
|
Will render as follows:
|
|
443
|
-
.
|
|
444
398
|
.IP "" 4
|
|
445
|
-
.
|
|
446
399
|
.nf
|
|
447
|
-
|
|
448
|
-
<h1>Today.</h1>
|
|
449
|
-
.
|
|
400
|
+
<h1>Today\.</h1>
|
|
450
401
|
.fi
|
|
451
|
-
.
|
|
452
402
|
.IP "" 0
|
|
453
|
-
.
|
|
454
403
|
.P
|
|
455
|
-
Comments may contain newlines
|
|
456
|
-
.
|
|
404
|
+
Comments may contain newlines\.
|
|
457
405
|
.SS "Partials"
|
|
458
|
-
Partials begin with a greater than sign, like \fB{{> box}}\fR
|
|
459
|
-
.
|
|
406
|
+
Partials begin with a greater than sign, like \fB{{> box}}\fR\.
|
|
460
407
|
.P
|
|
461
|
-
Partials are rendered at runtime (as opposed to compile time), so
|
|
462
|
-
recursive partials are possible. Just avoid infinite loops.
|
|
463
|
-
.
|
|
408
|
+
Partials are rendered at runtime (as opposed to compile time), so recursive partials are possible\. Just avoid infinite loops\.
|
|
464
409
|
.P
|
|
465
|
-
They also inherit the calling context
|
|
466
|
-
this:
|
|
467
|
-
.
|
|
410
|
+
They also inherit the calling context\. Whereas in ERB you may have this:
|
|
468
411
|
.IP "" 4
|
|
469
|
-
.
|
|
470
412
|
.nf
|
|
471
|
-
|
|
472
413
|
<%= partial :next_more, :start => start, :size => size %>
|
|
473
|
-
.
|
|
474
414
|
.fi
|
|
475
|
-
.
|
|
476
415
|
.IP "" 0
|
|
477
|
-
.
|
|
478
416
|
.P
|
|
479
417
|
Mustache requires only this:
|
|
480
|
-
.
|
|
481
418
|
.IP "" 4
|
|
482
|
-
.
|
|
483
419
|
.nf
|
|
484
|
-
|
|
485
420
|
{{> next_more}}
|
|
486
|
-
.
|
|
487
421
|
.fi
|
|
488
|
-
.
|
|
489
422
|
.IP "" 0
|
|
490
|
-
.
|
|
491
423
|
.P
|
|
492
|
-
Why? Because the \fBnext_more
|
|
493
|
-
.
|
|
424
|
+
Why? Because the \fBnext_more\.mustache\fR file will inherit the \fBsize\fR and \fBstart\fR methods from the calling context\.
|
|
494
425
|
.P
|
|
495
|
-
In this way you may want to think of partials as includes, or template
|
|
496
|
-
expansion, even though it's not literally true.
|
|
497
|
-
.
|
|
426
|
+
In this way you may want to think of partials as includes, or template expansion, even though it's not literally true\.
|
|
498
427
|
.P
|
|
499
428
|
For example, this template and partial:
|
|
500
|
-
.
|
|
501
429
|
.IP "" 4
|
|
502
|
-
.
|
|
503
430
|
.nf
|
|
504
|
-
|
|
505
|
-
base.mustache:
|
|
431
|
+
base\.mustache:
|
|
506
432
|
<h2>Names</h2>
|
|
507
433
|
{{#names}}
|
|
508
434
|
{{> user}}
|
|
509
435
|
{{/names}}
|
|
510
436
|
|
|
511
|
-
user
|
|
437
|
+
user\.mustache:
|
|
512
438
|
<strong>{{name}}</strong>
|
|
513
|
-
.
|
|
514
439
|
.fi
|
|
515
|
-
.
|
|
516
440
|
.IP "" 0
|
|
517
|
-
.
|
|
518
441
|
.P
|
|
519
442
|
Can be thought of as a single, expanded template:
|
|
520
|
-
.
|
|
521
443
|
.IP "" 4
|
|
522
|
-
.
|
|
523
444
|
.nf
|
|
524
|
-
|
|
525
445
|
<h2>Names</h2>
|
|
526
446
|
{{#names}}
|
|
527
447
|
<strong>{{name}}</strong>
|
|
528
448
|
{{/names}}
|
|
529
|
-
.
|
|
530
449
|
.fi
|
|
531
|
-
.
|
|
532
450
|
.IP "" 0
|
|
533
|
-
.
|
|
451
|
+
.P
|
|
452
|
+
\fBDynamic Names\fR
|
|
453
|
+
.P
|
|
454
|
+
Partials can be loaded dynamically at runtime using Dynamic Names; an \fBoptional\fR part of the Mustache specification which allows to dynamically determine a tag's content at runtime\.
|
|
455
|
+
.P
|
|
456
|
+
Dynamic Names consists of an asterisk, followed by a dotted name which follows the same notation and the same resolution as in an variable tag\. That is \fB{{>*dynamic}}\fR\. It can be thought as the following \fBhypothetical\fR tag (which is \fBnot allowed\fR!): \fB{{>{{dynamic}}}}\fR\.
|
|
457
|
+
.P
|
|
458
|
+
Templates:
|
|
459
|
+
.IP "" 4
|
|
460
|
+
.nf
|
|
461
|
+
main\.mustache:
|
|
462
|
+
Hello {{>*dynamic}}
|
|
463
|
+
|
|
464
|
+
world\.template:
|
|
465
|
+
everyone!
|
|
466
|
+
.fi
|
|
467
|
+
.IP "" 0
|
|
468
|
+
.P
|
|
469
|
+
Hash:
|
|
470
|
+
.IP "" 4
|
|
471
|
+
.nf
|
|
472
|
+
{
|
|
473
|
+
"dynamic": "world"
|
|
474
|
+
}
|
|
475
|
+
.fi
|
|
476
|
+
.IP "" 0
|
|
477
|
+
.P
|
|
478
|
+
Output:
|
|
479
|
+
.IP "" 4
|
|
480
|
+
.nf
|
|
481
|
+
Hello everyone!
|
|
482
|
+
.fi
|
|
483
|
+
.IP "" 0
|
|
484
|
+
.SS "Blocks"
|
|
485
|
+
A block begins with a dollar and ends with a slash\. That is, \fB{{$title}}\fR begins a "title" block and \fB{{/title}}\fR ends it\.
|
|
486
|
+
.P
|
|
487
|
+
Blocks mark parts of the template that may be overridden\. This can be done with a block of the same name within a parent section in the calling template (see \fBParents\fR below)\. If not overridden, the contents of a block render just as if the \fB{{$title}}\fR and \fB{{/title}}\fR tags weren't there\.
|
|
488
|
+
.P
|
|
489
|
+
Blocks could be thought of as template parameters or as inline partials that may be passed to another template\. They are part of the optional inheritance extension\.
|
|
490
|
+
.P
|
|
491
|
+
Template \fBarticle\.mustache\fR:
|
|
492
|
+
.IP "" 4
|
|
493
|
+
.nf
|
|
494
|
+
<h1>{{$title}}The News of Today{{/title}}</h1>
|
|
495
|
+
{{$body}}
|
|
496
|
+
<p>Nothing special happened\.</p>
|
|
497
|
+
{{/body}}
|
|
498
|
+
.fi
|
|
499
|
+
.IP "" 0
|
|
500
|
+
.P
|
|
501
|
+
Output:
|
|
502
|
+
.IP "" 4
|
|
503
|
+
.nf
|
|
504
|
+
<h1>The News of Today</h1>
|
|
505
|
+
<p>Nothing special happened\.</p>
|
|
506
|
+
.fi
|
|
507
|
+
.IP "" 0
|
|
508
|
+
.SS "Parents"
|
|
509
|
+
A parent begins with a less than sign and ends with a slash\. That is, \fB{{<article}}\fR begins an "article" parent and \fB{{/article}}\fR ends it\.
|
|
510
|
+
.P
|
|
511
|
+
Like an \fB{{>article}}\fR partial, a parent lets you expand another template inside the current one\. Unlike a partial, a parent also lets you override blocks of the other template\.
|
|
512
|
+
.P
|
|
513
|
+
Blocks within a parent can again be overridden by another including template\. Other content within a parent is ignored, like comments\.
|
|
514
|
+
.P
|
|
515
|
+
Template:
|
|
516
|
+
.IP "" 4
|
|
517
|
+
.nf
|
|
518
|
+
{{<article}}
|
|
519
|
+
Never shown
|
|
520
|
+
{{$body}}
|
|
521
|
+
{{#headlines}}
|
|
522
|
+
<p>{{\.}}</p>
|
|
523
|
+
{{/headlines}}
|
|
524
|
+
{{/body}}
|
|
525
|
+
{{/article}}
|
|
526
|
+
|
|
527
|
+
{{<article}}
|
|
528
|
+
{{$title}}Yesterday{{/title}}
|
|
529
|
+
{{/article}}
|
|
530
|
+
.fi
|
|
531
|
+
.IP "" 0
|
|
532
|
+
.P
|
|
533
|
+
Hash:
|
|
534
|
+
.IP "" 4
|
|
535
|
+
.nf
|
|
536
|
+
{
|
|
537
|
+
"headlines": [
|
|
538
|
+
"A pug's handler grew mustaches\.",
|
|
539
|
+
"What an exciting day!"
|
|
540
|
+
]
|
|
541
|
+
}
|
|
542
|
+
.fi
|
|
543
|
+
.IP "" 0
|
|
544
|
+
.P
|
|
545
|
+
Output, assuming the \fBarticle\.mustache\fR from before:
|
|
546
|
+
.IP "" 4
|
|
547
|
+
.nf
|
|
548
|
+
<h1>The News of Today</h1>
|
|
549
|
+
<p>A pug's handler grew mustaches\.</p>
|
|
550
|
+
<p>What an exciting day!</p>
|
|
551
|
+
|
|
552
|
+
<h1>Yesterday</h1>
|
|
553
|
+
<p>Nothing special happened\.</p>
|
|
554
|
+
.fi
|
|
555
|
+
.IP "" 0
|
|
556
|
+
.P
|
|
557
|
+
\fBDynamic Names\fR
|
|
558
|
+
.P
|
|
559
|
+
Some mustache implementations may allow the use of Dynamic Names in parent tags, similar to dynamic names in partials\. Here's an example of how Dynamic Names in parent tags work\.
|
|
560
|
+
.P
|
|
561
|
+
Templates:
|
|
562
|
+
.IP "" 4
|
|
563
|
+
.nf
|
|
564
|
+
{{!normal\.mustache}}
|
|
565
|
+
{{$text}}Here goes nothing\.{{/text}}
|
|
566
|
+
|
|
567
|
+
{{!bold\.mustache}}
|
|
568
|
+
<b>{{$text}}Here also goes nothing but it's bold\.{{/text}}</b>
|
|
569
|
+
|
|
570
|
+
{{!dynamic\.mustache}}
|
|
571
|
+
{{<*dynamic}}
|
|
572
|
+
{{$text}}Hello World!{{/text}}
|
|
573
|
+
{{/*dynamic}}
|
|
574
|
+
.fi
|
|
575
|
+
.IP "" 0
|
|
576
|
+
.P
|
|
577
|
+
Hash:
|
|
578
|
+
.IP "" 4
|
|
579
|
+
.nf
|
|
580
|
+
{
|
|
581
|
+
"dynamic": "bold"
|
|
582
|
+
}
|
|
583
|
+
.fi
|
|
584
|
+
.IP "" 0
|
|
585
|
+
.P
|
|
586
|
+
Output:
|
|
587
|
+
.IP "" 4
|
|
588
|
+
.nf
|
|
589
|
+
<b>Hello World!</b>
|
|
590
|
+
.fi
|
|
591
|
+
.IP "" 0
|
|
534
592
|
.SS "Set Delimiter"
|
|
535
|
-
Set Delimiter tags start with an equal sign and change the tag
|
|
536
|
-
delimiters from \fB{{\fR and \fB}}\fR to custom strings.
|
|
537
|
-
.
|
|
593
|
+
Set Delimiter tags start with an equal sign and change the tag delimiters from \fB{{\fR and \fB}}\fR to custom strings\.
|
|
538
594
|
.P
|
|
539
595
|
Consider the following contrived example:
|
|
540
|
-
.
|
|
541
596
|
.IP "" 4
|
|
542
|
-
.
|
|
543
597
|
.nf
|
|
544
|
-
|
|
545
598
|
* {{default_tags}}
|
|
546
599
|
{{=<% %>=}}
|
|
547
600
|
* <% erb_style_tags %>
|
|
548
601
|
<%={{ }}=%>
|
|
549
602
|
* {{ default_tags_again }}
|
|
550
|
-
.
|
|
551
603
|
.fi
|
|
552
|
-
.
|
|
553
604
|
.IP "" 0
|
|
554
|
-
.
|
|
555
605
|
.P
|
|
556
|
-
Here we have a list with three items
|
|
557
|
-
tag style, the second uses erb style as defined by the Set Delimiter
|
|
558
|
-
tag, and the third returns to the default style after yet another Set
|
|
559
|
-
Delimiter declaration.
|
|
560
|
-
.
|
|
606
|
+
Here we have a list with three items\. The first item uses the default tag style, the second uses erb style as defined by the Set Delimiter tag, and the third returns to the default style after yet another Set Delimiter declaration\.
|
|
561
607
|
.P
|
|
562
|
-
According to \
|
|
563
|
-
double\-braces may occur in the text and are awkward to use for
|
|
564
|
-
markup."
|
|
565
|
-
.
|
|
608
|
+
According to ctemplates \fIhttp://goog\-ctemplate\.sourceforge\.net/doc/howto\.html\fR, this "is useful for languages like TeX, where double\-braces may occur in the text and are awkward to use for markup\."
|
|
566
609
|
.P
|
|
567
|
-
Custom delimiters may not contain whitespace or the equals sign
|
|
568
|
-
.
|
|
610
|
+
Custom delimiters may not contain whitespace or the equals sign\.
|
|
569
611
|
.SH "COPYRIGHT"
|
|
570
612
|
Mustache is Copyright (C) 2009 Chris Wanstrath
|
|
571
|
-
.
|
|
572
613
|
.P
|
|
573
614
|
Original CTemplate by Google
|
|
574
|
-
.
|
|
575
615
|
.SH "SEE ALSO"
|
|
576
|
-
mustache(1),
|
|
616
|
+
mustache(1), \fIhttp://mustache\.github\.io/\fR
|