groue / GRMustache.swift

Flexible Mustache templates for Swift
http://mustache.github.com/
MIT License
594 stars 155 forks source link

How to render nested objects? #45

Closed ebbe-minecraft closed 7 years ago

ebbe-minecraft commented 7 years ago

Been trying to make a nested structure to map against the json response I'm working with but I don't really understand how the example works.

With support for Objective-C runtime, templates can render object properties: {{ user.name }}.

This make it sound like it's possible but is there a more thorough example of how this would be done? This is what I'm trying to do:

class FirstTemplate : NSObject {
    let nestedObject: NSObject

    init(nestedObject: NSObject) {
        self.nestedObject = nestedObject
    }
}

class SecondTemplate : NSObject {
    let someValue: String

    init(someValue: String) {
        self.someValue = someValue
    }
}

let template = try Template(string: "{{nestedObject.someValue}}") // .. json response
let rendering = try template.render(FirstTemplate(nestedObject: SecondTemplate(someValue: "Hello world!"))) //  .. renders blank

This just renders blank but I also tried:

struct FirstTemplate {
    let nestedObject: MustacheBoxable
}

extension FirstTemplate : MustacheBoxable {
    var mustacheBox: MustacheBox {
        return Box(["nestedObject": self.nestedObject])
    }
}

struct SecondTemplate {
    let someValue: String
}

extension SecondTemplate : MustacheBoxable {
    var mustacheBox: MustacheBox {
        return Box(["someValue": self.someValue])
    }
}

let context = FirstTemplate(nestedObject: SecondTemplate(someValue: "Hello world!"))
let template = try Template(string: "{{{nestedObject.someValue}}") // 
let rendering = try template.render(context) //  .. renders blank

.. but this works
// let context = FirstTemplate(nestedObject: SecondTemplate(someValue: "Hello world!"))
// let nestedContext = context.secondTemplate
// let rendering = try template.render(nestedContext) //  "Hello world!"
groue commented 7 years ago

Hello @patrikqvarnstrom.

When I run your first code snippet, I get expected output:

import Mustache

class FirstTemplate : NSObject {
    let nestedObject: NSObject

    init(nestedObject: NSObject) {
        self.nestedObject = nestedObject
    }
}

class SecondTemplate : NSObject {
    let someValue: String

    init(someValue: String) {
        self.someValue = someValue
    }
}

let template = try Template(string: "{{nestedObject.someValue}}")
let rendering = try template.render(FirstTemplate(nestedObject: SecondTemplate(someValue: "Hello world!")))
print(rendering)
// prints "Hello world!"

Your second code snippet fails with an error:

struct FirstTemplate {
    let nestedObject: MustacheBoxable
}

extension FirstTemplate : MustacheBoxable {
    var mustacheBox: MustacheBox {
        return Box(["nestedObject": self.nestedObject])
    }
}

struct SecondTemplate {
    let someValue: String
}

extension SecondTemplate : MustacheBoxable {
    var mustacheBox: MustacheBox {
        return Box(["someValue": self.someValue])
    }
}

let context = FirstTemplate(nestedObject: SecondTemplate(someValue: "Hello world!"))
// fatal error: 'try!' expression unexpectedly raised an error: Parse error at line 1: Unclosed Mustache tag: file /Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-802.0.53/src/swift/stdlib/public/core/ErrorType.swift, line 182
let template = try! Template(string: "{{{nestedObject.someValue}}") //
let rendering = try template.render(context)

That's because {{{nestedObject.someValue}} uses an unbalanced triple-mustache tag.

Are you sure you are not ignoring errors?

ebbe-minecraft commented 7 years ago

Hello @groue and thank for the quick response! That second example was a typo with the triple nested "{" but there is no errors in XCode.

My first snippet is not printing the second value at the moment but since you verified that it is working for you there is probably something else I need to debug. Feel free to close this. šŸ‘

Much appreciated!

groue commented 7 years ago

All right, @patrikqvarnstrom, I'll close this issue. Feel free to reopen it if you remain stuck. And add breakpoints to your code :-)