In Response to Fabien Potencier: Twig & PHP Templating

This evening I saw that the most excellent programmer, and lead of the the Symfony Framework: Fabien Potencier, had posted a new article on his blog about Templating Engines in PHP, and announcing a new templating engine: Twig

It’s a good article, and I highly recommend that you all go read it. But I took a few exceptions to some of his arguments against PHP as a templating language itself, I think he grossly undersold PHP-as-template in his enthusiasm to promote his new templating language that he created. This blog post is therefore simply a response to that. To that end, I’d like to start off with a few groundrules for my discussion:

  1. Fabien’s ideas, and blog post, are solid.
  2. Twig appears to be a great looking templating language
  3. While I prefer PHP-as-template, I understand why, and when, using a templating language makes sense

So now, what specific points do I take exception to that he made? Lemme run through them each, in order he presented them:

Verbosity of simply echoing a variable

From his blog:

The PHP language is verbose. You need no less than 14 characters just to output a simple variable (and no, using the more compact <?= shortcut is not an option):
<?php echo $var ?>

Therein lies my first complaint. He’s taken away an option that many consider valid. Yes, it’s long been touted that using short tags, specifically the <? ?> version of them in PHP is considered bad practice. In fact, I agree with them on that specific point. But it overlooks a very common practice. Many developers while shunning the <? ?> shortcut for long blocks of code, still love, and use, the <?= ?> shortcut specifically for templates.

Why do they do this? Simply put, it’s extremely simple, and removes the common complaint that Fabien has brought up. In fact, it is so common, start asking developers and you will find many that cry: “They can pry <?= from my cold dead fingers.”. So common, that there are a number of people (including myself), who have been tossing around the idea of proposing a new option to the short_tags directive for PHP, allowing not just having them turned on or off. But allowing a 3rd option, that would enable <?= ?> while disabling <? ?>

When this is done, The PHP output very closely matches the Django that was used as an example:

Original: <?php echo $var ?>
Short Tag: <?= $var ?>
Django: {{ var }}

Verbosity of output escaping

The article then also includes a discussion of how cumbersome it is to escape output in pure PHP, versus in most templating languages. I actually can’t directly disagree with this one, as even using short tags, you end up with the following comparison:

PHP: <?= htmlspecialchars($var, ENT_QUOTES, 'UTF-8') ?>
Django: {{ var|escape }}

The PHP version is ugly. So what am I arguing here? What I’m arguing, is that the complete premise is incorrect here. It shouldn’t matter how complicated it is to escape inside of the templating language, because you shouldn’t be escaping inside of your templating language.

That statement probably just sat wrong on some people. Afterall, the templating language is supposed to make things easy, right? Well, no. Templating languages are about separation of concern. And specifically in their one truly solid use case – allowing non-programmers to edit templates – are about separating the person editing that file, from any of the code.

Why then, would you trust the escaping of output, something that is vital to the safety and security of your website … to a non-coder who won’t understand those implications? The answer is: You shouldn’t. Therefore it is my opinion that you should be handling all escaping as needed before the data gets to your template. That’s the only way to ensure security. In fact, later in the page Fabien admits to this, stating:

For me, security should be enabled by default, especially for templates written by non-developers who are not necessarily aware of the common web threats like XSS or CSRF.

Now where Fabien and I disagree there, is that he believes the solution is just for the templating language to automatically escape everything. I personally dislike this approach, because indiscriminate or inappropriate escaping can cause just as many issues as not escaping in the first place. This is a tricky situation. Not one, IMO, to be left to chance. I therefore greatly prefer having the PHP code itself, handle escaping in appropriate ways. Leave that ‘code’ out of the templates.

Once you’ve taking the escaping out of the template (either via magic escaping or manual), the argument over ugly escaping, disappears.

Legibility of control structures

The argument stays again mostly in the realm of readability, and now turns to more advanced structures. He specifically gives an argument of an example that is very ugly in PHP:

    <?php if ($items): ?>
      <?php foreach ($items as $item): ?>
        * <?php echo $item ?>
      <?php endforeach; ?>
    <?php else: ?>
        No item has been found.
    <?php endif; ?>

PHP is a great toolkit, which means there are always a half dozen ways to do anything. That’s great IMO as far as a templating language because it means that I have different options to make something as legible as possible. No matter what. In the above situation, Fabien has taken what is a small control structure with very little text, and written it in, probably, one of the most ugly ways possible to drive the point home. Quite possibly unintentionally. Most programmers would have written that as something like:

    <?php
        if ($items) {
            foreach ($items as $item) {
                echo "* {$item}\n";
            }
        } else {
            echo "No item has been found.\n";
        }
    ?>

That’s not only much more readable than the original version to a programmer (and one might argue to anyone), but I even find it more legible than the (granted, smaller) version of this that Django provides, because of having an ‘else’ statement that can be applied to a for loop, from Fabien’s example:

    {% for item in items %}
      * {{ item }}
    {% else %}
      No item has been found.
    {% endfor %}

Now I realize that I’ve stated that I found it more legible, and I also talked about how a programmer would rewrite this. I realize at this point, I’m starting to cross paths, since didn’t I just say that the one real use-case of a templating language, was for non-programmers? Well yes, and that’s true. But realize that there are other even simpler ways to have accomplished the above. Such as a common trick of separating storing a $noItemsMessage variable if, in fact, no items existed. Allowing it to just be directly output instead of as part of the overarching if/else.

But really, this now leads directly into the next point:

Complexity of language

Fabien talks then about a number of different points, specifically referring to other templating languages, about how they are not powerful enough in many ways. He goes on to give a good example of the power of Django, showing examples of template inheritance, as a way that it mimics class structure inside of the templates.

This is more a failing of other languages, since you can directly mimic Django’s functionality via the use of a few variables and include files, I’ve done it many times. But overall, I think again we start to miss the point and start to run into the other problem when we start discussing templating langauges.

Discussions of creating inheritance, or complicated foreach w/ else statements, seem somewhat moot to me. Afterall, wasn’t the original goal again to have non-programmers writing these templates? Suddenly these are sounding like a programming language altogether. In fact, they are. It’s the common curse of the templating language. It starts as simple. But as people need to perform more complicated tasks for more complicated templates for more complicated websites, the needs of the templating language grows, and suddenly it’s become it’s own programming language, and becomes too complicated for a non-programmer to use, without learning basic programming skills

This point, is where, in my past, serious discussions have happened within organizations over “So who should really be writing these templates now?”.

So now let’s get down to a hard statement by me. It is my own personal opinion, that if you using a templating language, you shouldn’t be doing anything complicated. That defeats the purpose. If people are going to be learning to write code, they should learn PHP and become helpful. Or the control of the templates should pass into the hands of the programmers. And if the templates are in the hands of the programmers, having PHP as your templating language means nothing new to learn, for anyone.

It’s a vicious cycle, I realize, but I keep coming back to it. In general, you should always keep as much code out of your template as possible. There are always ways to structure data to make the template simpler. If you are taking the bulk of logic out of your template therefore, then having a complex language doesn’t matter. (Though, PHP should meet all your complexity needs that you could ever want anyway)

A valid point

So it appears that I’ve completely picked apart Fabien’s article, but I hope that you don’t see it that way. He makes some good points. There are arguments for using his, or any, templating language. But as I started off saying, he seemed overzealous in coming up with good examples, instead of trying to put them on equal grounds.

There is; however, one extremely valid point that he had. What few templating languges offer you, and PHP definitely doesn’t, is sandboxing. The ability to block the template code from doing certain actions. Accessing data it shouldn’t, calling functions that are inappropriate, etc.

If you are in a situation where you absolutely have to let templates be edited by untrusted sources, and being published unvalidated. (Such as letting users of a website edit templates on the fly) Then yes, you absolutely need to find another option besides PHP-as-template

22 Responses to In Response to Fabien Potencier: Twig & PHP Templating

  1. notjosh says:

    1. short_open_tags are considered to be pretty horrible practice, regardless of how concise they make your code
    2. Fabien didn’t create Twig (and states that quite clearly)

    it looks as though you haven’t completely grasped his notions, or you haven’t done a whole lot of template code (as would be implied by your foreach example – that would be a pain to maintain. it feels like you’re embedding HTML in PHP, instead of the other way around (where HTML is the template))

    and as for escaping, it’s largely that most developers are lazy, and won’t escape properly. in an MVC sense, you could be delivering HTML as well as JSON and XML for the same action (think: REST). the controller only wants to expose variables, it’s the responsibility of the view layer (note: not the template itself) to gracefully handle escaping. he’s on your side that it doesn’t belong in the templates though 😉 (and if you’re ever bored enough, take a look at the output escaping in symonfy – it’s quite transparent, but still flexible enough to grant you the unescaped values if you need it/them)

    that said, PHP can still be a valid templating language. it’s worked fine for me so far 🙂 that won’t change because of Twig 😉

    • Eli says:

      Hey notjosh, Thanks for your reply! In quick response though:

      Yes, I’ve done a lot of templating code. And yes, I personally find that foreach much easier to maintain, than many of the other options that have been presented.

      I did grasp his notions, and they are good notions, I stated that. Yes, Fabien wasn’t the original author, he stated that. But he also stated that he rewrote huge swaths of the code, and it’s now a Sensio Labs project.

      As far as short tags being a ‘pretty horrible practice’, I think you missed my point. You are correct that many experts, authors, speakers, etc all tout the line that short tags are of the devil. Heck, I do it myself. But at the same time, a very large swath of the PHP using populace, while shunning , in fact love and cherish for templating. To the point that some of us have been considering adding a separate language option to enable just it.

      Thanks again for your comment!

  2. zaadjis says:

    I would argue that the view layer is not responsible for “sandboxing”. If one is editing templates on the fly, than this is nothing more than “validation”. But if one doesn’t trust his designers, than he should implement a before commit/deploy hook that tokenizes the php template and validates it..

  3. runish says:

    Wow thx for posting this. I agree with everything you say, and more!

    Short tags are a part of PHP 4,5 and 6. You can turn them off, but that is risky busines if you are using third party libraries and who isn’t. They are here so USE them. I consider having short tag disabled a lot less intrusive than forcing users of your software to use a specific template engine that they might not be able to install on their server.

    I dont care about clashes with “<?xml". The only place that is a problem is in the main view file. All other places I would use ie. SimpleXML anyway. For all intents and purposes having the short tags turned on works great!

    So in the example should be written as:

    *

    No item has been found.

    Pastebin link if code in comment does not work: http://pastebin.com/f64a35054

    Notice you can omit the “;”‘s.

    Short tags make php into an awesome templating language. Use them!!!

  4. […] Eli White has also posted a response to Fabien. | | | | | […]

  5. […] White has responded to Fabien Potencier’s earlier post about templating languages in PHP with some of his own […]

  6. Ben Dunlap says:

    “It’s the common curse of the templating language. It starts as simple. But as people need to perform more complicated tasks…”

    In other words, Greenspun’s Tenth Rule — web edition.

  7. […] In Response to Fabien Potencier: Twig & PHP Templating « Eli’s Ramblings […]

  8. gggeek says:

    About variable escaping: the reason it has to be done by the templating language and not by the coder (either) is exactly the one you mention: it is too vital!
    You can look at it as layer for sending commands to an external system (the browser in this case), and the similarity with sql cannot escape you. Leaving it up to coders to avoid sql injection has historically been a recipe for doom, with the correct approach being usage of bind variables, where it’s the api that does the escaping in a transparent way – they key word here is ‘transparent’, as Fabien correctly pointed out…

  9. […] in PHP Eli White posted a response to a posting by Fabien Potencier about using PHP as a template language versus custom template […]

  10. […] the original here: In Response to Fabien Potencier: Twig & PHP Templating « Eli's … […]

  11. […] In Response to Fabien Potencier: Twig & PHP Templating […]

  12. gaiz says:

    I strongly disagree your quote “you shouldn’t be escaping inside of your templating language.”
    because if user enter incorrect input, page should re-enter the form and escaping is required.

    and “you should be handling all escaping as needed before the data gets to your template.”

    Template engine should handle presentation layer,
    if template use for creating other format (not HTML), it must not escape, right?

  13. […] указал Eli, «Я [Fabien] представляю шаблоны на PHP в таком виде потому […]

  14. […] “In Response to Fabien Potencier: Twig & PHP Templating“, Eli White another PHP Programmer is handling some feedback and discussion related to Twig […]

  15. […] Symfony Nerds, I wrote about Potencier’s ideas about a template engine. I just noticed that Eli White had also written an intelligent reply, well worth […]

  16. Love this article, but I’ve to add something of why we need to use a template engine:

    PHP born as a template engine, but it evolved only the functionality features, infact it’s practically the same for the presentation features, for example as you pointed out, the short tags aren’t configured by default in all servers, also the closing tag ?> eats the new line
    http://brian.moonspot.net/php-history-newline-closing-tag
    again, let’s remember that we are developer and we think different by the designers, the syntax of PHP can be very complex, also it doesn’t exists any official documentation for designers, that’s why for designers it can be easier to learn the smallest documentation of template engines, (exception for the huge Smarty).

    The purpose of template engine is to separate logic (php) from presentation (html), I think the only that really does it is Raintpl, because it’s WYSIWYG, you can write css and img with relative paths, in Smarty, Twig and all the others developers have to check the templates and change the paths any times a designers update them.

    About Twig, IMHO it’s good but, not the best as Potencier advise it, it is kinda slow and heavy, did you toke a look to the number of files and classes involved? 647 KB of files and 405.54 KB in memory, is really a lot for a template engine, considering that a template engine is “just” a script with a couple of regular expressions. My advise is to give a look to this complete benchmark and make up your mind:
    http://phpcomparison.net/

  17. tector says:

    Hat dies auf Tec's Playground rebloggt und kommentierte:
    Add your thoughts here… (optional)

  18. tector says:

    Hat dies auf Tec's Playground rebloggt und kommentierte:
    … nach wie vor ein Streitthema: PHP Template Engines … ich kann beide Seiten verstehen – mich aber keiner 100% anschließen…

Leave a comment