📜 ⬆️ ⬇️

Template engines for PHP, a review of the principles.

Such articles usually have a bad fate on Habré.
“Template engines”, especially “template engines for PHP” - by meeting these words in the title of a topic on a forum, the title of an article or a blog entry, you can be sure that the next holivar is somewhere nearby. What is the reason?

  1. Selection There are not many templates for PHP, but many of them. Some are implemented in native PHP code, others in C extensions. Many of them differ from each other only in trifles or statistical parameters (caching is / no, processing time, execution time, etc.), many are lightweight analogues of already known template engines, some of them are optimized versions.
  2. Different principles of work . At the heart of the most famous template engines are completely different principles (I want to talk about them in this article). Recall how much Smarty and Blitz differ in the principle of processing structures and logical conditions, but to call each of these principles a defective or insufficient language does not turn.
  3. Both of these causes give rise to the main reason for the emergence of holivars: self-sufficiency . If we had one template-maker per principle, and not 10-15, as it is now, it would be an absolute plus. But when, by manipulating the known principles of the work of template engines and their minor changes, a new, self-sufficient template maker is born - he gains some fame for himself, and the N-th side appears in the confrontation of programmers.

Swan, Cancer and Pike, is not it? Everyone pulls in his own way, but it’s impossible to point out the obvious functional shortcomings of any approach of one template maker - his supporters will always find a method for implementing this functionality, and the dispute again goes into an endless flame.
Now, actually why am I writing this article. I would like to highlight some types of template engines in terms of their syntax and level of flexibility provided to both the programmer and the coder (as I will call the person working with the template for the Web application).

I will not consider in detail the representatives of each type, only I will give the code examples I need. For definiteness, we will consider the most ordinary customer. This is a private individual, for example, a small office system administrator who does not speak programming languages, but is easily trained and is a webmaster and project coder at the same time. And this is not a spherical client in a vacuum - such a majority. If not people, then the requirements for the design of the site - "so that you can easily change it later"

-1) Pure PHP

Although I assigned a negative index to the pure PHP code, this was done only to clearly indicate the position that I adhere to:
for the customer, this is a dark forest, which he has no need to study, because the syntax of any programming language is designed for maximum flexibility, and therefore redundant , because for the template engine it is the most terrible flaw. As though the constructions in PHP based templates were not facilitated syntax, foreach, for, if, and all other constructs deserve abbreviations.
I will not take Zend_Framework as an example, but take a fairly developed and ambitious project, Savant3:
 <html>
 <table>
     <? php while ($ row = $ this-> result-> fetchRow ()):?>
         <tr>
             <? php foreach ($ row as $ val):?>
                 <td> <? php $ this -> _ ($ val)?> </ td>
             <? php endforeach;  ?>
         </ tr>
     <? php endwhile;  ?>
 </ table>
 </ html>
This is a native PHP code, but understanding the while rows ($ row = $ this-> result-> fetchRow ()): and foreach ($ row as $ val): requires complex PHP skills. And this is the main counterargument to statements like “PHP itself is an excellent template engine, why reinvent the wheel?”. Then, in order not to teach the customer to ride a one-wheeled vehicle on which programmers can work wonders, but to give something simpler and more resistant to syntactic liberties — a three-wheeled one, for example. We assumed earlier that for our client this is exactly the same level.
Let's go directly to the template engines. Numbering, according to tradition, start from scratch. </ P

0) Interpreter In Interpreter (3I)

By far the most famous is Smarty. And more abstract, but, in my opinion, with a more ambiguous syntax of ETS . PEAR represents a good class PEAR :: HTML_Template_Flexy. Their first problem is that, as Smarty’s opponents rightly point out, many constructs look the same in PHP code, and more complex tasks, in which Smarty differs from PHP, are quite rare. For example, the code from the examples PEAR :: HTML_Template_Flexy:
 {ucfirst (#this is the header #)}

 {includeBody (): h}

 {foreach: a, k, v}
   k is {k}, and v is {v}
 {end:}

 {if: showStuff} Hello {end:}
 {if: showDog ()} Doggy {end:}
And Smarty and any such template engine look redundant , it's silly to argue with that. How not to call it - heavy, slow, overloaded, but Smarty is just that. Similar template engines are written by programmers and for programmers. If the team is working on any project, then, of course, such a flexible syntax of the “additional language” and the ability to transfer part of the logic inside the template greatly simplify the development. But as soon as the project is transferred to the hands of people who are not familiar with the syntax of such a template, no documentation and tutorials will not save. And if the template engine itself is very poorly written, then it is impossible to grasp the logic at first sight. Although ETS is not similar to PHP in its pure form, it has a complex syntax, similar to Smarty in some details. To those who have never seen ETS, I’ll give this piece of code without comments:
 {mask: main}
 <html>
     <head> <title> {title} </ title> </ head>
     <body>
           <h1> {title} </ h1> <hr>
           {mask: mypartners}
                 {mask: // partners}
                       <b> {if: {id} == {../../id}} <p> {label} </ p> {/ if} </ b>
                 {/ mask}
           {/ mask}
     </ body>
 </ html>
 {/ mask}
I apologize for the excessive attention paid to Smarty, the essence is not in my attitude towards him, but in his unequivocal predominance in the sector of the considered template.

1) Block & Var

At the very dawn of template engines, when they were just separated from the PHP code, this type prevailed. These include: OO Template, PEAR :: HTML_Template_IT, Blitz, TemplatePower, Yapter and a lot more. When I wrote this article, I dug out an old (over 2 years old) list of 25 template engines (you can find some of the names given here) dated 2006. During 2007-2008 the MVC pattern has gained immense popularity (and with it all sorts of rail-like frameworks), and block template engines didn’t fit into it at all, because assumed additional code in the controller, which is responsible for cyclic and conditional blocks. And it is very significant that many of the links given in this review do not work . These template engines are morally obsolete, against the background of modern technologies for building web applications, in reviews they are most often called "classics", but they contain a very strong principle of interaction between the program <=> presentation (deliberately not called logic, later there can be different interpretations), which I want to review more. Let's take the Blitz code:
     {{BEGIN item}}
         hello, world
     {{END}}
And the corresponding PHP code:
 <?
 $ T = new Blitz ('tpl');
 $ T-> iterate ('/ item');
 echo $ T-> parse ();
 ?>
What does this code do? Simply displays the text "hello, world". Nothing more, but an important feature of such template engines: no effort from the template engine can change the essence of the operations performed . That is, if you don’t bite on the term “presentation logic” (about it later), it depends entirely on the program! Those. in essence, the coder has no control over the pattern — power in the form of blocks is elusive. Take now the ETS:
 {repeat: <b> n </ b>}
 hello, world
 {/ repeat}
And here everything is completely the opposite, right in the template there is an opportunity to control the cycle. Similarly with logical conditions. If the coder of the Blitz template wants to display the “hello, world” block 7 times, he will have to call the programmer for help, since This option is directly in the program. If the coder of the ETS template wants to do the same, he can do it himself, directly in the template. For such freedom, the coder pays by studying the Smarty or ETS syntax. And if he does not want to pay, he is strongly limited to the principles of the work of block template engines. But the existing symbiosis of block and interpreted template engines overwhelmingly have a terrible syntax and a no less terrible implementation.

2) Tag-based

These are template engines based on HTML tags or their derivatives, for example bTemplate, PEAR :: HTML_Template_Flexy (suitable for two categories at once). Here I will not spread much, just select two types of template engines:

')

Source: https://habr.com/ru/post/30767/


All Articles