groue / GRMustache.swift

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

Boxing a dictionary of type [String: Any] #8

Closed njdehoog closed 9 years ago

njdehoog commented 9 years ago

Hey @groue, was wondering if you could help me out with an issue I have. I have a dictionary of type [String: Any] which contains metadata for the files I'm rendering. Any advice on how I can make this work with the MustacheBoxable protocol?

groue commented 9 years ago

Hi @njdehoog!

Swift won't help making [String: Any] adopt MustacheBoxable because Swift won't help any specialization of a generic type adopt any protocol. So this is not the way to go.

A solution is to turn your dictionary into a [String: MustacheBox] by turning each dictionary value into a box. Any is not an easy type to deal with: I hope you know the actual type of your dictionary values.

For example:

let dictionary: [String: Any] = ["a": 1, "b": "foo"]

var boxDictionary: [String: MustacheBox] = [:]
for (key, value) in dictionary {
    switch(value) {
    case let boxable as MustacheBoxable:
        boxDictionary[key] = Box(boxable)
    default:
        // Process here eventual boxable value that does not adopt
        // MustacheBoxable such as collections, dictionaries, filters, etc.
        break
    }
}

let template = try! Template(string: "{{a}}, {{b}}")
try! template.render(Box(boxDictionary))
// "1, foo"

Tell me if this helps.

groue commented 9 years ago

BTW: Today I'm reluctant to add such a conversion function to the library, because there are types that are definitely not boxable, and I try to prevent such "unsafe" functions to get their way into the public API. We'll see how frequently your question is raised: the library is still young, so are Swift skills.

groue commented 9 years ago

@njdehoog I added a paragraph in the documentation to help make things more clear: https://github.com/groue/GRMustache.swift/tree/Swift2#templates-eat-boxed-values

njdehoog commented 9 years ago

Thanks for the explanation and the updated documentation @groue! I got it to work in the way that you described, but you made a good point about using more explicit data types, so I am now in the process of refactoring the code to do just that.

groue commented 9 years ago

I'm quite interested in your feedback. What kind of app code your writing? A standalone app, a library?

njdehoog commented 9 years ago

I'm writing a static site generator purely in Swift. Will let you know if I have any feedback on this library. So far it looks great! What do you use this library for yourself?

groue commented 9 years ago

GRMustache.swift has been my way to learn Swift.

I've been shipping the Objective-C GRMustache in several applications, to generate HTML pages or emails. This is where I could wrap my head around the feature set of the library. The Swift GRMustache has inherited all this experience, and is already pretty rich. But I haven't yet used it in any real application. I hope Swift 2 reveals robust enough :-)

groue commented 9 years ago

Since you're writing a static site generator, you may well have a use for the template caching provided by TemplateRepository: don't miss this class.

njdehoog commented 9 years ago

Thanks for the tip! I will keep that in mind.