groue / GRMustache.swift

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

Swift 3 Support #32

Closed mikecsh closed 7 years ago

mikecsh commented 7 years ago

Hello and thanks for a great library!

Are there any plans to upgrade GRMustache.swift for swift 3 syntax?

groue commented 7 years ago

Hello @mikecsh. Oops, I'm late. Please hold on.

groue commented 7 years ago

@mikecsh It's a work in progress!

tfsjohan commented 7 years ago

Would you say Swift 3 support is days, weeks or months away to be done?

groue commented 7 years ago

@tfsjohan It should be days.

tfsjohan commented 7 years ago

Super! Thanks for the quick reply.

bastianh commented 7 years ago

I'm trying the Swift3 branch in our app and it looks like everything works .. but we are only using it with one small template currently.

Let me know if we can help with testing or stuff like that.

groue commented 7 years ago

Thanks @bastianh for your support. It is not recommended to use the Swift3 branch in its current state.

Not only did I not try to make it work, but I'm also tweaking the inner guts in ways that may break stuff. The test suite does not compile yet - talk about passing tests...

The remaining work is about relationships with Foundation, the new Collection protocols, tests, and documentation updates.

mikecsh commented 7 years ago

Great news @groue - happy to help test if you need, this is a really useful project!

groue commented 7 years ago

Thanks! I'm not tweaking for the pleasure of tweaking. Yet Swift 2 used to automatically convert object to and from NSArray and NSDictionary, and this was very handy for Mustache rendering. This is gone with SE-0072. This means that ["name": "Arthur", "age": 42] is no longer easily boxable and rendered. I've got to find my way through this.

rasmk commented 7 years ago

@groue, I do not know what boxing problems you experience. Perhaps it's the same kind I had. I am posting in hope to help.

In the meantime I switched to Zewo/Mustache, which is said to be a fork of your repo, ported to Swift 3. It was not a smooth switch though. I needed to tweak a lot there to make it work.

One of the issues I faced was, my passing boxables into the library did not work anymore. In the end I changed public func Box<T: MustacheBoxable>(dictionary: [String: T]?) -> MustacheBox { to public func Box(dictionary: [String: MustacheBoxable]?) -> MustacheBox { in Box.swift and it started working like a charm.

Looks like generic signatures are used in Box functions only and do not descend any deeper into the framework.

I use dictionaries to pass the data to the template, so this change was sufficient for me. It would be much more work to apply the change in a consistent way. But perhaps giving up generics and using plain MustacheBoxables could help. If it does not, please ignore my post.

tfsjohan commented 7 years ago

I've used the MustacheBoxable protocol a lot to keep classes "Swifty" and avoid NSObject subclassing. For me it wouldn't be a problem if this would be a requirement, but I'm not sure it this affect how array or dictionary type properties would be handled.

groue commented 7 years ago

@rasmk, @tfsjohan Yes, the trouble is not really with boxable types: it is with collections (arrays, sets, and dictionaries). It's a rather mechanical job, actually. I've written as many tests as I could, and now it's a matter of keeping only the ones the Swift 3 can compile, and having them pass :-)

(note to myself: add tests for [AnyHashable: Any])

tfsjohan commented 7 years ago

Would you say the 3.0 branch is ready to use?

groue commented 7 years ago

@tfsjohan It is now, but it may evolve a bit regarding the boxing of collections: some Box(array) and Box(dictionary) may stop compiling, and some unsupported Box(array) and Box(dictionary) may become supported.

The rest should be just OK.

tfsjohan commented 7 years ago

Nice! Would you say that it's preferred to use Box(dictionary) over just a dictionary? Or is the other way around?

groue commented 7 years ago

@tfsjohan GRMustache templates are fed with boxed values. See documentation.

lroseblade commented 7 years ago

Hi @groue, if the swift 3 branch is largely working would it be worth tagging it in a release so it can be included in SPM Package.swift? I'm looking to update our tutorial here: http://www.kitura.io/en/resources/tutorials/templating.html with a fully working GRMustache template

groue commented 7 years ago

Hello @lroseblade,

It is working, but a proper tagged release needs a final touch in the collection boxing, and an updated documentation. I'm late, I admit, since GRDB eats a lot of my spare time.

But I have a question: doesn't Kitura use a specific GRMustache fork, because of the complicated relationship between Linux and Foundation? Until now, GRMustache has provided as much support as possible for Foundation, so that iOS/macOS developers don't have to "pay" for the limitations of Swift on Linux. Is it still relevant? Do you think it's now possible to unify our code bases, without sacrificing anything?

lroseblade commented 7 years ago

We don't fork, we pull in your package directly and then apply a wrapper around it. As GRMustache doesn't support Linux presently we have a platform check before pulling in the package and mark it Darwin only in the tutorial for now.

Regarding Swift Foundation on Linux, it has taken a big leap forward in 9 months and I've had a small team in India contributing to it since January (we got committer status two weeks ago woot) - if you're finding Swift Foundation issues then post them to the corelibs foundation mailing list and we might be able to help.

groue commented 7 years ago

[The Swift3 branch] is working, but a proper tagged release needs a final touch in the collection boxing, and an updated documentation.

The final touch for collection boxing is done. Basically one can box Set, [Any?], [AnyHashable: Any?], NSArray and NSDictionary. Recursive collections are supported (arrays of dictionaries of arrays etc.)

The difference with Swift 2 is that support for Collection, BidirectionalCollection, etc. is lost: one has to turn those types into concrete Set and Arrays before boxing: Box(1...10) won't compile, but Box(Array(1...10)) does.

Now I need to update the documentation.

matt-curtis commented 7 years ago

Awesome, @groue, thank you for the (seemingly!) tireless hard work. It's much appreciated :)

groue commented 7 years ago

Thanks to all of you for your patience: version 2.0.0 is out!

The main new feature is that the Box() function is no longer necessary:

// Templates eat raw data:
let rendering = try template.render(["name": "Arthur"])
let rendering = try template.render(Profile(name: "Arthur"))

The main breaking change, beyond the renaming of a few methods according to the Swift 3 design guidelines, is that the only supported collections are arrays, sets and dictionaries. Support for Range and other "exotic" Swift collections has been dropped.

Check the changelog for more information.

@lroseblade: the library still supports SPM, but I could only test it on macOS. Any help or suggestion for making sure GRMustache works well with Kitura would be welcome.

groue commented 7 years ago

@lroseblade : I could have Kitura run and render Mustache templates: https://github.com/groue/GRMustacheKituraDemo.

It had me fork IBM-Swift/Kitura-MustacheTemplateEngine so that it uses groue/GRMustache.swift 2.0.0 instead of IBM-Swift/GRMustache.swift 1.3.

Do you recommend that I open a pull request on IBM-Swift/Kitura-MustacheTemplateEngine?

lroseblade commented 7 years ago

Nice work @groue!

Yes, please raise the PR to change the Package.swift dependency and I'll see about getting it merged.