Closed sl1m3d closed 11 years ago
I will close this issue as "not an issue", since everything works as explained in the GRMustache documentation:
Inside the {{#-localizeData}}{{description}}{{/-localizeData}}
section, the localizer is at the top of the context stack. The rendering engine invokes valueForKey:
on it, finds the default implementation of the description
method, and renders it. When you override it so that it returns nil, the engine keeps on digging for a value, and eventually finds the description
key of the dictionary.
GRMustache rules are simple. It is not an option to make them more complex just for you.
However, GRMustache won't let you down. But you need to help yourself:
I advise you to read the Rendering Objects Guide, and read carefully the explanations about how and when the context stack is extended. You will come up with something like:
@interface MustacheLocalizer ()<GRMustacheTagDelegate, GRMustacheRendering>
@end
@implementation MustacheLocalizer
- (id)mustacheTag:(GRMustacheTag *)tag willRenderObject:(id)object {
if ([object isKindOfClass:[NSDictionary class]])
return object[@"en"];
return object;
}
- (NSString *)renderForMustacheTag:(GRMustacheTag *)tag context:(GRMustacheContext *)context HTMLSafe:(BOOL *)HTMLSafe error:(NSError **)error {
// Avoid having self enter the context stack, and simply render the Mustache tag.
render [tag renderContentWithContext:context HTMLSafe:HTMLSafe error:error];
}
@end
Actually, the following code is closer to your needs (as a rendering object, your localizer class takes full responsibility of its rendering, and must explicitly enter the rendering context as a tag delegate):
@interface MustacheLocalizer ()<GRMustacheTagDelegate, GRMustacheRendering>
@end
@implementation MustacheLocalizer
- (id)mustacheTag:(GRMustacheTag *)tag willRenderObject:(id)object {
if ([object isKindOfClass:[NSDictionary class]])
return object[@"en"];
return object;
}
- (NSString *)renderForMustacheTag:(GRMustacheTag *)tag context:(GRMustacheContext *)context HTMLSafe:(BOOL *)HTMLSafe error:(NSError **)error {
// Have self enter the context as a tag delegate - but not in the context stack
context = [context contextByAddingTagDelegate:self];
// Render the Mustache tag.
return [tag renderContentWithContext:context HTMLSafe:HTMLSafe error:error];
}
@end
The "Tag Delegates as Cross-Platform Filters" guide now documents how to avoid the context stack pollution: https://github.com/groue/GRMustache/blob/master/Guides/delegate.md#tag-delegates-as-cross-platform-filters
I have a special object that wraps an array item (similar to what is in https://github.com/groue/GRMustache/blob/master/Guides/sample_code/indexes.md) that I needed to account for
Ultimately this is what I wound up doing:
- (NSString *)renderForMustacheTag:(GRMustacheTag *)tag context:(GRMustacheContext *)context HTMLSafe:(BOOL *)HTMLSafe error:(NSError **)error {
return [tag renderContentWithContext:[context contextByAddingTagDelegate:self] HTMLSafe:HTMLSafe error:error];
}
-(id)mustacheTag:(GRMustacheTag *)tag willRenderObject:(id)object
{
id obj = nil;
if ([object isKindOfClass:[IndexedArrayItem class]])
obj = [(IndexedArrayItem*)object boxedObject] ? : object;
else
obj = object;
if ([obj isKindOfClass:[NSDictionary class]])
return obj[@"en"];
return object;
}
So Rob, does it work?
Yes, what i posted above seems a bit smelly, but it works for now. I think I need to delegate back to the IndexedArrayItem instead, but IndexedArrayItem handles everything with valueForKey and doesn't conform to the GRMustache protocols.
Two separate but similar issues ->
Sample code:
and the helper
When wrapping {{#-localizeData}} around {{description}}, the description of the class is returned.
When using the {{.}}, the delegate gives us the MustacheLocalizer object instead of the dictionary.