Recently I went to Luke Welling’s presentation entitled “PHP in the 21½th Century” at OSCON. He mentioned something interesting that got me thinking, something he calls “The Smarty Trap”. This trap occurs when someone decides to write a template engine with “a simple syntax that designers can understand” – it starts with some includes and printing a variable here and there. All goes well until he realizes he needs looping, so he builds loops into the language. And so it continues until the template engine is as complicated as any other programming language.
This is probably the most common argument against template engines. People often say “but PHP IS a template engine”. Proponents of template engines will then counter argue that the syntax is simpler, but in some cases this is just not true…
We use Smarty in one of our products and in retrospect, we would most likely not have chosen to use it if we had to do it all again. However, based on our requirements and design decisions at the time, it was probably the right choice for then. When we started out, we opted for a MVC architecture where controllers pull data from models and push the data as arrays to the view. The advantage of this approach is that it keeps the templates simple because you’re only ever printing the contents of variables and occasionally looping over a dataset.
As our product evolved and became more complicated, this process became tedious and inefficient. Objects had to be converted to arrays and passed to the view. Sometimes this included a hierarchy of child objects. Then we started implementing lazy loading and iterators, the benefit of which quickly evaporated when we converted all of our objects to arrays.
We decided to instead pass either the model objects to the view or to use view helpers. The view then calls methods on the model or loops over the iterator, preserving the original objects and any lazy loading. All was well again, but of course the views started getting more and more complicated. To refer back to the argument, our templates have now become as complicated as embedded PHP code in HTML would have been. Add of course the additional overhead of the template engine and the cost of learning yet another language and suddenly a template engine doesn’t make an awful lot of sense anymore.
The problem is that requirements, design decisions and technologies all shift and evolve over time. It is not possible to predict where your product will be in 2 years, 5 years or even a few months from now. As software engineers, we try to accommodate change as much as possible by building safeguards into our code. However, at the end of the day, we cannot predict the future so we have to make peace with the fact that continuous re-factoring is as much a fact of life as change itself.