UNPKG

12.5 kBMarkdownView Raw
1
2Templates
3=========
4
5View templates in Shunter are written in [Dust](http://www.dustjs.com/) and live in the `view` folder by default.
6
7- [Specifying a Template](#specifying-a-template)
8- [Dust Basics](#dust-basics)
9- [Using partials](#using-partials)
10- [Using layouts](#using-layouts)
11- [Built-In Dust Extensions](#built-in-dust-extensions)
12- [Writing Dust Extensions](#writing-dust-extensions)
13
14
15Specifying a Template
16---------------------
17
18When a JSON response is received from the back end with the (configured trigger header)[configuration-reference.md#trigger-parameter] (default: `Content-Type: application/x-shunter+json`), Shunter will look for a `layout.template` property and attempt to render the matching Dust file. So with the following JSON:
19
20```json
21{
22 "layout": {
23 "template": "foo"
24 }
25}
26```
27
28Shunter will attempt to render the file `view/foo.dust`. This allows your back end application to decide which template to render for a given page.
29
30Templates cannot contain "/" characters in Shunter, instead if you need to reference a template in a subdirectory you should use double underscores. So with the following JSON:
31
32```json
33{
34 "layout": {
35 "template": "foo__bar"
36 }
37}
38```
39
40Shunter will attempt to render the file `view/foo/bar.dust`.
41
42If a JSON response is received without the (configured trigger header)[configuration-reference.md#trigger-parameter] then Shunter will simply pass it through unmodified as it would any other resource.
43
44
45Dust Basics
46-----------
47
48Dust has all of the features you'd expect from a good templating language. We'll cover some basics here, but you should read the [Dust documentation](http://www.dustjs.com/) for more information.
49
50### References
51
52You can output properties from the back end JSON simply by surrounding the property name in curly braces. So with the following JSON and Dust template:
53
54```json
55{
56 "thing": "World"
57}
58```
59
60```html
61<p>Hello {thing}!</p>
62```
63
64Dust will render:
65
66```html
67<p>Hello World!</p>
68```
69
70### Conditionals
71
72You can conditionally output HTML based on the values of JSON properties. So with the following JSON and Dust template:
73
74```json
75{
76 "show_html": true
77}
78```
79
80```html
81{?show_html}
82 <p>Hello World!</p>
83{/show_html}
84```
85
86Dust will render:
87
88```html
89<p>Hello World!</p>
90```
91
92### Loops
93
94You can loop over arrays in the JSON with Dust and generate output for each item in the array. So with the following JSON and Dust template:
95
96```json
97{
98 "list": [
99 "foo",
100 "bar",
101 "baz"
102 ]
103}
104```
105
106```html
107<ul>
108 {#list}
109 <li>{.}</li>
110 {/list}
111</ul>
112```
113
114Dust will render:
115
116```html
117<ul>
118 <li>foo</li>
119 <li>bar</li>
120 <li>baz</li>
121</ul>
122```
123
124For more information on Dust, refer to the [Dust getting started documentation](http://www.dustjs.com/guides/getting-started/).
125
126
127Using Partials
128--------------
129
130Partials in Dust allow you to insert other Dust files into your template to create a page. This encourages code reuse, and smaller more maintainable templates.
131
132Partials are subject to the same naming rules as templates when they're references in Dust files. You'll need to replace slashes with double underscores in order for Shunter to find them.
133
134So with the following Dust templates:
135
136```html
137<!-- view/foo/bar.dust -->
138Hello World!
139```
140
141```html
142<!-- view/foo.dust -->
143<p>{>foo__bar/}</p>
144```
145
146When `view/foo.dust` is rendered, it will produce the following output:
147
148```html
149<p>Hello World!</p>
150```
151
152Partials can also be referenced by using JSON properties. This is very powerful if you'd like your back end to have more control over the presentation. So with the following JSON and Dust template:
153
154```json
155{
156 "foo": "bar"
157}
158```
159
160```html
161{>"{foo}"/}
162```
163
164The `view/bar.dust` partial will be rendered.
165
166For more information on partials in Dust partials, refer to the [Dust Partials documentation](http://www.dustjs.com/guides/partials/).
167
168
169Using Layouts
170-------------
171
172There are several ways to implement layouts in Shunter, either by allowing your JSON to configure them or by using Dust's built-in Blocks.
173
174### Layouts In JSON
175
176Because partials can be referenced using JSON properties, you could create layouts by using a single `layout` view and injecting a second template into the body of it.
177
178For example, given the following JSON and Dust templates:
179
180```json
181{
182 "layout": {
183 "template": "layout",
184 "page_template": "home"
185 },
186 "title": "Hello World!"
187}
188```
189
190```html
191<!-- view/layout.dust -->
192<!DOCTYPE html>
193<html lang="en">
194<head>
195 <title>{title}</title>
196</head>
197<body>
198 {>"{layout.page_template}"/}
199</body>
200</html>
201```
202
203```html
204<!-- view/home.dust -->
205<p>This is the home page!</p>
206```
207
208Dust will combine the templates and render:
209
210```html
211<!DOCTYPE html>
212<html lang="en">
213<head>
214 <title>Hello World!</title>
215</head>
216<body>
217 <p>This is the home page!</p>
218</body>
219</html>
220```
221
222### Layouts With Dust Blocks
223
224Dust has a feature called [Blocks and Inline Partials](http://www.dustjs.com/guides/blocks/) which is very powerful. It allows you to create templates which extend each other, and inject content into templates further up the chain.
225
226We can utilise this for layouts quite easily, and without any need to add extra layout properties to the JSON.
227
228For example, given the following JSON and Dust templates:
229
230```json
231{
232 "layout": {
233 "template": "home"
234 },
235 "title": "Hello World!"
236}
237```
238
239```html
240<!-- view/layout.dust -->
241<!DOCTYPE html>
242<html lang="en">
243<head>
244 <title>{title}</title>
245</head>
246<body>
247 {+bodyContent/}
248</body>
249</html>
250```
251
252```html
253<!-- view/home.dust -->
254{>"layout"/}
255
256{<bodyContent}
257 <p>This is the home page!</p>
258{/bodyContent}
259```
260
261Dust will combine the templates and render:
262
263```html
264<!DOCTYPE html>
265<html lang="en">
266<head>
267 <title>Hello World!</title>
268</head>
269<body>
270 <p>This is the home page!</p>
271</body>
272</html>
273```
274
275
276Built-In Dust Extensions
277------------------------
278
279For when basic logic isn't enough, you can use helpers and filters to extend Dust. Although templates should ideally contain as little logic as possible, sometimes you can't get away from it.
280
281Dust helpers can run on a block of HTML:
282
283```html
284{@helper}HTML to run the helper on{/helper}
285```
286
287Or by themselves to output content:
288
289```html
290{@helper/}
291```
292
293They are also configurable with parameters:
294
295```html
296{@helper param="value"/}
297```
298
299Filters are different – they operate on existing values:
300
301```html
302{myProperty|filter}
303```
304
305Filters are chainable:
306
307```html
308{myProperty|filter1|filter2}
309```
310
311Shunter includes the full set of [officially supported Dust helpers](http://www.dustjs.com/guides/dust-helpers/). These add a lot of power to the language.
312
313As well as including the official helpers and filters, Shunter comes bundled with some additional ones:
314
315### The `assetPath` Helper
316
317The `assetPath` helper is used to output the correct paths to MD5-fingerprinted assets. It's required for your application to run in production.
318
319`assetPath` accepts a `src` parameter which should be set to the non-fingerprinted path:
320
321```html
322<link rel="stylesheet" href="{@assetPath src="main.css"/}"/>
323```
324
325### The `and` Helper
326
327The `and` helper is used to check whether several properties are all truthy. It accepts a `keys` parameter which should be a pipe-separated list of properties to check. If all of them are truthy, the helper block will be output:
328
329```html
330{@and keys="foo|bar"}
331 Output if `foo` and `bar` are both truthy
332{/and}
333```
334
335The `and` helper supports an `{:else}` block:
336
337```html
338{@and keys="foo|bar"}
339 Output if `foo` and `bar` are both truthy
340{:else}
341 Output if either `foo` or `bar` are falsy
342{/and}
343```
344
345Also if the `not` parameter is `true`, the behaviour of the helper is inverted:
346
347```html
348{@and keys="foo|bar" not=true}
349 Output if `foo` and `bar` are both falsy
350{/and}
351```
352
353### The `or` Helper
354
355The `or` helper is used to check whether one of the given properties are truthy. It accepts a `keys` parameter which should be a pipe-separated list of properties to check. If at least one of them is truthy, the helper block will be output:
356
357```html
358{@or keys="foo|bar"}
359 Output if either `foo` or `bar` are truthy
360{/or}
361```
362
363The `or` helper supports an `{:else}` block:
364
365```html
366{@or keys="foo|bar"}
367 Output if either `foo` or `bar` are truthy
368{:else}
369 Output if `foo` and `bar` are both falsy
370{/or}
371```
372
373Also if the `not` parameter is `true`, the `or` helper will render the block if at least one of the properties is _falsy_:
374
375```html
376{@or keys="foo|bar" not=true}
377 Output if either `foo` or `bar` are falsy
378{/or}
379```
380
381### The `dateFormat` Helper
382
383The `dateFormat` helper is used to format dates. It accepts two parameters: `date` and `format`. The `date` parameter expects a date string, and the `format` should be a formatting string supported by the [node-dateformat library](https://github.com/felixge/node-dateformat):
384
385```html
386{@dateFormat date="2015-09-14" format="dd mmmm yyyy"/}
387<!-- Outputs: "14 September 2015" -->
388```
389
390### The `numberFormat` Helper
391
392The `numberFormat` helper is used to format numbers. It accepts a single parameter (`num`) and outputs the given number with thousands seperators:
393
394```html
395{@numberFormat num="1000000"/}
396<!-- Outputs: "1,000,000" -->
397```
398
399### The `lower` Filter
400
401The `lower` filter takes a property and lowercases the value. If `foo` is `Hello World`:
402
403```html
404{foo|lower}
405<!-- Outputs: "hello world" -->
406```
407
408### The `upper` Filter
409
410The `upper` filter takes a property and uppercases the value. If `foo` is `Hello World`:
411
412```html
413{foo|upper}
414<!-- Outputs: "HELLO WORLD" -->
415```
416
417### The `title` Filter
418
419The `title` filter takes a property and titlecases the value. If `foo` is `hello world`:
420
421```html
422{foo|title}
423<!-- Outputs: "Hello World" -->
424```
425
426### The `trim` Filter
427
428The `trim` filter takes a property and strips leading and trailing whitespace from the value. If `foo` is `\r\n \thello world\n`:
429
430```html
431{foo|trim}
432<!-- Outputs: "hello world" -->
433```
434
435### The `amp` Filter
436
437The `amp` filter replaces ampersands in a property with HTML entities, but ignores ampersands that are the opening for an existing entity. If `foo` is `Hello World & Everyone&hellip;`:
438
439```html
440{foo|amp}
441<!-- Outputs: "Hello World &amp; Everyone&hellip;" -->
442```
443
444Note that the `&hellip;` has not been touched.
445
446### The `stripTags` Filter
447
448The `stripTags` filter strips HTML open/close tags from a string. If `foo` is `<p>Hello <i>World</i></p>`:
449
450```html
451{foo|stripTags}
452<!-- Outputs: "Hello World" -->
453```
454
455### The `html` Filter
456
457The `html` filter encodes HTML special characters `<>&"'` as HTML entities. It will also ignore ampersands that are the opening for an existing entity, in the same way as the `amp` filter. If `foo` is `Hello <i>World</i> & "Everyone"`:
458
459```html
460{foo|html}
461<!-- Outputs: "Hello &#60;i&#62;World&#60;/i&#62; &amp; &#34;Everyone&#34;" -->
462```
463
464
465Writing Dust Extensions
466-----------------------
467
468It's also possible to write your own Dust helpers and filters to use in your Shunter application. Dust extensions live in the `dust` directory of your application and must export a single function:
469
470```js
471module.exports = function(dust) {
472 // `dust.helpers` = an object to add helpers to
473 // `dust.filters` = an object to add filters to
474};
475```
476
477An example helper might look like the following, which outputs the current year:
478
479```js
480// <app>/dust/current-year.js
481module.exports = function(dust) {
482 dust.helpers.currentYear = function(chunk) {
483 var date = new Date();
484 return chunk.write(date.getFullYear());
485 };
486};
487```
488
489An example filter might look like the following, which reverses a string and outputs it:
490
491```js
492// <app>/dust/reverse.js
493module.exports = function(dust) {
494 dust.filters.reverse = function(value) {
495 return value.split('').reverse().join('');
496 };
497};
498```
499
500Dust helpers and filters can also access the Shunter renderer and config objects by accepting more arguments in the exported function:
501
502```js
503module.exports = function(dust, renderer, config) {
504 // `renderer` = the Shunter renderer object
505 // `config` = the Shunter application configuration
506};
507```
508
509Dust has excellent documentation on how to write both [helpers](http://www.dustjs.com/docs/helper-api/) and [filters](http://www.dustjs.com/docs/filter-api/). You should follow these guides if you want to learn how to write helpers that leverage parameters and blocks.
510
511
512---
513
514Related:
515
516- [Full API Documentation](index.md)