Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 199 lines (145 sloc) 7.01 kb
2e61bf9 @groue Fix internal guide links
authored
1 [up](../../../../tree/master/Guides/sample_code), [next](indexes.md)
18da0ef @groue Number formatting sample code
authored
2
3 Number formatting
4 =================
5
a68a579 @groue Rewritten number formatting guide, so that it uses filters.
authored
6 For the purpose of demonstration, we'll see various ways to have GRMustache render a numeric value formatted in different ways.
7
8 We'll render the value 0.5 as a *raw* number, as a percentage, and as a *decimal*. For instance, on a French system, we'll get the following output:
9
10 raw: 0.5
11 percent: 50 %
12 decimal: 0,5
13
14
18da0ef @groue Number formatting sample code
authored
15 In a genuine Mustache way
16 -------------------------
17
18 Mustache is a simple template language. This is why there are so many [other Mustache implementations](https://github.com/defunkt/mustache/wiki/Other-Mustache-implementations).
19
20 If your goal is to design your templates so that they are compatible with those, the best way to format numbers is to have your data objects provide those formatted numbers.
21
a68a579 @groue Rewritten number formatting guide, so that it uses filters.
authored
22 ### 1st technique: NSDictionary
18da0ef @groue Number formatting sample code
authored
23
24 Let's render the simple template:
25
a68a579 @groue Rewritten number formatting guide, so that it uses filters.
authored
26 raw: {{ value }}
27 percent: {{ percent }}
28 decimal: {{ decimal }}
18da0ef @groue Number formatting sample code
authored
29
a68a579 @groue Rewritten number formatting guide, so that it uses filters.
authored
30 It's quite easy to put numbers and formatted numbers in a dictionary:
18da0ef @groue Number formatting sample code
authored
31
32 ```objc
fae0cef @groue Rewritten number formatting guide, so that it uses filters.
authored
33 // The raw number
a68a579 @groue Rewritten number formatting guide, so that it uses filters.
authored
34 NSNumber *value = [NSNumber numberWithFloat: 0.5]:
18da0ef @groue Number formatting sample code
authored
35
fae0cef @groue Rewritten number formatting guide, so that it uses filters.
authored
36 // NSNumberFormatter objects knows how to format numbers
18da0ef @groue Number formatting sample code
authored
37 NSNumberFormatter *percentNumberFormatter = [[NSNumberFormatter alloc] init];
38 percentNumberFormatter.numberStyle = kCFNumberFormatterPercentStyle;
a68a579 @groue Rewritten number formatting guide, so that it uses filters.
authored
39 NSString *percent = [numberFormatter stringFromNumber:value];
40
41 NSNumberFormatter *decimalNumberFormatter = [[NSNumberFormatter alloc] init];
42 decimalNumberFormatter.numberStyle = kCFNumberFormatterDecimalStyle;
43 NSString *decimal = [numberFormatter stringFromNumber:value];
18da0ef @groue Number formatting sample code
authored
44
f5f8e18 @groue Rewritten number formatting guide, so that it uses filters.
authored
45 // Render "raw: 0.5, percent: 50 %, decimal: 0,5"
a68a579 @groue Rewritten number formatting guide, so that it uses filters.
authored
46 NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:
47 value, @"value",
48 percent, @"percent",
49 decimal, @"decimal",
50 nil];
18da0ef @groue Number formatting sample code
authored
51 NSString *rendering = [template renderObject:dictionary];
52 ```
53
a68a579 @groue Rewritten number formatting guide, so that it uses filters.
authored
54 ### 2nd technique: GRMustache-targetted properties
18da0ef @groue Number formatting sample code
authored
55
35162b7 @groue Hard wrap documentation to 80 columns
authored
56 Often, data comes from your model objects, not from a hand-crafted NSDictionary.
18da0ef @groue Number formatting sample code
authored
57
a68a579 @groue Rewritten number formatting guide, so that it uses filters.
authored
58 In this case, the best option is to declare a category on your model object, and implement specific keys that will output the formatted numbers:
18da0ef @groue Number formatting sample code
authored
59
60 ```objc
a68a579 @groue Rewritten number formatting guide, so that it uses filters.
authored
61 @interface Model
62 @property float value; // the original property provided by the model
63 @end
64
65 @interface Model(GRMustache)
18da0ef @groue Number formatting sample code
authored
66 @property (readonly) NSString *percent;
a68a579 @groue Rewritten number formatting guide, so that it uses filters.
authored
67 @property (readonly) NSString *decimal;
18da0ef @groue Number formatting sample code
authored
68 @end
69
a68a579 @groue Rewritten number formatting guide, so that it uses filters.
authored
70 @implementation Model(GRMustache)
18da0ef @groue Number formatting sample code
authored
71 - (NSString *)percent
72 {
a68a579 @groue Rewritten number formatting guide, so that it uses filters.
authored
73 NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
74 numberFormatter.numberStyle = kCFNumberFormatterPercentStyle;
75 return [numberFormatter stringFromNumber:[NSNumber numberWithFloat:self.value]];
76 }
77
78 - (NSString *)decimal
79 {
80 NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
81 numberFormatter.numberStyle = kCFNumberFormatterDecimalStyle;
82 return [numberFormatter stringFromNumber:[NSNumber numberWithFloat:self.value]];
18da0ef @groue Number formatting sample code
authored
83 }
84 @end
85 ```
86
87 You would then render normally:
88
89 ```objc
f5f8e18 @groue Rewritten number formatting guide, so that it uses filters.
authored
90 // Render "raw: 0.5, percent: 50 %, decimal: 0,5"
a68a579 @groue Rewritten number formatting guide, so that it uses filters.
authored
91 Model *model = ...
92 model.value = 0.5;
18da0ef @groue Number formatting sample code
authored
93 NSString *rendering = [template renderObject:model];
94 ```
95
a68a579 @groue Rewritten number formatting guide, so that it uses filters.
authored
96 GRMustache filters
97 ------------------
18da0ef @groue Number formatting sample code
authored
98
c1aaf13 @groue More links from guides to sample projects
authored
99 **[Download the code](../../../../tree/master/Guides/sample_code/number_formatting)**
3f50ab0 @groue Links to sample code projects hosted at https://github.com/groue/GRMu…
authored
100
18da0ef @groue Number formatting sample code
authored
101 You may ask yourself, is it worth declaring dozens of stub properties just for formatting numbers?
102
a68a579 @groue Rewritten number formatting guide, so that it uses filters.
authored
103 [Filters](../filters.md) are quite helpful, here. However, **it may be tedious or impossible for [other Mustache implementations](https://github.com/defunkt/mustache/wiki/Other-Mustache-implementations) to produce the same rendering.**
18da0ef @groue Number formatting sample code
authored
104
105 So check again the genuine Mustache way, above. Or keep on reading, now that you are warned.
106
a68a579 @groue Rewritten number formatting guide, so that it uses filters.
authored
107 Let's first rewrite our template so that it uses filters:
18da0ef @groue Number formatting sample code
authored
108
a68a579 @groue Rewritten number formatting guide, so that it uses filters.
authored
109 {{% FILTERS }} # tell GRMustache to trigger support for filters
110 raw: {{ value }}
111 percent: {{ percent(value) }}
112 decimal: {{ decimal(value) }}
18da0ef @groue Number formatting sample code
authored
113
a68a579 @groue Rewritten number formatting guide, so that it uses filters.
authored
114 After we have told GRMustache how the `percent` and `decimal` filters should process their input, we will be releived from the need to prepare our data before it is rendered: no more adding of specific keys in a dictionary, no more declaration of a category on our models.
18da0ef @groue Number formatting sample code
authored
115
116 ```objc
117 - (NSString *)render
118 {
119 /**
a68a579 @groue Rewritten number formatting guide, so that it uses filters.
authored
120 * Our template wants to render floats in various formats: raw, or formatted
121 * as percentage, or formatted as decimal.
122 *
123 * This is typically a job for filters: we'll define the `percent` and
124 * `decimal` filters.
125 *
126 * For now, we just have our template use them. The initial {{ %FILTERS }}
127 * pragma tag tells GRMustache to trigger support for filters, which are an
128 * extension to the Mustache specification.
18da0ef @groue Number formatting sample code
authored
129 */
a68a579 @groue Rewritten number formatting guide, so that it uses filters.
authored
130
131 NSString *templateString = @"{{% FILTERS }}"
132 @"raw: {{ value }}\n"
133 @"percent: {{ percent(value) }}\n"
134 @"decimal: {{ decimal(value) }}";
135 GRMustacheTemplate *template = [GRMustacheTemplate templateFromString:templateString error:NULL];
18da0ef @groue Number formatting sample code
authored
136
a68a579 @groue Rewritten number formatting guide, so that it uses filters.
authored
137 /**
138 * Now we have to define those filters.
139 *
140 * Filters have to be objects that conform to the GRMustacheFilter protocol.
141 * The easiest way to build one is to use the
142 * [GRMustacheFilter filterWithBlock:] method.
143 *
144 * The formatting itself is done by our friend NSNumberFormatter.
145 */
146
147 // Build our formatters
18da0ef @groue Number formatting sample code
authored
148
149 NSNumberFormatter *percentNumberFormatter = [[NSNumberFormatter alloc] init];
150 percentNumberFormatter.numberStyle = kCFNumberFormatterPercentStyle;
a68a579 @groue Rewritten number formatting guide, so that it uses filters.
authored
151
18da0ef @groue Number formatting sample code
authored
152 NSNumberFormatter *decimalNumberFormatter = [[NSNumberFormatter alloc] init];
153 decimalNumberFormatter.numberStyle = kCFNumberFormatterDecimalStyle;
154
155
a68a579 @groue Rewritten number formatting guide, so that it uses filters.
authored
156 // Build our filters
18da0ef @groue Number formatting sample code
authored
157
a68a579 @groue Rewritten number formatting guide, so that it uses filters.
authored
158 id percentFilter = [GRMustacheFilter filterWithBlock:^id(id value) {
159 return [percentNumberFormatter stringFromNumber:value];
160 }];
18da0ef @groue Number formatting sample code
authored
161
a68a579 @groue Rewritten number formatting guide, so that it uses filters.
authored
162 id decimalFilter = [GRMustacheFilter filterWithBlock:^id(id value) {
163 return [decimalNumberFormatter stringFromNumber:value];
164 }];
18da0ef @groue Number formatting sample code
authored
165
166
167 /**
a68a579 @groue Rewritten number formatting guide, so that it uses filters.
authored
168 * GRMustache does not load filters from the rendered data, but from a
169 * specific filters container.
170 *
171 * We'll use a NSDictionary for storing the filters, but you can use any
172 * other KVC-compliant container.
35162b7 @groue Hard wrap documentation to 80 columns
authored
173 */
a68a579 @groue Rewritten number formatting guide, so that it uses filters.
authored
174
175 NSDictionary *filters = [NSDictionary dictionaryWithObjectsAndKeys:
176 percentFilter, @"percent",
177 decimalFilter, @"decimal",
178 nil];
179
459f57b @groue v4.1.0
authored
180
35162b7 @groue Hard wrap documentation to 80 columns
authored
181 /**
f5f8e18 @groue Rewritten number formatting guide, so that it uses filters.
authored
182 * Prepare our data
35162b7 @groue Hard wrap documentation to 80 columns
authored
183 */
a68a579 @groue Rewritten number formatting guide, so that it uses filters.
authored
184
185 Model *model = ...;
186 model.value = 0.5;
f5f8e18 @groue Rewritten number formatting guide, so that it uses filters.
authored
187
188
189 /**
190 * Render "raw: 0.5, percent: 50 %, decimal: 0,5"
191 */
192
a68a579 @groue Rewritten number formatting guide, so that it uses filters.
authored
193 return [template renderObject:model withFilters:filters];
18da0ef @groue Number formatting sample code
authored
194 }
195 ```
196
c1aaf13 @groue More links from guides to sample projects
authored
197 **[Download the code](../../../../tree/master/Guides/sample_code/number_formatting)**
198
2e61bf9 @groue Fix internal guide links
authored
199 [up](../../../../tree/master/Guides/sample_code), [next](indexes.md)
Something went wrong with that request. Please try again.