PageRenderTime 28ms CodeModel.GetById 11ms app.highlight 14ms RepoModel.GetById 2ms app.codeStats 0ms

/scalate-website/src/documentation/_mustache.md

http://github.com/scalate/scalate
Markdown | 287 lines | 192 code | 95 blank | 0 comment | 0 complexity | 9ba2aa8cb99aa22a03c888acd53028a9 MD5 | raw file
  1# Mustache
  2
  3* Table of contents
  4{:toc}
  5
  6## Introduction
  7
  8Scalate's Mustache is a Scala/Java implementation of the [Mustache](http://mustache.github.com/) template language.
  9
 10Mustache provides logic-less templates which also work inside the browser using [mustache.js](http://github.com/janl/mustache.js) - so ideal for HTML templates which your designers own. 
 11
 12You can use a regular HTML file as the template and let your designer own it, using a little JavaScript file inject the template with sample data. Your Scala/Java developer can then use the template and inject the values on the server side using the real services and domain model.
 13
 14A typical Mustache template:
 15
 16{pygmentize:: text}
 17Hello {{name}} 
 18You have just won ${{value}}!
 19{{#in_ca}}
 20Well, ${{taxed_value}}, after taxes.
 21{{/in_ca}}
 22{pygmentize}
 23
 24Given the following attributes:
 25
 26{pygmentize:: scala}
 27Map(
 28  "name" -> "Chris",
 29  "value" -> 10000,
 30  "taxed_value" -> 10000 - (10000 * 0.4),
 31  "in_ca" -> true
 32  )
 33{pygmentize}
 34
 35Will produce the following:
 36
 37{pygmentize:: text}
 38Hello Chris
 39You have just won $10000!
 40Well, $6000.0, after taxes.
 41{pygmentize}
 42
 43## Syntax
 44
 45Mustache works using tags which are surrounded by mustaches **{{someTag}}**. There are various kinds of tag
 46
 47### Variables
 48
 49The most basic tag type is the variable. A **{{name}}** tag just tries to lookup *name* in the current context and if there is no name then nothing is rendered.
 50
 51All values are HTML escaped by default. If you want to return unescaped HTML use the triple mustache **{{{name}}}**. Or you can use **{{& name}}**
 52
 53You can customize how a null value or empty string is rendered by configuring properties on [RenderContext](http://scalate.fusesource.org/maven/${project_version}/scalate-core/scaladocs/org/fusesource/scalate/RenderContext.html) such as **nullString** or **noneString**
 54
 55### Sections
 56
 57Sections render blocks of text one or more times, depending on the value of the key in the current context.
 58
 59A section begins with **{{\#foo}}** and ends with **{{/foo}}**. The behavior of the section is defined by the value of the key.
 60
 61#### Empty Lists, false or None
 62
 63If a key exists and is false, None or an empty collection then the section will not render anything. 
 64
 65Template:
 66
 67{pygmentize:: text}
 68Shown.
 69{{#nothin}}
 70  Never shown!
 71{{/nothin}}
 72{pygmentize}
 73
 74Given the following attributes:
 75
 76{pygmentize:: scala}
 77Map("person" -> true)
 78{pygmentize}
 79
 80Will produce the following:
 81
 82{pygmentize:: text}
 83Shown.
 84{pygmentize}
 85
 86#### Non Empty Lists
 87
 88If the value is a non-empty list the section will be displayed multiple times. In each case the context of the section will be set to the item in the list.
 89
 90Template:
 91
 92{pygmentize:: text}
 93{{#repo}}
 94  <b>{{name}}</b>
 95{{/repo}}
 96{pygmentize}
 97
 98Given the following attributes:
 99
100{pygmentize:: scala}
101Map(
102  "repo" -> List(
103    Map("name" -> "resque"),
104    Map("name" -> "hub"),
105    Map("name" -> "rip")
106  )
107)
108{pygmentize}
109
110Will produce the following:
111
112{pygmentize:: text}
113<b>resque</b>
114<b>hub</b>
115<b>rip</b>
116{pygmentize}
117
118#### Functions
119
120When the value is a function which takes a String parameter then it will be invoked with the text of the section.
121
122{pygmentize:: text}
123{{#wrapped}}
124  {{name}} is awesome.
125{{/wrapped}}
126{pygmentize}
127
128Given the following attributes:
129
130{pygmentize:: scala}
131Map(
132  "name" -> "Willy"
133  "wrapped" -> ((text: String) => <b>{text}</b>)
134)
135{pygmentize}
136
137Will produce the following:
138
139{pygmentize:: text}
140<b>Willy is awesome.</b>
141{pygmentize}
142
143
144#### Non False Values
145
146When the value is not false, None or a collection it will be used as the context for a single rendering of the block
147
148{pygmentize:: text}
149{{#person?}}
150  Hi {{name}}!
151{{/person?}}
152{pygmentize}
153
154Given the following attributes:
155
156{pygmentize:: scala}
157Map(
158  "person?" -> Map("name" -> "Jon")
159)
160{pygmentize}
161
162Will produce the following:
163
164{pygmentize:: text}
165Hi Jon!
166{pygmentize}
167
168
169### Inverted Sections
170
171An inverted section begins with a caret (hat) and ends with a slash. That is **{{^person}}** begins a "person" inverted section while **{{/person}}** ends it.
172
173While sections can be used to render text one 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.
174
175{pygmentize:: text}
176{{#repo}}
177  <b>{{name}}</b>
178{{/repo}}
179{{^repo}}
180  No repos :(
181{{/repo}}
182{pygmentize}
183
184Given the following attributes:
185
186{pygmentize:: scala}
187Map(
188  "repo" -> 
189)
190{pygmentize}
191
192Will produce the following:
193
194{pygmentize:: text}
195No repos :(
196{pygmentize}
197
198### Comments
199
200Comments begin with a bang and are ignored. The following template:
201
202{pygmentize:: text}
203<h1>Today{{! ignore me }}.</h1>
204{pygmentize}
205
206Will produce the following:
207
208{pygmentize:: text}
209<h1>Today.</h1>
210{pygmentize}
211
212Comments may contain newlines.
213
214### Partials
215
216Partials begin with a greater than sign, like **{{> box}}**.
217
218Partials are rendered at runtime (as opposed to compile time), so recursive partials are possible. Just avoid infinite loops.
219
220They also inherit the calling context so you don't have to pass in state.
221
222In this way you may want to think of partials as includes, or template expansion, even though it's not literally true.
223
224For example, this template and partial:
225
226base.mustache:
227
228{pygmentize:: text}
229<h2>Names</h2>
230{{#names}}
231  {{> user}}
232{{/names}}
233{pygmentize}
234
235user.mustache:
236
237{pygmentize:: text}
238<strong>{{name}}</strong>
239{pygmentize}
240
241Can be thought of as a single, expanded template:
242
243{pygmentize:: text}
244<h2>Names</h2>
245{{#names}}
246  <strong>{{name}}</strong>
247{{/names}}
248{pygmentize}
249
250### Set Delimiter
251
252Set Delimiter tags start with an equal sign and change the tag delimiters from {{ and }} to custom strings.
253
254Consider the following contrived example:
255
256{pygmentize:: text}
257* {{default_tags}}
258{{=<% %>=}}
259* <% erb_style_tags %>
260<%={{ }}=%>
261* {{ default_tags_again }}
262{pygmentize}
263
264Here 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.
265
266According to ctemplates, this "is useful for languages like TeX, where double-braces may occur in the text and are awkward to use for markup."
267
268Custom delimiters may not contain whitespace or the equals sign.
269
270## Layouts
271
272The way the layouts work with the other template languages in Scalate is you define attributes inside the templates which are then passed into the layout template as template attributes. However Mustache has no 'set attribute' syntax since its a 'no logic in the template' style.
273
274The Mustache approach is inside a layout template we can use the **{{#html}}** section to navigate the HTML of the template output.
275
276For example this template [sample.mustache](https://github.com/scalate/scalate/blob/master/scalate-core/src/test/resources/org/fusesource/scalate/mustache/sample.mustache) we could apply this layout [mylayout.mustache](https://github.com/scalate/scalate/blob/master/scalate-core/src/test/resources/org/fusesource/scalate/mustache/mylayout.mustache) to generate [this output](https://github.com/scalate/scalate/blob/master/scalate-core/src/test/scala/org/fusesource/scalate/mustache/LayoutTest.scala#L30)
277
278Inside the **{{#html}}** section we can then pull out child elements by name.  So inside the **{{#head}}** section you can refer to **{{title}}** and you'll get the entire &lt;title&gt; element (attributes and all). 
279
280If you want just the children an element, create a section for it and use **{{_}}** (e.g. the way we exclude the &lt;body&gt; element in the layout but just use all the children). Names starting with @ refer to attributes. (This is using the **\** method on [NodeSeq](http://www.scala-lang.org/api/rc/scala/xml/NodeSeq.html) underneath).
281
282
283
284## Other Resources
285
286* [Mustache reference](http://mustache.github.com/mustache.5.html)
287* [Other Mustache implementations](http://mustache.github.com/)