New TwigView Plugin
CakePHP ships with PHP based templates, and while this works for many people we’ve also recently re-launched the Twig plugin. For that past several years Wyrihaximus has maintained the excellent TwigView plugin. The CakePHP core team has joined forces with Wyrihaximus and taken over completing the 4.0 upgrade and polishing up parts.
Why use Twig?
Before we look at how you would use the TwigView plugin, it is good to step back and look at why you might want to use Twig at all. As mentioned earlier many people think of PHP as great for templating but there are some problems:
1. PHP syntax is verbose and hard to read when you have nested control structures.
2. PHP doesn’t include automatic HTML escaping. This means you need to be very vigilant about not accidentally introducing XSS vectors.
As an example of how PHP syntax and Twig differ take the following PHP code:
- <ul>
- <?php foreach ($users as $user) { ?>
- <?php if ($user->avatar) { ?>
- <li>
- <img src="<?= $user->avatar->url ?>" alt="<?= $user->username ?>" />
- <?= $user->username ?>
- </li>
- <?php } ?>
- <?php } ?>
- </ul>
You could make the template a bit more readable by using the endforeach
syntax, the above code doesn’t include and HTML escaping. Adding that will add more function calls and syntax to wade through. The same logic in Twig including HTML escaping would look like:
- <ul>
- {% for user in users %}
- {% if user.avatar %}
- <li>
- <img src="{{ user.avatar.url }}" alt="{{ user.username }}" />
- {{ user.username }}
- </li>
- {% endif %}
- {% endfor %}
- </ul>
I find the twig version much easier to read, and you have zero chance of accidentally introducing a XSS vector.
Recent Improvements
Wyrihaximus has done an amazing job maintaining TwigView for many years, and we’re happy to help carry the project forward and add a few improvements along the way. Some of the new features include:
- Being able to use
fetch('blockname')
as a function. - Being able to use
cell()
andelement()
as functions instead of tags. This enables the output of these functions to be used more easily.
My favorite new feature is a new syntax for helpers that doesn’t require using |raw
. Previously you would call helpers like:
- {{ Html.link('Login', {_name: 'login'})|raw }}
The |raw
always bothered me, as it made using raw
common place when it should only be used in exceptional cases. Now you can use:
You can use this style of function call for any helper loaded in your View without having to write additional Twig extensions. Your helpers will need to continue applying HTML escaping like before though.
You can start using the cakephp/twig-view in your 4.x applications today. I feel it is production ready and am running it in production myself.
I wouldn’t put the PHP code above in such an example. It should always have the h() part included IMO – even in such examples:
<?= h($user->username) ?>
To avoid XSS – especially when people see these examples and just copy/paste the idea/code.
And here even more so, as you want to compare those two, so having the PHP code being equal to the auto escaped twig one makes much sense to me.
In other words: The PHP code must never exist without the escaping in place :)
Personally, I still only use Twig when generating PHP code (as generating PHP from PHP is hell). Otherwise, I am usually quite fine using PHP itself as a glorified templating engine ;)
Even though it is surely true, that the templates would be a bit cleaner using Twig here (as you are forced to offload more logic to helpers and alike).
Mark on 4/28/20