Twig, the next generation template engine for PHP
I've been using Smarty 2 for about 7 years, and, while Smarty 3 is still in beta, Twig just popped up in the scene. Notable Smarty opposer Fabien Potencier was apparently converted by this template engine, so Twig must either be magic, or excellent, or both.
One of the major drawbacks of Smarty is that it is bloated (think of all those "internal functions" next to the two walruses of classes), renders fairly unreadable source code and is not that well extensible. Some of the syntax choices in smarty aren't that practical either... How many times have you typed {foreach $items as $value}
in a Smarty template? I have about a gazillion times. And who the H thought of that abominable {section ...}
thing?).
Of course, I also need to point out that it is actually quite fast, it makes for an excellent alternative to writing templates in pure PHP, and there has never been any template engine nearly as simple and at the same time powerful as Smarty. Not to mention the fact that it was actually the first one to come with a compiler paradigm. Well, I have used it for such a long time, I think that counts as enough defence.
Ever since PHP is evolving more and more into an object-oriented language, and even more so, the community is gaining more and more good developers, there was bound to be someone to say: "Smarties are for children, real men just gnaw on wood". So Twig is born. And a prodigy it is.
The set-up is very straight forward. A solid compiler, with great extensibility. You can hook into the compiler's syntax tree with your custom nodes, change the syntax by defining delimiters, easily read the generated code, and redesign every part of the engine because of it's design-by-contract implementation.
Here are some pointers if you're used to smarty:
Default delimiters, the $ sign and data types
Default, Twig uses {{ var }}
delimiting for variable output, and {% ... %}
for control structures. The dollar sign is a goner, so get used to that. There is no difference between an array and an object, so you can write {{ var.property }}
for both arrays and objects. A slight difference is that in case var is an object, Twig also checks if the var has a getter for the property in either form property()
or getProperty()
.
For-loops and sections
foreach is called for
, and sections need to be rewritten to for-loops as well.
#!twig
{% for key, value in items %}
{{ key }} contains {{ value }}
{% endfor %}
Special context-sensitive variables are available in the loop
variable.
modifiers and functions
Twig supports Smarty-style modifiers, though parameters are passed within parentheses: {{ var|modify("with argument") }}
. Functions are supported as well, and can be implemented by writing extensions to the compiler.
Cool stuff that smarty doesn't do
- Template inheritance. Define a layout in one and populate the blocks in another template.
- Macro's, which are tiny pieces of template code, reusable as a function in the rest of the template. You can store macro's in external templates, and import them for reuse.
- Access a parent context reference, which enable you to identify for example which
loop
variable you want to access in a nested loop, the inner or the outer one. - A generic expression parser, which enables you to set and define complex expressions wherever an expression is allowed
And probably I'm leaving out a whole bunch of other nice features. Read more about it in the Twig documentation, and get inspired.
I hope a 1.0 version will see the daylight soon. I think it is a very welcome attribution to the community, so let's thank Armin Ronacher for kick-starting Twig, and Fabien for his conversion to the one true faith: PHP is no longer just a template engine. ;)
PS: If the first question that comes to mind is Why use a template engine if you're already using PHP, never mind. There are plenty valid points to use a separate template engine. There a plenty valid points against it too. I don't really care. Smarty has done the job outstandingly, and as long as the deemed successor compiles into PHP code, I'm happy.