Skip to content
Newer
Older
100644 186 lines (122 sloc) 6.9 KB
4dc441a @groue Guides/introduction.md is the documentation root: update all links
authored
1 [up](introduction.md), [next](filters.md)
fda93a5 @groue Update helpers and delegate documentation so that they better fit wit…
authored
2
3 Helpers
4 =======
5
d67b4cc @groue Guides/helpers.md refactoring + Insert Guides/localization.md in the …
authored
6 GRMustache helpers allow you to implement "Mustache lambdas", that is to say sections such as `{{#name}}...{{/name}}` that render in your own fashion.
fda93a5 @groue Update helpers and delegate documentation so that they better fit wit…
authored
7
d67b4cc @groue Guides/helpers.md refactoring + Insert Guides/localization.md in the …
authored
8
9 Overview
10 --------
fda93a5 @groue Update helpers and delegate documentation so that they better fit wit…
authored
11
12 When GRMustache renders a section `{{#name}}...{{/name}}`, it looks for the `name` key in the [context stack](runtime/context_stack.md), using the standard Key-Value Coding `valueForKey:` method. GRMustache may find a string, an [array](runtime/loops.md), a [boolean](runtime/booleans.md), whatever, or a helper. It's here a matter of attaching code, instead of regular values, to the keys of your data objects.
13
14 GRMustache recognizes a helper when it finds an object that conforms to the `GRMustacheHelper` protocol.
15
16
d67b4cc @groue Guides/helpers.md refactoring + Insert Guides/localization.md in the …
authored
17 ### GRMustacheHelper protocol
fda93a5 @groue Update helpers and delegate documentation so that they better fit wit…
authored
18
d67b4cc @groue Guides/helpers.md refactoring + Insert Guides/localization.md in the …
authored
19 This protocol is defined as:
fda93a5 @groue Update helpers and delegate documentation so that they better fit wit…
authored
20
d67b4cc @groue Guides/helpers.md refactoring + Insert Guides/localization.md in the …
authored
21 ```objc
22 @protocol GRMustacheHelper <NSObject>
23 @required
24 - (NSString *)renderSection:(GRMustacheSection *)section;
25 @end
26 ```
fda93a5 @groue Update helpers and delegate documentation so that they better fit wit…
authored
27
d67b4cc @groue Guides/helpers.md refactoring + Insert Guides/localization.md in the …
authored
28 This `renderSection:` method will be called when the helper is asked to render the section is it attached to.
fda93a5 @groue Update helpers and delegate documentation so that they better fit wit…
authored
29
d67b4cc @groue Guides/helpers.md refactoring + Insert Guides/localization.md in the …
authored
30 The protocol comes with a `GRMustacheHelper` class, which provides a convenient method for building a helper without implementing a full class that conforms to the protocol:
fda93a5 @groue Update helpers and delegate documentation so that they better fit wit…
authored
31
32 ```objc
d67b4cc @groue Guides/helpers.md refactoring + Insert Guides/localization.md in the …
authored
33 @interface GRMustacheHelper: NSObject<GRMustacheHelper>
34 + (id)helperWithBlock:(NSString *(^)(GRMustacheSection* section))block;
fda93a5 @groue Update helpers and delegate documentation so that they better fit wit…
authored
35 @end
36 ```
37
d67b4cc @groue Guides/helpers.md refactoring + Insert Guides/localization.md in the …
authored
38 Just like the `renderSection:` protocol method, the block takes a section and returns the rendering. In most cases, this is the easiest way to write a helper.
fda93a5 @groue Update helpers and delegate documentation so that they better fit wit…
authored
39
d67b4cc @groue Guides/helpers.md refactoring + Insert Guides/localization.md in the …
authored
40 The `GRMustacheSection` parameter represents the section attached to a helper. It provides the following methods:
fda93a5 @groue Update helpers and delegate documentation so that they better fit wit…
authored
41
42 ```objc
d67b4cc @groue Guides/helpers.md refactoring + Insert Guides/localization.md in the …
authored
43 @interface GRMustacheSection: NSObject
44 @property (nonatomic, readonly) NSString *innerTemplateString;
45 - (NSString *)render;
46 - (NSString *)renderTemplateString:(NSString *)string error:(NSError **)outError;
47 @end
fda93a5 @groue Update helpers and delegate documentation so that they better fit wit…
authored
48 ```
49
d67b4cc @groue Guides/helpers.md refactoring + Insert Guides/localization.md in the …
authored
50 The `innerTemplateString` property contains the *raw template string* inside the section, the `...` in `{{#lambda}}...{{/lambda}}`. In the inner template string, `{{tags}}` will not have been interpolated: you'll get the raw template string.
fda93a5 @groue Update helpers and delegate documentation so that they better fit wit…
authored
51
d67b4cc @groue Guides/helpers.md refactoring + Insert Guides/localization.md in the …
authored
52 The `render` method returns the *rendering of the inner content* of the section, just as if the helper was not here. `{{tags}}` are, this time, interpolated. This allows helper to perform "double-pass" rendering, by performing a first "classical" Mustache rendering followed by some post-processing.
fda93a5 @groue Update helpers and delegate documentation so that they better fit wit…
authored
53
d67b4cc @groue Guides/helpers.md refactoring + Insert Guides/localization.md in the …
authored
54 The `renderTemplateString:error:` returns the *rendering of an alternate content* for the section. The eventual `{{tags}}` in the alternate content are, again, interpolated. Should you provide a template string with a syntax error, the method would return nil, and sets its error argument.
fda93a5 @groue Update helpers and delegate documentation so that they better fit wit…
authored
55
d67b4cc @groue Guides/helpers.md refactoring + Insert Guides/localization.md in the …
authored
56 Let's see some examples.
fda93a5 @groue Update helpers and delegate documentation so that they better fit wit…
authored
57
58
d67b4cc @groue Guides/helpers.md refactoring + Insert Guides/localization.md in the …
authored
59 Wrapping a section's content
60 ----------------------------
fda93a5 @groue Update helpers and delegate documentation so that they better fit wit…
authored
61
d67b4cc @groue Guides/helpers.md refactoring + Insert Guides/localization.md in the …
authored
62 Let's write a helper which wraps its section:
fda93a5 @groue Update helpers and delegate documentation so that they better fit wit…
authored
63
d67b4cc @groue Guides/helpers.md refactoring + Insert Guides/localization.md in the …
authored
64 Template:
fda93a5 @groue Update helpers and delegate documentation so that they better fit wit…
authored
65
d67b4cc @groue Guides/helpers.md refactoring + Insert Guides/localization.md in the …
authored
66 {{#wrapped}}
67 {{name}} is awesome.
68 {{/wrapped}}
fda93a5 @groue Update helpers and delegate documentation so that they better fit wit…
authored
69
d67b4cc @groue Guides/helpers.md refactoring + Insert Guides/localization.md in the …
authored
70 Data:
fda93a5 @groue Update helpers and delegate documentation so that they better fit wit…
authored
71
72 ```objc
d67b4cc @groue Guides/helpers.md refactoring + Insert Guides/localization.md in the …
authored
73 id data = @{
74 @"name": @"Arthur",
75 @"wrapped": [GRMustacheHelper helperWithBlock:^(GRMustacheSection *section) {
76 NSString *rawRendering = [section render];
77 return [NSString stringWithFormat:@"<b>%@</b>", rawRendering];
78 }]};
79 ```
fda93a5 @groue Update helpers and delegate documentation so that they better fit wit…
authored
80
d67b4cc @groue Guides/helpers.md refactoring + Insert Guides/localization.md in the …
authored
81 Render:
fda93a5 @groue Update helpers and delegate documentation so that they better fit wit…
authored
82
d67b4cc @groue Guides/helpers.md refactoring + Insert Guides/localization.md in the …
authored
83 <b>Arthur is awesome.</b>
fda93a5 @groue Update helpers and delegate documentation so that they better fit wit…
authored
84
d67b4cc @groue Guides/helpers.md refactoring + Insert Guides/localization.md in the …
authored
85 ```objc
86 NSString *rendering = [template renderObject:data];
87 ```
fda93a5 @groue Update helpers and delegate documentation so that they better fit wit…
authored
88
d67b4cc @groue Guides/helpers.md refactoring + Insert Guides/localization.md in the …
authored
89 This wrapper helper performs a *double-pass rendering*: The `[section render]` would return the rendering of the inner content, that is to say, `Arthur is awesome.`.
fda93a5 @groue Update helpers and delegate documentation so that they better fit wit…
authored
90
d67b4cc @groue Guides/helpers.md refactoring + Insert Guides/localization.md in the …
authored
91 The helper then returns this raw rendering wrapped inside a HTML `<b>` tag, which enters the final rendering.
fda93a5 @groue Update helpers and delegate documentation so that they better fit wit…
authored
92
93
d67b4cc @groue Guides/helpers.md refactoring + Insert Guides/localization.md in the …
authored
94 Rendering an alternate template string
95 --------------------------------------
fda93a5 @groue Update helpers and delegate documentation so that they better fit wit…
authored
96
d67b4cc @groue Guides/helpers.md refactoring + Insert Guides/localization.md in the …
authored
97 For the purpose of demonstration, we'll implement a helper that turns a portion of a template into a HTML link.
fda93a5 @groue Update helpers and delegate documentation so that they better fit wit…
authored
98
d67b4cc @groue Guides/helpers.md refactoring + Insert Guides/localization.md in the …
authored
99 Template:
100
101 {{#movie}}
102 {{#link}}{{title}}{{/link}}
103 {{#director}}
104 by {{#link}}{{firstName}} {{lastName}}{{/link}}
105 {{/director}}
106 {{/movie}}
fda93a5 @groue Update helpers and delegate documentation so that they better fit wit…
authored
107
d67b4cc @groue Guides/helpers.md refactoring + Insert Guides/localization.md in the …
authored
108 Data:
fda93a5 @groue Update helpers and delegate documentation so that they better fit wit…
authored
109 ```objc
d67b4cc @groue Guides/helpers.md refactoring + Insert Guides/localization.md in the …
authored
110 id data = @{
111 @"movie": @{
112 @"url": @"/movies/123",
113 @title: @"Citizen Kane",
114 @director: @{
115 @"url": @"/people/321",
116 @"firstName": @"Orson",
117 @"lastName": @"Welles",
118 }
119 },
120 @"link": [GRMustacheHelper helperWithBlock:^(GRMustacheSection *section) {
121 NSString *format = @"<a href=\"{{url}}\">%@</a>";
122 NSString *templateString = [NSString stringWithFormat:format, section.innerTemplateString];
123 return [section renderTemplateString:templateString error:NULL];
124 }]
125 }
fda93a5 @groue Update helpers and delegate documentation so that they better fit wit…
authored
126 ```
127
d67b4cc @groue Guides/helpers.md refactoring + Insert Guides/localization.md in the …
authored
128 Render:
129
130 <a href="/movies/123">Citizen Kane</a>
131 by <a href="/people/321">Orson Welles</a>
fda93a5 @groue Update helpers and delegate documentation so that they better fit wit…
authored
132
133 ```objc
d67b4cc @groue Guides/helpers.md refactoring + Insert Guides/localization.md in the …
authored
134 NSString *rendering = [template renderObject:data];
fda93a5 @groue Update helpers and delegate documentation so that they better fit wit…
authored
135 ```
136
d67b4cc @groue Guides/helpers.md refactoring + Insert Guides/localization.md in the …
authored
137 This helper again performs a *double-pass rendering*:
fda93a5 @groue Update helpers and delegate documentation so that they better fit wit…
authored
138
d67b4cc @groue Guides/helpers.md refactoring + Insert Guides/localization.md in the …
authored
139 It first wraps the inner template string (`{{title}}`, or `{{firstName}} {{lastName}}`) inside a HTML link, whose url is *also expressed* as a Mustache tag. This gives the two alternate template strings: `<a href="{{url}}">{{title}}</a>` and `<a href="{{url}}">{{firstName}} {{lastName}}</a>`.
fda93a5 @groue Update helpers and delegate documentation so that they better fit wit…
authored
140
d67b4cc @groue Guides/helpers.md refactoring + Insert Guides/localization.md in the …
authored
141 Since both movie and director data objects contain values for the `url` key, the renderings of those alternate template string embed the URL of Citizen Kane and of its director.
fda93a5 @groue Update helpers and delegate documentation so that they better fit wit…
authored
142
143
d67b4cc @groue Guides/helpers.md refactoring + Insert Guides/localization.md in the …
authored
144 Providing helpers aside
145 -----------------------
fda93a5 @groue Update helpers and delegate documentation so that they better fit wit…
authored
146
d67b4cc @groue Guides/helpers.md refactoring + Insert Guides/localization.md in the …
authored
147 All the examples above use an ad-hoc NSDictionary for filling the template. This dictionary contains both values and helpers.
fda93a5 @groue Update helpers and delegate documentation so that they better fit wit…
authored
148
d67b4cc @groue Guides/helpers.md refactoring + Insert Guides/localization.md in the …
authored
149 However, generally, your data will not come from dictionaries, but from your *model objects*. And you don't want to pollute them with Mustache helpers:
fda93a5 @groue Update helpers and delegate documentation so that they better fit wit…
authored
150
d67b4cc @groue Guides/helpers.md refactoring + Insert Guides/localization.md in the …
authored
151 ```objc
152 Movie *movie = ...;
fda93a5 @groue Update helpers and delegate documentation so that they better fit wit…
authored
153
d67b4cc @groue Guides/helpers.md refactoring + Insert Guides/localization.md in the …
authored
154 // How to provide the `link` helper?
155 NSString *rendering = [template renderObject:movie];
156 ```
157
158 The solution is the `renderObjectsInArray:` method of GRMustacheTemplate. Simply provide an array filled with you helper, and your model object:
fda93a5 @groue Update helpers and delegate documentation so that they better fit wit…
authored
159
160 ```objc
d67b4cc @groue Guides/helpers.md refactoring + Insert Guides/localization.md in the …
authored
161 Movie *movie = ...;
162 id helpers = @{ @"link": [GRMustacheHelper ...] };
163 NSString *rendering = [template renderObjectsInArray:@[helpers, movie]];
fda93a5 @groue Update helpers and delegate documentation so that they better fit wit…
authored
164 ```
165
166
d67b4cc @groue Guides/helpers.md refactoring + Insert Guides/localization.md in the …
authored
167 GRMustache helpers vs. Mustache lambdas
168 ---------------------------------------
fda93a5 @groue Update helpers and delegate documentation so that they better fit wit…
authored
169
170 **Warning: If your goal is to design GRMustache helpers that remain compatible with Mustache lambdas of [other Mustache implementations](https://github.com/defunkt/mustache/wiki/Other-Mustache-implementations), read the following with great care.**
171
172 The strings returned by GRMustache helpers are directly inserted in the final rendering, without any further processing.
173
174 However, the specification [states](https://github.com/mustache/spec/blob/v1.1.2/specs/%7Elambdas.yml#L90) that "Lambdas used for sections should have their results parsed" (read, processed as a Mustache template, and rendered in the current context).
175
d67b4cc @groue Guides/helpers.md refactoring + Insert Guides/localization.md in the …
authored
176 In order to comply with the genuine Mustache behavior, a helper must return the result of the `renderTemplateString:` method of the section, as the linking helper seen above.
177
178
179 Sample code
180 -----------
181
182 The [localization.md](sample_code/localization.md) sample code uses helpers for localizing portions of template.
fda93a5 @groue Update helpers and delegate documentation so that they better fit wit…
authored
183
184
4dc441a @groue Guides/introduction.md is the documentation root: update all links
authored
185 [up](introduction.md), [next](filters.md)
Something went wrong with that request. Please try again.