Nerds who love the symfony-project
25 Oct
Fabien Potencier has stirred up a storm with his post about template systems. If you’ve got time, you might want to read the whole thing, plus all the comments at the end, many of which are well written. If you are short on time, I’m going to here summarize what I think are some of the best points.
It’s worth noting that Potencier is introducing a new PHP template system, called Twig, which will be natively supported in Symfony 2.0. So as you read his criticism of other template engines, understand that he’s explaining why he thinks his new system is best.
For me, the big suprise was to realize how much Potencier dislikes PHP. He is, after all, the lead programmer of Symfony, and Symfony, more than any other framework, aims to give the world the kind of strict MVC framework that will allow the corporate world to take PHP seriously. And, as far as I know, Symfony is the only PHP framework that has been used to build really big sites, like Yahoo Bookmarks and DailyMotion. Potencier seems to be one of the many programmers who admire the cleaness of Python relative to PHP. In his critique, he compares several PHP template engines to the Python-powered Django, and in every case he regards Django as superior:
I will take Django as an example of a modern template language in my examples for reasons you will understand later on, and mainly because I think Django template language hits that sweet spot I talked about above.
The Symfony project has seen this kind of Python-envy before. The first version of Symfony used Propel as its exclusive ORM, and Propel, in turn, relied upon Creole. But the lead programmer of Creole (Hans Lellelid) eventually gave it up and switched to Python, and, on his way out, he denounced PHP:
On more of a rant/stream-of-thought note, I wonder if PHP is ready for the next generation of web applications. It worked great for creating HTML templates, but are people building new applications today really using PHP to generate HTML? Maybe they are, but everything seems to be moving to a model where the backend is just a services layer. PHP doesn’t offer any advantages over other languages when it comes to a simple web services layer; heck, Java even starts to look easy if all I’m doing is writing a JSON-RPC server that talks to a database. The multiple-page model for serving requests no longer makes sense; instead you have some sort of front controller — so now you’re using a framework. And all of these languages have frameworks, but languages like Java and Python not only have web frameworks but have framework API standards. They’ve been thinking about this for a lot longer, and it shows. So I think that PHP as a solution needs to evolve at the engine level (with things like namespaces + built-in phar, etc.) AND it needs to evolve at the community level (with new standards and framework specifications). I’m not sure either type of evolution is really compatible with PHP’s democracy-driven development model.
Potencier criticizes 5 main things about PHP as a template language:
1.) A lack of concision
2.) A lack of a template oriented syntax
3.) A lack of reusability
4.) A lack of security
5.) A lack of a sandbox mode (a mode where untrusted users are free to write, unable to do harm)
Of concision, he offers this:
PHP becomes ridiculously verbose when it comes to output escaping (and yes, escaping variables coming from an unsafe source is mandatory nowadays):
<?php echo htmlspecialchars($var, ENT_QUOTES, ‘UTF-8′) ?>
Compare with the same examples written with the Django template language:
{{ var|escape }}
Of a template oriented syntax, he offers this contrast of PHP and Django:
<?php if ($items): ?>
<?php foreach ($items as $item): ?>
* <?php echo $item ?>
<?php endforeach; ?>
<?php else: ?>
No item has been found.
<?php endif; ?>The Django version is much better thanks to the use of an else clause for the for tag:
{% for item in items %}
* {{ item }}
{% else %}
No item has been found.
{% endfor %}
About reusability, he says he is looking forward to having ‘traits’ in PHP. See my last post for more about that.
Potencier seems to like the Smarty template system, but he mentions that it has terrible performance. He also lists these flaws:
* Not object oriented
* No template inheritance
* No sandbox mode
* No automatic escaping
His criticism of PHPTAL:
PHPTAL is a very nice project that implements the Zope Page Templates syntax. It is very well designed, supports lots of features, but is unable to render templates besides HTML ones, which can be a problem if you want to use the same language for emails, RSS feeds, and so on. Also, I think the syntax is not web designer friendly, especially when you use advanced features like template inheritance:
Of Calypso:
Calypso is an implementation of the Django Template Language in PHP….But, the author himself acknowledge that the implementation is flawed.
Indeed, the author of Calypso writes:
I have tested Calypso performance some weeks ago and have not been able to write on it before. Don’t use it please its fucking slow and cannot be optimized in the current architecture, because the template will NOT be parsed into intermediate PHP code. …Triple or higher inheritence may not work under some circumstances. Which sucks. I sadly have no time currently to fix any of the issues poping up with Calypso, so please don’t use it for anything production.
Once you understand how much Potencier admires Django/Python, you can understand where he is coming from when he introduces Twig:
When I started looking for a PHP template language, I focused on libraries trying to mimic the Django template language features. After many hours of Googling, I found Twig. Twig was written by Armin Ronacher of Jinja fame. Needless to say I have the uttermost respect for Armin as he does a wonderful job with Jinja.
He wrote Twig back in 2008 for Chypr, a blogging platform. But he never really developed it further as he mostly work with Python.
When I had a look at the code, I was immediately sure it was what I was looking for. The main difference with Calypso being the fact that Twig compiles the templates down to plain PHP code. I started to use it a bit and at the end of last week, I asked Armin if he wouldn’t mind letting the project starts a new life. His answer was enthusiastic, and so I began hacking the code. My version is much different from that of Armin, but the lexer and parser are mostly the original ones.
So, for Twig, Potencier lists these advantages:
Native template inheritance (templates are compiled as classes);
Solid automatic auto-escaping (with no associated runtime overhead as everything is done during compilation);
Very secure sandbox mode (white-list the tags, filters, and methods that can be used in templates);
Great extensibility: you override everything, even the core features, by bundling your own tags and filters as an extension; but you can also manipulate the AST (Abstract Syntax Tree) before compilation. By leveraging this possibilities, you can even create your own DSL (Domain Specific Language), targeted at your application.
In the comments, Vincent Cogne makes a point that I agree with, about the need of designers to be able to read the templates:
When working with a graphic team in charge of the integration of the website’s pages you must have a template system easy to use for a non-coder person. I think flow control and loops are to complicated in the template engines listed in this article. Designers don’t have to know the use of FOR AS structures. phpBB template Engine uses BEGIN/END key words which I found more handy.
I’ve found that if the designers can not work on the templates, then what you get in the end is a mediocre experience for the end user. There are a thousand small issues of usability that the designer tends to test and refine as they iterate a design - a process which becomes impossible if the designer has to wait on the programmer to make a change to the template. (This issue is important for content websites, but it is even more important for software/GUI issues.)
In response, Alex Farran makes a good point:
@vincent @Dominic I think your two comments sum up why template languages are such a difficult compromise. To keep it understandable to non-developers you have to restrict it to a very limited set of control structures. Too limited to be of much practical use. So you add features that turn it into a small programming language. Now your developers complain that they have to learn another language that doesn’t offer many advantages over PHP, and several disadvantages.
WishCow repeats the point about designers needing to edit the templates:
I’m completely against the “designers don’t have to know about foreach and stuff” mentality. They should totally know about it. It is a very simple, and easy to understand concept. Saying that one engine’s way of doing a foreach is nicer for a designer, is not reason enough.
I agree with this strongly. I’ve had the luck to work with some truly great designers. They usually have no problem learning enough PHP to read the templates. They are smart, and they need to have control over every graphical property of the GUI.
Miles Johnson offered strong criticism of the very idea of a template engine:
I in all honestly think template engines are garbage. I hate the fact that you have to basically “learn” a new language and syntax that can be easily written out as PHP. Secondly it will be slower then using regular PHP because it will have tons of parsing and possible regex to process. Thirdly its lack of support for the most basic of tasks, like not being able to use all of PHPs built in functions, is a total pain.
Chris.R says he would stop using Symfony if the new template engine were mandatory (but Potencier later insisted that Twig would never be mandatory):
If Symfony 2.0 forces the use of a template engine I will be back to looking for a framework, I know I am not going to change the symfony developers mind by making this statement, but you asked for feedback and here it is.
In response to some of the fears and concerns expressed in the comments of his first post, Potencier posted again, with some reassuring words about the value of pure-PHP templates:
Before I try to answer some questions, I’d like to re-state that I like PHP templates. And you should remember that symfony has only used plain old PHP templates since the beginning. As a matter of fact, I’m been advocating about using PHP templates since my first PHP project, and I have never used any other PHP template engines. So, I’m not against PHP templates; I just find that some PHP limitations as a template language are more and more irritating for me.
He also mentions a new Symfony template component that I knew nothing about:
If you are looking for a templating engine that only uses PHP and have built-in support for template inheritance, blocks, helpers, and some more, the good news is that I have coded one some weeks ago under the Symfony Templating Component name. It’s a standalone component, which has no other dependencies, and I’m sure most people wanting to use plain PHP for their projects will love this project.
It is hard to keep up with everything going on the world of Symfony. The new template component describes itself thus:
The Symfony Templating component provides all the tools needed to build any kind of template system. The Symfony Templating component is a thin and flexible layer on top of PHP that provides simple but powerful features, covering most templating common needs.
At first it seems confusing that Potencier is introducing 2 new template systems at the same time. However, I believe the goals are different: one uses pure PHP and one does not. And, if I’m not mistaken, everything over at components.symfony-project.org is meant to be refactorization of the technologies in Symfony, in particular, Symfony 2.0. So the new Symfony template component is probably the template module being de-coupled from the rest of the Symfony framework. (In the world of Symfony, there will never be a Merb rebellion, like there was in the Rails community, because the core Symfony team are their own Merb rebellion.)
Potencier tries to explain his motivations, again:
One of the key point of my reasoning is that a good template language should aim to find the sweet spot. The template language should find the best compromise about too many and not enough features. As I said in my previous post, the template language is all about presentation logic. And of course, simple conditions and loops are part of the presentation logic. But do you want to use array_chunk() in a template? Probably not. This call belongs to the controller or the model, depending on what you want to do.
A surprisingly intense argument opened up about how to handle output escaping. Potencier said:
Some commenters advocate that output escaping should be done in the controllers. That cannot work. As John Campbell writes: “The problem is that the controller can’t possibly be aware of the context of the output, nor understand which type of escaping is correct.” The issue is therefore not that simple. On the one hand, developers should take care of output escaping, but it cannot be done in controllers. On the other hand, web designers should not have to take care about output escaping, but templates is the only place where you have enough context information to apply sensible escaping. That’s why automatic output escaping seems the best compromise to me, plus the fact that being “almost” secure by default is a big advantage.
Several people wrote in the comments to suggest that output escaping does not belong in the templates, and should instead be handled in the model. Pádraic Brady wrote a reply to that argument:
The obvious problem with escaping for a View within a Model. The Model knows exactly nothing about the View. Why should it?
The Model is a representation of state, and the domain logic which acts upon that state. Whether an external actor wants to stick that state into HTML, XML, JSON, CSV, PHP, or any other format is its business. Therefore, only such an external actor actually knows the correct means of escaping the data it received from the Model, whether it is a Controller, or the View itself.
Unless, of course, you make the Model aware of the View. In which case, congratulations, you just broke one of the primary separations contained in MVC (check a UML diagram - the little arrow in the line connecting the View to the Model is a one way association).
Developers should note that “automatic escaping” within Views has been around for a long long time as a form of Poka-Yoke safe guarding. It’s about time PHP developers figured that out. Kudos to Fabien, it’s been part of Symfony for a long time now. I don’t completely buy the performance problems (I use it here custom implemented into Zend_View with no measurable performance hit), so nobody should be afraid to look into the implementation possibilities.
Such a debate opens my eyes to the range of template styles that are already in use in Symfony projects - there are well over a 100 comments on the 2 posts, with many Symfony developers expressing strong opinions about the various options.
For my part, I’ve always been an advocate of pure-PHP templates, and their use was one feature that I liked about Symfony. As for Twig, the only feature it has that I can ever imagine needing is the sandboxing, and then only if I’m asked to build the kind of site where random, untrusted users are allowed to create their own templates (perhaps an online social network where users are allowed to customize the look of their own profile pages).
But damn, it is impressive the way the Symfony team keeps coming out with interesting technologies.
8 Responses for "What would the ideal template system be for Symfony?"
Thank you for the excellent summary!
+1, very good read. and gave me a lot to think about
Great article, just thought i’d throw in my thoughts.
My main work involves creating applications for designers who need to be able to understand the templates. For my projects i have made the phpBB template class standalone as this is perfect for designers.
Its not that powerful although you can do some pretty nice things with it but overall for ease of use for a designer it the best in my opinion.
There are a couple of things that i would like to see in it(such as namespaces to global template variables clashing) but other than that it is great.
Here is a link to my article on how to make it standalone:
http://www.phpbb.com/community/viewtopic.php?f=71&t=1557455
Now how would we get this into symfony.
Veganista, in your article you write:
“After about a year of putting it off i finally decided i would take the plunge and try and get it to work standalone. After doing it, it took about 30 minutes, im really annoyed i didnt do it earlier. Here is how to do it, it should take you about 10 minutes.”
It sounds like this could be turned into a Symfony plugin with some ease. Then you’d need to have the plugin override the default template system of Symfony. I have not looked to see what classes are involved, though I imagine this is the kind of task you could do in a single day. And with all the refactoring that Potencier is doing, it will clearly get easier and easier to swap out the default Symfony view code, and replace it with whatever you want. No doubt when 2.0 comes out, and when Twig is officially introduced as part of Symfony, there will be a lot of debate about what would constitute the ideal template system for Symfony. This is a debate that is only now beginning, and will likely last a long time. And no doubt each development team, with its own style, will prefer different systems of allowing the designers to interact with the code.
[...] I’ve a new post up at Symfony Nerds. Fabien Potencier, the lead developer on Symfony, has recently introduced 2 new components related to templates in Symfony, including Twig, a template engine that will be introduced in Symfony 2.0. I try to offer an overview of the whole debate around these developments. [...]
good summary.
There is just one thing I would like to add: Fabien doesn’t especially like django or python. He likes any good code. To find good code he does not restrict himself to any programming language. I admire that.
And to be fair: PHP is indeed pretty flawed. PHP community is working hard to fix it, but other languages had just a better start.
To be fair, I think PHP is a fairly mangled language. There is the inconsistent use of underscores in function names:
str_replace()
stristr()
And inconsistent rules about when a variable is being transformed inside of a function:
reset($array)
which does not return.
PHP was successful at a young age, which imposes a certain awkwardness. I think Ruby and Groovy and several other languages are more elegant. But nothing is as simple to get going on a web server as PHP. It had that great advantage in 1999, and it remains a strong point even now, despite stuff like Phusion for Rails.
One reason that I am excited about Symfony is it is a big step toward bringing best practices to the world of PHP, a world that is notorious for worst practices.
Perhaps fabpot should have had a look at genshi (edgewall.org). Or perhaps he did have a look at it, since most of what I have seen in the examples, somehow reminds me of the approach that edgewall with their genshi templating system for python has gone. The latter though is implemented using web standards such as xml, xpath and so on.
Leave a reply