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