First of all, if you don’t know, the Leaf 4 release contains some major syntactical changes compared to the previous version. Curly brackets were replaced with the new
#end prefix syntax.
This is a major step forward, but also a breaking change, that means you have to upgrade your currently existing Leaf 3 codebase, otherwise your templates won’t work. The other major change is related to template inheritance. The new
import keywords replaced the previous
set keywords, again.
So correct me if I’m wrong, but this improvement is like taking a step backward, because in Leaf 2, we had more or less the same template inheritance API functions (import, export, extend, and embed). I suppose that this change can be confusing for some people who were already familiar with the 2nd or the 3rd version of Leaf. (I was surprised when I saw these changes.) 😐
I don’t want to criticize this decision, but these changes don’t necessary deserve a major version number. It’s not a big improvement from a developer (end-user) perspective. The only thing what changed with Leaf 4.0.0 is that we developers have to change our codebase to make things work again, but we’ve gained almost zero new features, that I’d expect from a major release.
I was very sad about this and I can imagine that this can make server side Swift developers quite upset. I’ve already missed quite a lot of features from Leaf, that I’d expect from a modern template engine. Just take a look at mustache or handlebars, they are of course older, but it’s worth to mention that they have some way more advanced features, that you still can’t do in Leaf. 😢
Now, in the middle of the 4.0.0 development an interesting thing happened with Leaf…
There was a new branch called Tau (means rebirth) created and maintained by @tdotclare. I jumped the train and started to use this experimental branch instead of the main / dev.
We also started to talk quite a lot with tdotclare, since there were some issues, especially in the beginning, but finally I’ve found someone on Vapor’s discord who I could ask about Leaf. He helped me a lot and I’m extremely grateful, because without him, the template layer of Feather CMS wouldn’t be such an amazing (modular, reusable, extensible) system. 🙏
Long story short, tdotclare implemented lots of great new features for Leaf Tau, the whole system started to look like as a real template engine, not just something that you could use to replace key-based variables in a very long output string. (Pardon me, but this is the case with Leaf.) 🙈
We had a vision about the future of Tau, where you could differentiate types, create new language elements and specific extensions (functions, methods, blocks, contexts) for the task you need to solve, in a safe and easy way. Tau already has all these goodies and even more.
You can define variables and constants, and the new template hierarchy system seems to be more logical and future proof than any other previous variants of the template inheritance APIs. Finally, after countless hours of conversations, feedbacks, testing, and bug squashing, the Tau features were merged to the main branch and released under the 4.0.0-tau.1 tag.
If you want to keep using Tau, you should pin your Swift dependency versions to:
.package(url: "https://github.com/vapor/leaf", .exact("4.0.0-tau.1")),
.package(url: "https://github.com/vapor/leaf-kit", .exact("1.0.0-tau.1.1")),
Unfortunately, the Vapor core team decided to revert these changes shortly after the Tau release without a detailed explanation. As far as I know the main reason was that the core team wants to keep Leaf as a “simple” template engine. Don’t get me wrong, I’m fine with that decision, but then it was definitely a mistake to officially release Tau and shortly after remove it just like that. 😕
So here’s what I was thinking about this entire topic in the last few months.
I’ve always felt like these new Tau features are way too good to simply drop them, just to go with Leaf. Plus what does the term “simple” means? Can I expect anything new in Leaf or is it going to be only bug fixes only from now on? Is the future bright for Leaf or should I simply drop it? 💧
Well, yes. I’m not going to use Leaf again.
If you are planning to build a new project and you need a reliable, fast, dynamic template engine with a just very basic (limited) feature set, then you should consider using Leaf. 🍃
Domain Specific Languages
Nowadays everyone is into DSL’s (SwiftUI), so why not use a DSL library, such as HTMLKit or Plot instead of Leaf? If the template engine won’t allow me to do more in the future then a DSL would be a way better choice. It could be more safe and performant, but of course we’d sacrifice the dynamic nature (you always have to recompile the entire server code after something changes), but still, based on the circumstances, I can only think of this solution as a better alternative.
If you don’t want to dynamically update templates and you’re fine with the “static site generator” approach, then I’d suggest to use a Domain Specific Language based template engine.
It is a dynamic template engine with a very rich feature set, that you can use to build more complex templates. Since Tau is derived from Leaf it means that the syntax is very similar, so the official Leaf documentation covers pretty much everything that you have to know about it, plus I already have some nice tutorials on my site about using the new features of Tau.
Based on my experience, I’m going to stick with “Tau”.
It is worth to mention that Tau will be re-released later on in a separate repository under a brand new name. Sadly, I can’t give an exact schedule for the transition process just yet. Hopefully this way we can avoid further confusions and developers can pick the right tool for the job.
The Vapor core team and the authors of Leaf are doing an amazing job. This post is not intended to harm them in any way, but I just wanted to provide some real explanation for everyone who was asking me about the current status of Leaf and Tau. Thanks for understanding this. 🙏