01 May 2019 - by 'Maurits van der Schee'
In a previous post I have introduced PHP templating in 165 lines of code with no dependencies. I have added several features since it's initial release and the line count has roughly doubled. This post gives you an overview of the added functionality and explains how to use it.
Conditionals are an essential construct in a template. When you implement them without 'else' or 'elseif' you get either a lot of repeated conditions and unnecessary nesting.
Published: {{if:post.published}}yes{{else}}no{{endif}}
You may also use the 'elseif' statement:
Frequency:
{{if:post.frequency|eq(1)}}
daily
{{elseif:post.frequency|eq(7)}}
weekly
{{else}}
every {{post.frequency}} days
{{endif}}
Note that the 'else' statement is not required.
While it may be very useful to loop over the elements of an array, you sometimes have a associative array (or hashmap) and want to loop over the keys. This was the 'for' syntax:
Roles:
{{for:role:roles}}
{{role}}
{{endfor}}
Now you may also use this alternative 'for' syntax:
Properties:
{{for:val:key:properties}}
{{key}}={{val}}
{{endfor}}
As you can see this alternative form of 'for' statement is detected/determined by the number of parameters of the statement.
Values that are inserted in the template may contain JavaScript and thus open up a XSS vulnerability (which can be used for session stealing and such). To avoid XSS, all values that are replaced in the template are escaped. This can be turned off in case you are generating plain text. This means that:
<a href="{{url}}">click here</a>
can be used without worrying that a user will insert an 'onclick' event by letting the variable 'url' contain a closing quote that is interpreted as such.
Since we are now using a string-aware split function (see: Split while respecting quotes in PHP) you do not have to worry that characters between quotes have effects on higher level split operations. This means that you can write:
{{date|formatDate("M j, Y")}}
without having to worry that the comma is the argument separator for the 'formatDate' function (and you can use the pipe character in the string).
The Template class has grown a bit (to 320 lines) and gained some valuable features. It's parsing strategy is not the fastest, but it will do for small to medium size templates. There are still no dependencies and it should be easily portable to other languages. You find the source code on Github:
https://github.com/mintyphp/core/blob/master/src/Template.php
and the tests:
https://github.com/mintyphp/core/blob/master/src/Tests/TemplateTest.php
Enjoy!
PS: Liked this article? Please share it on Facebook, Twitter or LinkedIn.