Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Collection Indexes Sample Code update

  • Loading branch information...
commit 59c121a6cc33ebba69003956b1a5f359d117d5b5 1 parent d95b7f7
@groue authored
Showing with 5,046 additions and 605 deletions.
  1. +12 −12 Guides/rendering_objects.md
  2. +88 −189 Guides/sample_code/indexes.md
  3. +126 −94 Guides/sample_code/indexes/GRMustacheIndexes.xcodeproj/project.pbxproj
  4. +9 −7 Guides/sample_code/indexes/GRMustacheIndexes/{Document.h → AppDelegate.h}
  5. +24 −11 Guides/sample_code/indexes/GRMustacheIndexes/{Person.m → AppDelegate.m}
  6. +0 −82 Guides/sample_code/indexes/GRMustacheIndexes/Document.m
  7. +7 −0 Guides/sample_code/indexes/GRMustacheIndexes/Document.mustache
  8. +34 −0 Guides/sample_code/indexes/GRMustacheIndexes/GRMustacheIndexes-Info.plist
  9. +1 −1  Guides/sample_code/indexes/GRMustacheIndexes/GRMustacheIndexes-Prefix.pch
  10. +0 −28 Guides/sample_code/indexes/GRMustacheIndexes/Person.h
  11. +6 −8 Guides/sample_code/indexes/GRMustacheIndexes/PositionFilter.h
  12. +63 −73 Guides/sample_code/indexes/GRMustacheIndexes/PositionFilter.m
  13. +4,666 −0 Guides/sample_code/indexes/GRMustacheIndexes/en.lproj/MainMenu.xib
  14. +10 −31 Guides/sample_code/indexes/GRMustacheIndexes/main.m
  15. +0 −24 Guides/sample_code/layout/GRMustacheLayout.xcodeproj/project.pbxproj
  16. +0 −29 Guides/sample_code/layout/GRMustacheLayout/en.lproj/Credits.rtf
  17. +0 −2  Guides/sample_code/layout/GRMustacheLayout/en.lproj/InfoPlist.strings
  18. +0 −12 Guides/sample_code/localization/GRMustacheLocalization.xcodeproj/project.pbxproj
  19. +0 −2  Guides/sample_code/localization/GRMustacheLocalization/en.lproj/InfoPlist.strings
View
24 Guides/rendering_objects.md
@@ -102,13 +102,13 @@ The `renderContentWithContext:HTMLSafe:error:` method returns the rendering of t
Your rendering objects can thus delegate their rendering to the tag they are given. They can render the tag once or many times:
-`Document.mustache`
+`Document.mustache`:
{{#twice}}
Mustache is awesome!
{{/twice}}
-`Render.m`
+`Render.m`:
```objc
id data = @{
@@ -212,7 +212,7 @@ You can still choose the rendered partial at runtime, with simple variable tags:
<a href="{{url}}">{{firstName}} {{lastName}}</a>
-`Render.m`
+`Render.m`:
```objc
id data = @{
@@ -264,7 +264,7 @@ Example: Dynamic partials, take 2
<a href="{{url}}">{{firstName}} {{lastName}}</a>
-`Render.m`
+`Render.m`:
```objc
id data = @{
@@ -309,19 +309,19 @@ Example: Dynamic partials, take 3: objects that "render themselves"
Let's implement something similar to Ruby on Rails's `<%= render @movie %>`:
-`Document.mustache`
+`Document.mustache`:
{{movie}}
-`Movie.mustache`
+`Movie.mustache`:
{{title}} by {{director}}
-`Person.mustache`
+`Person.mustache`:
{{firstName}} {{lastName}}
-`Render.m`
+`Render.m`:
```objc
Person *director = [Person personWithFirstName:@"Orson" lastName:@"Welles"];
@@ -421,19 +421,19 @@ Example: Render collections of objects
Using the same Movie and Person class introduced above, we can easily render a list of movies, just as Ruby on Rails's <%= render @movies %>:
-`Document.mustache`
+`Document.mustache`:
{{movies}} {{! one movie is not enough }}
-`Movie.mustache`
+`Movie.mustache`:
{{title}} by {{director}}
-`Person.mustache`
+`Person.mustache`:
{{firstName}} {{lastName}}
-`Render.m`
+`Render.m`:
```objc
id data = @{
View
277 Guides/sample_code/indexes.md
@@ -28,6 +28,8 @@ So check again the genuine Mustache way, above. Or keep on reading, now that you
Below we'll implement the special keys `position`, `isFirst`, and `isOdd`. We'll render the following template:
+`Document.mustache`:
+
<ul>
{{# withPosition(people) }}
<li class="{{# isOdd }}odd{{/ isOdd }} {{# isFirst }}first{{/ isFirst }}">
@@ -36,7 +38,7 @@ Below we'll implement the special keys `position`, `isFirst`, and `isOdd`. We'll
{{/ withPosition(people) }}
</ul>
-We expect, on output, the following rendering:
+Final rendering:
<ul>
<li class="odd first">
@@ -59,9 +61,8 @@ Let's first assume that the filter is already implemented, ready to be used. It
```objc
/**
- * A GRMustache filter that, given an array, returns another array made of
- * objects that render just as original array items, but for the extra
- * following keys:
+ * A GRMustache filter that render its array argument with the extra following
+ * keys defined for each item:
*
* - position: returns the 1-based index of the item
* - isOdd: returns YES if the position of the item is odd
@@ -71,77 +72,24 @@ Let's first assume that the filter is already implemented, ready to be used. It
@end
```
-Well, it looks quite a good fit for our task: if we provide this filter with an array of people, it will return an array of objects that will be able to give a template both their positions, and the properties of their people.
+Well, it looks quite a good fit for our task. We have everything we need to render our template:
-We have everything we need to render our template:
+`Render.m`:
```objc
-- (NSString *)render
-{
- /**
- * Our template want to render the `people` array with support for various
- * positional information on top of regular keys fetched from each person
- * of the array:
- *
- * - position: the 1-based index of the person
- * - isOdd: YES if the position of the person is odd
- * - isFirst: YES if the person is the first of the people array.
- *
- * This is typically a job for filters: we'll define the `withPosition`
- * filters to be an instance of the PositionFilter class. That class has
- * been implemented so that it provides us with the extra keys for free.
- *
- * For now, we just declare our template.
- */
- NSString *templateString = @"<ul>\n"
- @"{{# withPosition(people) }}"
- @" <li class=\"{{# isOdd }}odd{{/ isOdd }} {{# isFirst }}first{{/ isFirst }}\">\n"
- @" {{ position }}:{{ name }}\n"
- @" </li>\n"
- @"{{/ withPosition(people) }}"
- @"</ul>";
- GRMustacheTemplate *template = [GRMustacheTemplate templateFromString:templateString error:NULL];
-
-
- /**
- * Now we have to define this filter. The PositionFilter class is already
- * there, ready to be instanciated:
- */
-
- PositionFilter *positionFilter = [[PositionFilter alloc] init];
-
-
- /**
- * GRMustache does not load filters from the rendered data, but from a
- * specific filters container.
- *
- * We'll use a NSDictionary for attaching positionFilter to the
- * "withPosition" key, but you can use any other KVC-compliant container.
- */
-
- NSDictionary *filters = @{ @"withPosition": positionFilter };
-
-
- /**
- * Now we need an array of people that will be sequentially rendered by the
- * `{{# withPosition(people) }}...{{/ withPosition(people) }}` section.
- *
- * We'll use a NSDictionary for storing the array, but as always you can use
- * any other KVC-compliant container.
- */
-
- Person *alice = [Person personWithName:@"Alice"];
- Person *bob = [Person personWithName:@"Bob"];
- Person *craig = [Person personWithName:@"Craig"];
- NSDictionary *data = @{ @"people": @[alice, bob, craig] };
-
-
- /**
- * Render.
- */
-
- return [template renderObject:data withFilters:filters];
-}
+id data = @{
+ @"people": @[
+ @{ @"name": @"Alice" },
+ @{ @"name": @"Bob" },
+ @{ @"name": @"Craig" },
+ ],
+ @"withPosition": [PositionFilter new]
+};
+
+NSString *rendering = [GRMustacheTemplate renderObject:data
+ fromResource:@"Document"
+ bundle:nil
+ error:NULL];
```
### The filter implementation
@@ -153,144 +101,95 @@ Let's now implement this nifty `PositionFilter` class.
We have already seen above its declaration: it's simply a class that conforms to the GRMustacheFilter protocol:
```objc
+/**
+ * A GRMustache filter that render its array argument with the extra following
+ * keys defined for each item:
+ *
+ * - position: returns the 1-based index of the item
+ * - isOdd: returns YES if the position of the item is odd
+ * - isFirst: returns YES if the item is at position 1
+ */
@interface PositionFilter : NSObject<GRMustacheFilter>
@end
```
-As such, it must implement the `transformedValue:` method:
-
-```objc
-@implementation PositionFilter
-- (id)transformedValue:(id)object
-{
- return ...;
-}
-```
-
-Provided with an array, it returns another array filled with objects "that render just as original array items, but for the extra following keys: `position`, `isOdd`, `isFirst`."
+As such, it must implement the `transformedValue:` method, that returns the result of the filter. That result will perform a custom rendering of its array argument.
-We have to implement those objects as well. In order to do their job, they have to now both the original item in the original array, and its index. Below is the declaration of those objects, madeof an initialization method that provides all the required information. They are a subclass of the `GRMustacheProxy` class, we'll explain why soon.
-
-```objc
-@interface PositionFilterItem : GRMustacheProxy
-- (id)initWithObjectAtIndex:(NSUInteger)index fromArray:(NSArray *)array;
-@end
-```
-
-Based on this declaration, we can implement the `PositionFilter` class itself:
+You provide custom rendering with objects that conform to the `GRMustacheRendering` protocol (see the [Rendering Objects Guide](../rendering_objects.md)). Our custom rendering object will render the section tag as many times as it has items, extending the [context stack](../runtime.md) with both a dictionary containing the special keys, and the array items that will provide the `name` key:
```objc
@implementation PositionFilter
/**
- * GRMustacheFilter protocol required method
+ * The transformedValue: method is required by the GRMustacheFilter protocol.
+ *
+ * Don't provide any type checking, and assume the filter argument is an array:
*/
-- (id)transformedValue:(id)object
+
+- (id)transformedValue:(NSArray *)array
{
/**
- * Let's first validate the input: we can only filter arrays.
- */
-
- NSAssert([object isKindOfClass:[NSArray class]], @"Not an NSArray");
- NSArray *array = (NSArray *)object;
-
-
- /**
- * Let's return a new array made of PositionFilterItem instances.
- * They will provide the `position`, `isOdd` and `isFirst` keys while
- * letting original array items provide the other keys.
+ * We want to provide custom rendering of the array.
+ *
+ * So let's provide an object that does custom rendering.
*/
- NSMutableArray *replacementArray = [NSMutableArray arrayWithCapacity:array.count];
- [array enumerateObjectsUsingBlock:^(id object, NSUInteger index, BOOL *stop) {
- PositionFilterItem *item = [[PositionFilterItem alloc] initWithObjectAtIndex:index fromArray:array];
- [replacementArray addObject:item];
+ return [GRMustache renderingObjectWithBlock:^NSString *(GRMustacheTag *tag, GRMustacheContext *context, BOOL *HTMLSafe, NSError *__autoreleasing *error) {
+
+ /**
+ * We are going to render the tag once for each item. We need a buffer
+ * to store all those renderings:
+ */
+
+ NSMutableString *buffer = [NSMutableString string];
+
+
+ /**
+ * For each item...
+ */
+
+ [array enumerateObjectsUsingBlock:^(id item, NSUInteger index, BOOL *stop) {
+
+ /**
+ * Have our "specials" keys enter the context stack:
+ */
+
+ id specials = @{
+ @"position": @(index + 1),
+ @"isFirst" : @(index == 0),
+ @"isOdd" : @(index % 2 == 0),
+ };
+ GRMustacheContext *itemContext = [context contextByAddingObject:specials];
+
+
+ /**
+ * Have the item itself enter the context stack (so that the `name`
+ * key can render):
+ */
+
+ itemContext = [itemContext contextByAddingObject:item];
+
+
+ /**
+ * Append the item rendering to our buffer:
+ */
+
+ NSString *itemRendering = [tag renderContentWithContext:itemContext HTMLSafe:HTMLSafe error:error];
+ [buffer appendString:itemRendering];
+ }];
+
+
+ /**
+ * Done
+ */
+
+ return buffer;
}];
- return replacementArray;
}
@end
```
-Our filter is ready. We now just need to implement the `PositionFilterItem` class itself.
-
-It must "*render just as original array items, but for the extra following keys: `position`, `isOdd`, `isFirst`.*"
-
-This is the job of the [GRMustacheProxy](../proxies) class. `GRMustacheProxy` is a convenience class that let you build objects that behaves exactly the same as another object, named its "delegate". It is simply a matter of subclassing it in
-order to add support for our extra keys, and this is why `PositionFilterItem` is a subclass of `GRMustacheProxy`.
-
-Here we go:
-
-```objc
-/**
- * Let's declare a private property that stored the index: `index_`, and allows
- * us to implement the `position`, `isFirst` and `isOdd` keys.
- *
- * The underscore suffix avoids the property to pollute Mustache context:
- * your templates may contain a {{position}} tag, but it's unlikely they embed
- * any {{index_}} tags.
- */
-@interface PositionFilterItem()
-@property (nonatomic) NSUInteger index_;
-@end
-```
-
-The initializer is straightforward:
-
-```objc
-@implementation PositionFilterItem
-
-/**
- * PositionFilterItem is a subclass of GRMustacheProxy, so that it behaves
- * just as the array item. The array item is the "delegate" of the proxy.
- *
- * Let's also store the index, so that we can compute values for `position`,
- * `isFirst`, and `isOdd`.
- */
-- (id)initWithObjectAtIndex:(NSUInteger)index fromArray:(NSArray *)array
-{
- // Initialize as a GRMustacheProxy with delegate:
- self = [super initWithDelegate:[array objectAtIndex:index]];
-
- // Store the index:
- if (self) {
- self.index_ = index;
- }
- return self;
-}
-```
-
-So are the three positional properties, `position`, `isOdd`, and `isFirst`:
-
-```objc
-/**
- * Support for {{position}}: returns the 1-based index of the object.
- */
-- (NSUInteger)position
-{
- return self.index_ + 1;
-}
-
-/**
- * Support for `{{#isFirst}}...{{/isFirst}}`: return YES if element is the
- * first.
- */
-- (BOOL)isFirst
-{
- return self.index_ == 0;
-}
-
-/**
- * Support for `{{#isOdd}}...{{/isOdd}}`: return YES if element's position is
- * odd.
- */
-- (BOOL)isOdd
-{
- return (self.index_ % 2) == 0;
-}
-
-@end
-```
**[Download the code](../../../../tree/master/Guides/sample_code/indexes)**
View
220 Guides/sample_code/indexes/GRMustacheIndexes.xcodeproj/project.pbxproj
@@ -7,116 +7,113 @@
objects = {
/* Begin PBXBuildFile section */
- 562952A215A1663B0061A6B1 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 562952A115A1663B0061A6B1 /* Foundation.framework */; };
- 562952A515A1663B0061A6B1 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 562952A415A1663B0061A6B1 /* main.m */; };
- 562952B915A167710061A6B1 /* Document.m in Sources */ = {isa = PBXBuildFile; fileRef = 562952B815A167710061A6B1 /* Document.m */; };
- 562952BC15A167E90061A6B1 /* Person.m in Sources */ = {isa = PBXBuildFile; fileRef = 562952BB15A167E90061A6B1 /* Person.m */; };
- 562952BF15A168550061A6B1 /* PositionFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = 562952BE15A168550061A6B1 /* PositionFilter.m */; };
- 56F9D2CF15A30E47003026DD /* libGRMustache5-MacOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 56F9D2CE15A30E47003026DD /* libGRMustache5-MacOS.a */; };
+ 56F393A9163FF77F005E4A25 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 56F393A8163FF77F005E4A25 /* Cocoa.framework */; };
+ 56F393B5163FF77F005E4A25 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 56F393B4163FF77F005E4A25 /* main.m */; };
+ 56F393BC163FF780005E4A25 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 56F393BB163FF780005E4A25 /* AppDelegate.m */; };
+ 56F393BF163FF780005E4A25 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 56F393BD163FF780005E4A25 /* MainMenu.xib */; };
+ 56F393D1163FF7B7005E4A25 /* libGRMustache6-MacOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 56F393D0163FF7B7005E4A25 /* libGRMustache6-MacOS.a */; };
+ 56F393D3163FF7C9005E4A25 /* Document.mustache in Resources */ = {isa = PBXBuildFile; fileRef = 56F393D2163FF7C9005E4A25 /* Document.mustache */; };
+ 56F393DA163FF837005E4A25 /* PositionFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = 56F393D9163FF837005E4A25 /* PositionFilter.m */; };
/* End PBXBuildFile section */
-/* Begin PBXCopyFilesBuildPhase section */
- 5629529B15A1663B0061A6B1 /* CopyFiles */ = {
- isa = PBXCopyFilesBuildPhase;
- buildActionMask = 2147483647;
- dstPath = /usr/share/man/man1/;
- dstSubfolderSpec = 0;
- files = (
- );
- runOnlyForDeploymentPostprocessing = 1;
- };
-/* End PBXCopyFilesBuildPhase section */
-
/* Begin PBXFileReference section */
- 5629529D15A1663B0061A6B1 /* GRMustacheIndexes */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = GRMustacheIndexes; sourceTree = BUILT_PRODUCTS_DIR; };
- 562952A115A1663B0061A6B1 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
- 562952A415A1663B0061A6B1 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
- 562952A715A1663B0061A6B1 /* GRMustacheIndexes-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "GRMustacheIndexes-Prefix.pch"; sourceTree = "<group>"; };
- 562952B315A167220061A6B1 /* GRMustache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GRMustache.h; path = include/GRMustache.h; sourceTree = "<group>"; };
- 562952B715A167710061A6B1 /* Document.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Document.h; sourceTree = "<group>"; };
- 562952B815A167710061A6B1 /* Document.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Document.m; sourceTree = "<group>"; };
- 562952BA15A167E90061A6B1 /* Person.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Person.h; sourceTree = "<group>"; };
- 562952BB15A167E90061A6B1 /* Person.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Person.m; sourceTree = "<group>"; };
- 562952BD15A168550061A6B1 /* PositionFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PositionFilter.h; sourceTree = "<group>"; };
- 562952BE15A168550061A6B1 /* PositionFilter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PositionFilter.m; sourceTree = "<group>"; };
- 56F9D2CE15A30E47003026DD /* libGRMustache5-MacOS.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libGRMustache5-MacOS.a"; path = "lib/libGRMustache5-MacOS.a"; sourceTree = "<group>"; };
+ 56F393A4163FF77F005E4A25 /* GRMustacheIndexes.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GRMustacheIndexes.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 56F393A8163FF77F005E4A25 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
+ 56F393AB163FF77F005E4A25 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
+ 56F393AC163FF77F005E4A25 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; };
+ 56F393AD163FF77F005E4A25 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
+ 56F393B0163FF77F005E4A25 /* GRMustacheIndexes-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "GRMustacheIndexes-Info.plist"; sourceTree = "<group>"; };
+ 56F393B4163FF77F005E4A25 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
+ 56F393B6163FF780005E4A25 /* GRMustacheIndexes-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "GRMustacheIndexes-Prefix.pch"; sourceTree = "<group>"; };
+ 56F393BA163FF780005E4A25 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
+ 56F393BB163FF780005E4A25 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
+ 56F393BE163FF780005E4A25 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainMenu.xib; sourceTree = "<group>"; };
+ 56F393CF163FF7B7005E4A25 /* GRMustache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GRMustache.h; path = include/GRMustache.h; sourceTree = "<group>"; };
+ 56F393D0163FF7B7005E4A25 /* libGRMustache6-MacOS.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libGRMustache6-MacOS.a"; path = "lib/libGRMustache6-MacOS.a"; sourceTree = "<group>"; };
+ 56F393D2163FF7C9005E4A25 /* Document.mustache */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Document.mustache; sourceTree = "<group>"; };
+ 56F393D8163FF837005E4A25 /* PositionFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PositionFilter.h; sourceTree = "<group>"; };
+ 56F393D9163FF837005E4A25 /* PositionFilter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PositionFilter.m; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
- 5629529A15A1663B0061A6B1 /* Frameworks */ = {
+ 56F393A1163FF77F005E4A25 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- 562952A215A1663B0061A6B1 /* Foundation.framework in Frameworks */,
- 56F9D2CF15A30E47003026DD /* libGRMustache5-MacOS.a in Frameworks */,
+ 56F393A9163FF77F005E4A25 /* Cocoa.framework in Frameworks */,
+ 56F393D1163FF7B7005E4A25 /* libGRMustache6-MacOS.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
- 5629529215A1663A0061A6B1 = {
+ 56F39399163FF77F005E4A25 = {
isa = PBXGroup;
children = (
- 562952A315A1663B0061A6B1 /* GRMustacheIndexes */,
- 562952A015A1663B0061A6B1 /* Frameworks */,
- 5629529E15A1663B0061A6B1 /* Products */,
+ 56F393AE163FF77F005E4A25 /* GRMustacheIndexes */,
+ 56F393A7163FF77F005E4A25 /* Frameworks */,
+ 56F393A5163FF77F005E4A25 /* Products */,
);
sourceTree = "<group>";
};
- 5629529E15A1663B0061A6B1 /* Products */ = {
+ 56F393A5163FF77F005E4A25 /* Products */ = {
isa = PBXGroup;
children = (
- 5629529D15A1663B0061A6B1 /* GRMustacheIndexes */,
+ 56F393A4163FF77F005E4A25 /* GRMustacheIndexes.app */,
);
name = Products;
sourceTree = "<group>";
};
- 562952A015A1663B0061A6B1 /* Frameworks */ = {
+ 56F393A7163FF77F005E4A25 /* Frameworks */ = {
isa = PBXGroup;
children = (
- 562952A115A1663B0061A6B1 /* Foundation.framework */,
+ 56F393A8163FF77F005E4A25 /* Cocoa.framework */,
+ 56F393AA163FF77F005E4A25 /* Other Frameworks */,
);
name = Frameworks;
sourceTree = "<group>";
};
- 562952A315A1663B0061A6B1 /* GRMustacheIndexes */ = {
+ 56F393AA163FF77F005E4A25 /* Other Frameworks */ = {
isa = PBXGroup;
children = (
- 562952A415A1663B0061A6B1 /* main.m */,
- 562952CA15A169E60061A6B1 /* Classes */,
- 56F9D2CC15A30DD1003026DD /* GRMustache */,
- 562952A615A1663B0061A6B1 /* Supporting Files */,
+ 56F393AB163FF77F005E4A25 /* AppKit.framework */,
+ 56F393AC163FF77F005E4A25 /* CoreData.framework */,
+ 56F393AD163FF77F005E4A25 /* Foundation.framework */,
);
- path = GRMustacheIndexes;
+ name = "Other Frameworks";
sourceTree = "<group>";
};
- 562952A615A1663B0061A6B1 /* Supporting Files */ = {
+ 56F393AE163FF77F005E4A25 /* GRMustacheIndexes */ = {
isa = PBXGroup;
children = (
- 562952A715A1663B0061A6B1 /* GRMustacheIndexes-Prefix.pch */,
+ 56F393BA163FF780005E4A25 /* AppDelegate.h */,
+ 56F393BB163FF780005E4A25 /* AppDelegate.m */,
+ 56F393D8163FF837005E4A25 /* PositionFilter.h */,
+ 56F393D9163FF837005E4A25 /* PositionFilter.m */,
+ 56F393D2163FF7C9005E4A25 /* Document.mustache */,
+ 56F393CD163FF79A005E4A25 /* GRMustache */,
+ 56F393AF163FF77F005E4A25 /* Supporting Files */,
);
- name = "Supporting Files";
+ path = GRMustacheIndexes;
sourceTree = "<group>";
};
- 562952CA15A169E60061A6B1 /* Classes */ = {
+ 56F393AF163FF77F005E4A25 /* Supporting Files */ = {
isa = PBXGroup;
children = (
- 562952B715A167710061A6B1 /* Document.h */,
- 562952B815A167710061A6B1 /* Document.m */,
- 562952BA15A167E90061A6B1 /* Person.h */,
- 562952BB15A167E90061A6B1 /* Person.m */,
- 562952BD15A168550061A6B1 /* PositionFilter.h */,
- 562952BE15A168550061A6B1 /* PositionFilter.m */,
+ 56F393BD163FF780005E4A25 /* MainMenu.xib */,
+ 56F393B0163FF77F005E4A25 /* GRMustacheIndexes-Info.plist */,
+ 56F393B4163FF77F005E4A25 /* main.m */,
+ 56F393B6163FF780005E4A25 /* GRMustacheIndexes-Prefix.pch */,
);
- name = Classes;
+ name = "Supporting Files";
sourceTree = "<group>";
};
- 56F9D2CC15A30DD1003026DD /* GRMustache */ = {
+ 56F393CD163FF79A005E4A25 /* GRMustache */ = {
isa = PBXGroup;
children = (
- 562952B315A167220061A6B1 /* GRMustache.h */,
- 56F9D2CE15A30E47003026DD /* libGRMustache5-MacOS.a */,
+ 56F393CF163FF7B7005E4A25 /* GRMustache.h */,
+ 56F393D0163FF7B7005E4A25 /* libGRMustache6-MacOS.a */,
);
name = GRMustache;
path = ../../../..;
@@ -125,13 +122,13 @@
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
- 5629529C15A1663B0061A6B1 /* GRMustacheIndexes */ = {
+ 56F393A3163FF77F005E4A25 /* GRMustacheIndexes */ = {
isa = PBXNativeTarget;
- buildConfigurationList = 562952AC15A1663B0061A6B1 /* Build configuration list for PBXNativeTarget "GRMustacheIndexes" */;
+ buildConfigurationList = 56F393C2163FF780005E4A25 /* Build configuration list for PBXNativeTarget "GRMustacheIndexes" */;
buildPhases = (
- 5629529915A1663B0061A6B1 /* Sources */,
- 5629529A15A1663B0061A6B1 /* Frameworks */,
- 5629529B15A1663B0061A6B1 /* CopyFiles */,
+ 56F393A0163FF77F005E4A25 /* Sources */,
+ 56F393A1163FF77F005E4A25 /* Frameworks */,
+ 56F393A2163FF77F005E4A25 /* Resources */,
);
buildRules = (
);
@@ -139,55 +136,82 @@
);
name = GRMustacheIndexes;
productName = GRMustacheIndexes;
- productReference = 5629529D15A1663B0061A6B1 /* GRMustacheIndexes */;
- productType = "com.apple.product-type.tool";
+ productReference = 56F393A4163FF77F005E4A25 /* GRMustacheIndexes.app */;
+ productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
- 5629529415A1663B0061A6B1 /* Project object */ = {
+ 56F3939B163FF77F005E4A25 /* Project object */ = {
isa = PBXProject;
attributes = {
- LastUpgradeCheck = 0430;
+ LastUpgradeCheck = 0450;
+ ORGANIZATIONNAME = "Gwendal Roué";
};
- buildConfigurationList = 5629529715A1663B0061A6B1 /* Build configuration list for PBXProject "GRMustacheIndexes" */;
+ buildConfigurationList = 56F3939E163FF77F005E4A25 /* Build configuration list for PBXProject "GRMustacheIndexes" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
);
- mainGroup = 5629529215A1663A0061A6B1;
- productRefGroup = 5629529E15A1663B0061A6B1 /* Products */;
+ mainGroup = 56F39399163FF77F005E4A25;
+ productRefGroup = 56F393A5163FF77F005E4A25 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
- 5629529C15A1663B0061A6B1 /* GRMustacheIndexes */,
+ 56F393A3163FF77F005E4A25 /* GRMustacheIndexes */,
);
};
/* End PBXProject section */
+/* Begin PBXResourcesBuildPhase section */
+ 56F393A2163FF77F005E4A25 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 56F393BF163FF780005E4A25 /* MainMenu.xib in Resources */,
+ 56F393D3163FF7C9005E4A25 /* Document.mustache in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
/* Begin PBXSourcesBuildPhase section */
- 5629529915A1663B0061A6B1 /* Sources */ = {
+ 56F393A0163FF77F005E4A25 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- 562952A515A1663B0061A6B1 /* main.m in Sources */,
- 562952B915A167710061A6B1 /* Document.m in Sources */,
- 562952BC15A167E90061A6B1 /* Person.m in Sources */,
- 562952BF15A168550061A6B1 /* PositionFilter.m in Sources */,
+ 56F393B5163FF77F005E4A25 /* main.m in Sources */,
+ 56F393BC163FF780005E4A25 /* AppDelegate.m in Sources */,
+ 56F393DA163FF837005E4A25 /* PositionFilter.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
+/* Begin PBXVariantGroup section */
+ 56F393BD163FF780005E4A25 /* MainMenu.xib */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 56F393BE163FF780005E4A25 /* en */,
+ );
+ name = MainMenu.xib;
+ sourceTree = "<group>";
+ };
+/* End PBXVariantGroup section */
+
/* Begin XCBuildConfiguration section */
- 562952AA15A1663B0061A6B1 /* Debug */ = {
+ 56F393C0163FF780005E4A25 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ARCHS = "$(ARCHS_STANDARD_64_BIT)";
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
@@ -198,85 +222,93 @@
"$(inherited)",
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
- GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- MACOSX_DEPLOYMENT_TARGET = 10.7;
+ MACOSX_DEPLOYMENT_TARGET = 10.8;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
};
name = Debug;
};
- 562952AB15A1663B0061A6B1 /* Release */ = {
+ 56F393C1163FF780005E4A25 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ARCHS = "$(ARCHS_STANDARD_64_BIT)";
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
- GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- MACOSX_DEPLOYMENT_TARGET = 10.7;
+ MACOSX_DEPLOYMENT_TARGET = 10.8;
SDKROOT = macosx;
};
name = Release;
};
- 562952AD15A1663B0061A6B1 /* Debug */ = {
+ 56F393C3163FF780005E4A25 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "GRMustacheIndexes/GRMustacheIndexes-Prefix.pch";
+ INFOPLIST_FILE = "GRMustacheIndexes/GRMustacheIndexes-Info.plist";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"\"$(SRCROOT)/../../../lib\"",
);
PRODUCT_NAME = "$(TARGET_NAME)";
+ WRAPPER_EXTENSION = app;
};
name = Debug;
};
- 562952AE15A1663B0061A6B1 /* Release */ = {
+ 56F393C4163FF780005E4A25 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "GRMustacheIndexes/GRMustacheIndexes-Prefix.pch";
+ INFOPLIST_FILE = "GRMustacheIndexes/GRMustacheIndexes-Info.plist";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"\"$(SRCROOT)/../../../lib\"",
);
PRODUCT_NAME = "$(TARGET_NAME)";
+ WRAPPER_EXTENSION = app;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
- 5629529715A1663B0061A6B1 /* Build configuration list for PBXProject "GRMustacheIndexes" */ = {
+ 56F3939E163FF77F005E4A25 /* Build configuration list for PBXProject "GRMustacheIndexes" */ = {
isa = XCConfigurationList;
buildConfigurations = (
- 562952AA15A1663B0061A6B1 /* Debug */,
- 562952AB15A1663B0061A6B1 /* Release */,
+ 56F393C0163FF780005E4A25 /* Debug */,
+ 56F393C1163FF780005E4A25 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
- 562952AC15A1663B0061A6B1 /* Build configuration list for PBXNativeTarget "GRMustacheIndexes" */ = {
+ 56F393C2163FF780005E4A25 /* Build configuration list for PBXNativeTarget "GRMustacheIndexes" */ = {
isa = XCConfigurationList;
buildConfigurations = (
- 562952AD15A1663B0061A6B1 /* Debug */,
- 562952AE15A1663B0061A6B1 /* Release */,
+ 56F393C3163FF780005E4A25 /* Debug */,
+ 56F393C4163FF780005E4A25 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
- rootObject = 5629529415A1663B0061A6B1 /* Project object */;
+ rootObject = 56F3939B163FF77F005E4A25 /* Project object */;
}
View
16 ...code/indexes/GRMustacheIndexes/Document.h → ...e/indexes/GRMustacheIndexes/AppDelegate.h
@@ -1,17 +1,17 @@
// The MIT License
-//
+//
// Copyright (c) 2012 Gwendal Roué
-//
+//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
-//
+//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
-//
+//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -20,8 +20,10 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
-#import <Foundation/Foundation.h>
+#import <Cocoa/Cocoa.h>
+
+@interface AppDelegate : NSObject <NSApplicationDelegate>
+
+@property (assign) IBOutlet NSWindow *window;
-@interface Document : NSObject
-- (NSString *)render;
@end
View
35 ...e_code/indexes/GRMustacheIndexes/Person.m → ...e/indexes/GRMustacheIndexes/AppDelegate.m
@@ -1,17 +1,17 @@
// The MIT License
-//
+//
// Copyright (c) 2012 Gwendal Roué
-//
+//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
-//
+//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
-//
+//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -20,16 +20,29 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
-#import "Person.h"
+#import "AppDelegate.h"
+#import "GRMustache.h"
+#import "PositionFilter.h"
-@implementation Person
-@synthesize name=_name;
+@implementation AppDelegate
-+ (id)personWithName:(NSString *)name
+- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
- Person *person = [Person new];
- person.name = name;
- return person;
+ id data = @{
+ @"people": @[
+ @{ @"name": @"Alice" },
+ @{ @"name": @"Bob" },
+ @{ @"name": @"Craig" },
+ ],
+ @"withPosition": [PositionFilter new]
+ };
+
+ NSString *rendering = [GRMustacheTemplate renderObject:data
+ fromResource:@"Document"
+ bundle:nil
+ error:NULL];
+
+ NSLog(@"rendering = %@", rendering);
}
@end
View
82 Guides/sample_code/indexes/GRMustacheIndexes/Document.m
@@ -1,82 +0,0 @@
-// The MIT License
-//
-// Copyright (c) 2012 Gwendal Roué
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-#import "GRMustache.h"
-#import "Document.h"
-#import "Person.h"
-#import "PositionFilter.h"
-
-@implementation Document
-
-- (NSString *)render
-{
- /**
- * Our template want to render the `people` array with support for various
- * positional information on top of regular keys fetched from each person
- * of the array:
- *
- * - position: the 1-based index of the person
- * - isOdd: YES if the position of the person is odd
- * - isFirst: YES if the person is the first of the people array.
- *
- * This is typically a job for filters: we'll define the `withPosition`
- * filters to be an instance of the PositionFilter class. That class has
- * been implemented so that it provides us with the extra keys for free.
- *
- * For now, we just declare our template.
- */
- NSString *templateString = @"<ul>\n"
- @"{{# withPosition(people) }}"
- @" <li class=\"{{# isOdd }}odd{{/ isOdd }} {{# isFirst }}first{{/ isFirst }}\">\n"
- @" {{ position }}:{{ name }}\n"
- @" </li>\n"
- @"{{/ withPosition(people) }}"
- @"</ul>";
- GRMustacheTemplate *template = [GRMustacheTemplate templateFromString:templateString error:NULL];
-
-
- /**
- * Now we need an array of people that will be sequentially rendered by the
- * `{{# withPosition(people) }}...{{/ withPosition(people) }}` section.
- *
- * We'll use a NSDictionary for storing the array and the filter. As always
- * you can use any other KVC-compliant container.
- */
-
- Person *alice = [Person personWithName:@"Alice"];
- Person *bob = [Person personWithName:@"Bob"];
- Person *craig = [Person personWithName:@"Craig"];
- NSArray *people = @[alice, bob, craig];
- NSDictionary *data = @{
- @"people": people,
- @"withPosition": [[PositionFilter alloc] init]
- };
-
-
- /**
- * Render.
- */
-
- return [template renderObject:data error:NULL];
-}
-
-@end
View
7 Guides/sample_code/indexes/GRMustacheIndexes/Document.mustache
@@ -0,0 +1,7 @@
+<ul>
+{{# withPosition(people) }}
+ <li class="{{# isOdd }}odd{{/ isOdd }} {{# isFirst }}first{{/ isFirst }}">
+ {{ position }}:{{ name }}
+ </li>
+{{/ withPosition(people) }}
+</ul>
View
34 Guides/sample_code/indexes/GRMustacheIndexes/GRMustacheIndexes-Info.plist
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>en</string>
+ <key>CFBundleExecutable</key>
+ <string>${EXECUTABLE_NAME}</string>
+ <key>CFBundleIconFile</key>
+ <string></string>
+ <key>CFBundleIdentifier</key>
+ <string>com.github.groue.${PRODUCT_NAME:rfc1034identifier}</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>${PRODUCT_NAME}</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1</string>
+ <key>LSMinimumSystemVersion</key>
+ <string>${MACOSX_DEPLOYMENT_TARGET}</string>
+ <key>NSHumanReadableCopyright</key>
+ <string>Copyright © 2012 Gwendal Roué. All rights reserved.</string>
+ <key>NSMainNibFile</key>
+ <string>MainMenu</string>
+ <key>NSPrincipalClass</key>
+ <string>NSApplication</string>
+</dict>
+</plist>
View
2  Guides/sample_code/indexes/GRMustacheIndexes/GRMustacheIndexes-Prefix.pch
@@ -3,5 +3,5 @@
//
#ifdef __OBJC__
- #import <Foundation/Foundation.h>
+ #import <Cocoa/Cocoa.h>
#endif
View
28 Guides/sample_code/indexes/GRMustacheIndexes/Person.h
@@ -1,28 +0,0 @@
-// The MIT License
-//
-// Copyright (c) 2012 Gwendal Roué
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-#import <Foundation/Foundation.h>
-
-@interface Person : NSObject
-@property (nonatomic, strong) NSString *name;
-+ (id)personWithName:(NSString *)name;
-@end
View
14 Guides/sample_code/indexes/GRMustacheIndexes/PositionFilter.h
@@ -1,17 +1,17 @@
// The MIT License
-//
+//
// Copyright (c) 2012 Gwendal Roué
-//
+//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
-//
+//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
-//
+//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -24,9 +24,8 @@
#import "GRMustache.h"
/**
- * A GRMustache filter that, given an array, returns another array made of
- * objects that render just as original array items, but for the extra
- * following keys:
+ * A GRMustache filter that render its array argument with the extra following
+ * keys defined for each item:
*
* - position: returns the 1-based index of the item
* - isOdd: returns YES if the position of the item is odd
@@ -34,4 +33,3 @@
*/
@interface PositionFilter : NSObject<GRMustacheFilter>
@end
-
View
136 Guides/sample_code/indexes/GRMustacheIndexes/PositionFilter.m
@@ -1,17 +1,17 @@
// The MIT License
-//
+//
// Copyright (c) 2012 Gwendal Roué
-//
+//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
-//
+//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
-//
+//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -22,83 +22,73 @@
#import "PositionFilter.h"
-#pragma mark - PositionFilter implementation
-
-// Documented in PositionFilter.h
@implementation PositionFilter
/**
- * The method required by the GRMustacheFilter protocol
+ * The transformedValue: method is required by the GRMustacheFilter protocol.
+ *
+ * Don't provide any type checking, and assume the filter argument is an array:
*/
-- (id)transformedValue:(id)object
+
+- (id)transformedValue:(NSArray *)array
{
- // Input validation: we can only filter arrays.
-
- NSAssert([object isKindOfClass:[NSArray class]], @"Not an NSArray");
- NSArray *array = (NSArray *)object;
+ /**
+ * We want to provide custom rendering of the array.
+ *
+ * So let's provide an object that does custom rendering.
+ */
- // Let's return a object that provides custom rendering:
-
- return [GRMustache renderingObjectWithBlock:^NSString *(GRMustacheTag *tag, GRMustacheContext *context, BOOL *HTMLSafe, NSError *__autoreleasing *error)
- {
- // We only provide custom rendering for sections (and overridable
- // sections, since they are supposed to render in the same way.
+ return [GRMustache renderingObjectWithBlock:^NSString *(GRMustacheTag *tag, GRMustacheContext *context, BOOL *HTMLSafe, NSError *__autoreleasing *error) {
+
+ /**
+ * We are going to render the tag once for each item. We need a buffer
+ * to store all those renderings:
+ */
- switch (tag.type)
- {
- case GRMustacheTagTypeSection:
- case GRMustacheTagTypeOverridableSection:
- {
- // {{# withPosition(items) }}...{{/}}
- // {{$ withPosition(items) }}...{{/}}
- //
- // Let's render the section tag as many times as we have items.
-
- NSMutableString *buffer = [NSMutableString string];
- NSUInteger position = 1;
- for (id item in array)
- {
-
- // For each item, extend the context stack twice:
- //
- // - once with our special keys, `position`, `isFirst` and `isOdd`,
- // - once with the item itself, so that it can provide its own keys:
-
- NSDictionary *special = @{
- @"position": @(position),
- @"isFirst": @(position == 1),
- @"isOdd": @(position % 2 == 1),
- };
- GRMustacheContext *itemContext = [context contextByAddingObject:special];
- itemContext = [itemContext contextByAddingObject:item];
-
- // Append the rendering to our buffer. Don't forget to handle errors:
-
- NSString *rendering = [tag renderContext:itemContext HTMLSafe:HTMLSafe error:error];
- if (!rendering) {
- // Some error occurred.
- return nil;
- }
-
- [buffer appendString:rendering];
- ++position;
- }
- return buffer;
- } break;
-
- default:
- {
- // {{ withPosition(items) }}
- // {{^ withPosition(items) }}...{{/}}
-
- // For other tags, use the default Mustache rendering:
-
- id<GRMustacheRendering> renderingObject = [GRMustache renderingObjectForObject:array];
- return [renderingObject renderForMustacheTag:tag context:context HTMLSafe:HTMLSafe error:error];
- } break;
- }
+ NSMutableString *buffer = [NSMutableString string];
+
+
+ /**
+ * For each item...
+ */
+
+ [array enumerateObjectsUsingBlock:^(id item, NSUInteger index, BOOL *stop) {
+
+ /**
+ * Have our "specials" keys enter the context stack:
+ */
+
+ id specials = @{
+ @"position": @(index + 1),
+ @"isFirst" : @(index == 0),
+ @"isOdd" : @(index % 2 == 0),
+ };
+ GRMustacheContext *itemContext = [context contextByAddingObject:specials];
+
+
+ /**
+ * Have the item itself enter the context stack (so that the `name`
+ * key can render):
+ */
+
+ itemContext = [itemContext contextByAddingObject:item];
+
+
+ /**
+ * Append the item rendering to our buffer:
+ */
+
+ NSString *itemRendering = [tag renderContentWithContext:itemContext HTMLSafe:HTMLSafe error:error];
+ [buffer appendString:itemRendering];
+ }];
+
+
+ /**
+ * Done
+ */
+
+ return buffer;
}];
}
@end
-
View
4,666 Guides/sample_code/indexes/GRMustacheIndexes/en.lproj/MainMenu.xib
4,666 additions, 0 deletions not shown
View
41 Guides/sample_code/indexes/GRMustacheIndexes/main.m
@@ -1,35 +1,14 @@
-// The MIT License
-//
-// Copyright (c) 2012 Gwendal Roué
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
+//
+// main.m
+// GRMustacheIndexes
+//
+// Created by Gwendal Roué on 30/10/12.
+// Copyright (c) 2012 Gwendal Roué. All rights reserved.
+//
-#import <Foundation/Foundation.h>
-#import "Document.h"
+#import <Cocoa/Cocoa.h>
-int main(int argc, const char * argv[])
+int main(int argc, char *argv[])
{
- @autoreleasepool {
- Document *document = [Document new];
- NSString *rendering = [document render];
- NSLog(@"%@", rendering);
- }
- return 0;
+ return NSApplicationMain(argc, (const char **)argv);
}
-
View
24 Guides/sample_code/layout/GRMustacheLayout.xcodeproj/project.pbxproj
@@ -8,9 +8,7 @@
/* Begin PBXBuildFile section */
5667CC4915A1B95F0096B183 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5667CC4815A1B95F0096B183 /* Cocoa.framework */; };
- 5667CC5315A1B95F0096B183 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 5667CC5115A1B95F0096B183 /* InfoPlist.strings */; };
5667CC5515A1B95F0096B183 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 5667CC5415A1B95F0096B183 /* main.m */; };
- 5667CC5915A1B95F0096B183 /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 5667CC5715A1B95F0096B183 /* Credits.rtf */; };
5667CC5C15A1B95F0096B183 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 5667CC5B15A1B95F0096B183 /* AppDelegate.m */; };
5667CC5F15A1B95F0096B183 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5667CC5D15A1B95F0096B183 /* MainMenu.xib */; };
5667CC6A15A1B99C0096B183 /* layout.mustache in Resources */ = {isa = PBXBuildFile; fileRef = 5667CC6915A1B99C0096B183 /* layout.mustache */; };
@@ -27,10 +25,8 @@
5667CC4C15A1B95F0096B183 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; };
5667CC4D15A1B95F0096B183 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
5667CC5015A1B95F0096B183 /* GRMustacheLayout-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "GRMustacheLayout-Info.plist"; sourceTree = "<group>"; };
- 5667CC5215A1B95F0096B183 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
5667CC5415A1B95F0096B183 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
5667CC5615A1B95F0096B183 /* GRMustacheLayout-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "GRMustacheLayout-Prefix.pch"; sourceTree = "<group>"; };
- 5667CC5815A1B95F0096B183 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = en; path = en.lproj/Credits.rtf; sourceTree = "<group>"; };
5667CC5A15A1B95F0096B183 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
5667CC5B15A1B95F0096B183 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
5667CC5E15A1B95F0096B183 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainMenu.xib; sourceTree = "<group>"; };
@@ -109,11 +105,9 @@
isa = PBXGroup;
children = (
5667CC5015A1B95F0096B183 /* GRMustacheLayout-Info.plist */,
- 5667CC5115A1B95F0096B183 /* InfoPlist.strings */,
5667CC5415A1B95F0096B183 /* main.m */,
5667CC5D15A1B95F0096B183 /* MainMenu.xib */,
5667CC5615A1B95F0096B183 /* GRMustacheLayout-Prefix.pch */,
- 5667CC5715A1B95F0096B183 /* Credits.rtf */,
);
name = "Supporting Files";
sourceTree = "<group>";
@@ -197,8 +191,6 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- 5667CC5315A1B95F0096B183 /* InfoPlist.strings in Resources */,
- 5667CC5915A1B95F0096B183 /* Credits.rtf in Resources */,
5667CC5F15A1B95F0096B183 /* MainMenu.xib in Resources */,
5667CC6A15A1B99C0096B183 /* layout.mustache in Resources */,
5667CC6C15A1B9B40096B183 /* header.mustache in Resources */,
@@ -222,22 +214,6 @@
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
- 5667CC5115A1B95F0096B183 /* InfoPlist.strings */ = {
- isa = PBXVariantGroup;
- children = (
- 5667CC5215A1B95F0096B183 /* en */,
- );
- name = InfoPlist.strings;
- sourceTree = "<group>";
- };
- 5667CC5715A1B95F0096B183 /* Credits.rtf */ = {
- isa = PBXVariantGroup;
- children = (
- 5667CC5815A1B95F0096B183 /* en */,
- );
- name = Credits.rtf;
- sourceTree = "<group>";
- };
5667CC5D15A1B95F0096B183 /* MainMenu.xib */ = {
isa = PBXVariantGroup;
children = (
View
29 Guides/sample_code/layout/GRMustacheLayout/en.lproj/Credits.rtf
@@ -1,29 +0,0 @@
-{\rtf0\ansi{\fonttbl\f0\fswiss Helvetica;}
-{\colortbl;\red255\green255\blue255;}
-\paperw9840\paperh8400
-\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
-
-\f0\b\fs24 \cf0 Engineering:
-\b0 \
- Some people\
-\
-
-\b Human Interface Design:
-\b0 \
- Some other people\
-\
-
-\b Testing:
-\b0 \
- Hopefully not nobody\
-\
-
-\b Documentation:
-\b0 \
- Whoever\
-\
-
-\b With special thanks to:
-\b0 \
- Mom\
-}
View
2  Guides/sample_code/layout/GRMustacheLayout/en.lproj/InfoPlist.strings
@@ -1,2 +0,0 @@
-/* Localized versions of Info.plist keys */
-
View
12 Guides/sample_code/localization/GRMustacheLocalization.xcodeproj/project.pbxproj
@@ -8,7 +8,6 @@
/* Begin PBXBuildFile section */
5632EF1315E0D55D009EA316 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5632EF1215E0D55D009EA316 /* Cocoa.framework */; };
- 5632EF1D15E0D55D009EA316 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 5632EF1B15E0D55D009EA316 /* InfoPlist.strings */; };
5632EF1F15E0D55D009EA316 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 5632EF1E15E0D55D009EA316 /* main.m */; };
5632EF2615E0D55D009EA316 /* GRAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 5632EF2515E0D55D009EA316 /* GRAppDelegate.m */; };
5632EF2915E0D55D009EA316 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5632EF2715E0D55D009EA316 /* MainMenu.xib */; };
@@ -24,7 +23,6 @@
5632EF1615E0D55D009EA316 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; };
5632EF1715E0D55D009EA316 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
5632EF1A15E0D55D009EA316 /* GRMustacheLocalization-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "GRMustacheLocalization-Info.plist"; sourceTree = "<group>"; };
- 5632EF1C15E0D55D009EA316 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
5632EF1E15E0D55D009EA316 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
5632EF2015E0D55D009EA316 /* GRMustacheLocalization-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "GRMustacheLocalization-Prefix.pch"; sourceTree = "<group>"; };
5632EF2415E0D55D009EA316 /* GRAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GRAppDelegate.h; sourceTree = "<group>"; };
@@ -105,7 +103,6 @@
children = (
5632EF2715E0D55D009EA316 /* MainMenu.xib */,
5632EF1A15E0D55D009EA316 /* GRMustacheLocalization-Info.plist */,
- 5632EF1B15E0D55D009EA316 /* InfoPlist.strings */,
5632EF1E15E0D55D009EA316 /* main.m */,
5632EF2015E0D55D009EA316 /* GRMustacheLocalization-Prefix.pch */,
);
@@ -174,7 +171,6 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- 5632EF1D15E0D55D009EA316 /* InfoPlist.strings in Resources */,
5632EF2915E0D55D009EA316 /* MainMenu.xib in Resources */,
56BF7C5615E0E08F0067308D /* Localizable.strings in Resources */,
);
@@ -196,14 +192,6 @@
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
- 5632EF1B15E0D55D009EA316 /* InfoPlist.strings */ = {
- isa = PBXVariantGroup;
- children = (
- 5632EF1C15E0D55D009EA316 /* en */,
- );
- name = InfoPlist.strings;
- sourceTree = "<group>";
- };
5632EF2715E0D55D009EA316 /* MainMenu.xib */ = {
isa = PBXVariantGroup;
children = (
View
2  Guides/sample_code/localization/GRMustacheLocalization/en.lproj/InfoPlist.strings
@@ -1,2 +0,0 @@
-/* Localized versions of Info.plist keys */
-
Please sign in to comment.
Something went wrong with that request. Please try again.