您现在的位置是:首页 > 学无止境
Php Template Engines
Php Template Engines
The overall goal of this article is to advocate the use of template engines in PHP applications and to provide argumentation to support template engine usage. It also contains several examples of template engines, their advantages, and shortcomings, as well as a short guide for selecting the right template engine for your Web-based projects.
What Is a Template Engine
Template engine is in a sense a component that allows separation of php and HTML codes. When template engine is used in the application, HTML code is placed into separate files, templates. In addition to the HTML code, these files contain processing instructions that template engines execute, assembling the final HTML page which is downloaded and converted by browsers into what we see as Web pages. Typically, template engines execute a number of processing instructions, including, but certainly not limited to inserting a value of a certain variable, looping through a set of listings, displaying their titles, and including other template(s).
Key Reason to Use Template Engines
A task of separating the work of programmers from the work of designers is the most typical reason to use template engines in PHP or other languages. Certain authors covering this subject say that with the help of template engines, designers can create the look of a Web page without any substantial involvement of Web programmers. If there is only one person working on a Web application, there is no need for a template engine.
I consider this statement a bit misleading. The biggest advantage of any template engine is to separate the roles of a business domain developer (a programmer), and a front-end developer (designer) even if both roles are performed by the same person. These tasks, while being deeply interrelated, still require different skills and capabilities. When programmers work on the business logic of a website, they need to concentrate on the proper application design, architecture, data structures, business rules, and information storage.
Having that many tasks in mind, one can hardly pay enough attention to the look and feel of the website. When the development of functionality is complete, developers can start working on the appearance of the application. If the business logic code (php) and presentation code (HTML) are mixed, then it takes substantial effort to develop and maintain the appropriate look and feel of Web pages generated by such code. Such approach is slow and error-prone.
With php code separated from HTML code, it is so much easier to maintain both independently, even for a single developer. It allows developers to concentrate on specific tasks, improving the quality of both the implemented functionality and its visual presentation.
Therefore, using template engine benefits Web projects both in short and long term, and that is, regardless of a number or developers working on it.
A Very Basic Php-Based Template Engine
Many opponents of template engine usage (if they still exist) use the following statement as their main argument: PHP itself is a template engine, why use another one on top of PHP? My answer to this is as follows: it is true, there is no need for another one, PHP is well-suited to take care of this issue nicely. However, it all works fine if we keep the business logic and presentation parts of code in different files.
Let us say we have an unstructured php code that has generated a Web page:
<html>
<head>
<title><?php
function getTitle(){ ... };
$title=getTitle(); echo $title;?></title>
</head>
<body>
<div class="menu"> ... </div>
<div class="content">
<?php
function getArticles{ ... };
echo '<h1 class="page_title">' . $title . '</h1>'
$articles = getArticles();
foreach($articles as $article)
{
echo '<div class="article" id="article"' . $article['id']. '>';
echo '<h2 class="article_title">' . $article['title'] . '</h2>';
echo '<p>' . $article['text'] . '</p>';
echo '<div>';
}
?>
</div>
</body>
</html>
Now, let us move the business logic part of the code to the beginning of the file, leaving the presentation part at the end of file. With a little help of short tags we get:
<?php
function getTitle(){ ... }
function getArticles{ ... }
$title=getTitle();
$articles = getArticles();
?>
<html>
<head>
<title><?=$title;?></title>
</head>
<body>
<div class="menu"> ... </div>
<div class="content">
<h1 class="page_title"><?=$title;?></h1>
<? foreach($articles as $article): ?>
<div class="article" id="article<?=$article['id'];?>" >
<h2 class="article_title">
<?=$article['title'];?>
</h2>
<p>
<?=$article['text'];?>
</p>
</div>
<? endforeach; ?>
</div>
</body>
</html>
Now, the code is much clearer, and it is much easier to notice that I forgot to close the div tag inside the loop. When there is more PHP and html code, the merits of separation of code are a lot more obvious.
The obvious next step is to place the HTML code into a separate file, named "template.php", which will make the php code look even better:
<?php
function getTitle(){ ... }
function getArticles{ ... }
$title=getTitle();
$articles = getArticles();
include "template.php";
?>
This method works perfectly for small web applications (single scripts or similar), but it has too many shortcoming, like shared namespace between business logic and templates, and still poor template legibility. It can be substantially improved with the technique described in the article here .
The Smarty Template Engine
Smarty is the leading template engine for PHP-based applications. It is feature-reach, fast and reliable. Template language used by Smarty is very easy to read and maintainable. Here is how the above template example looks like if designed for Smarty:
<html>
<head>
<title>{$title}</title>
</head>
<body>
<div class="menu"> ... </div>
<div class="content">
<h1 class="page_title">{$title}</h1>
{foreach from="$articles" item="article"}
<div class="article" id="article{$article.id}">
<h2 class="article_title">{$article.title}</h2>
<p>{$article.text}</p>
</div>
{/foreach}
</div>
</body>
</html>
Smarty tags are more concise and elegant. It is clearly easier to differentiate Smaty tags (the curly brackets) from HTML tags. This feature of Smarty template language significantly reduces chances for an error.
Here is the php code that will display the template above:
<?php
function getTitle(){ ... }
function getArticles{ ... }
$smarty = new Smarty();
$smarty->assign('title', getTitle());
$smarty->assign('articles', getArticles());
$smarty->display("template.tpl");?>
As you can see, using Smarty is straightforward. In most applications using Smarty, there are quite a few more lines of code than shown in the example above, primarily since there is a need to set paths to template directory and to locations to store the compiled templates. However, a simple application can use the default values instead. Smarty template syntax supports all of the standard template tasks out of the box:
- Basic insertion of variable value, as shown in the above sample {$title}
- Insertion of array’s element by index, as in {$article.id}. This can be nested like {$article.author.firstname} .
- Escaping text inserted from variables. The {$title|escape:”html”} will replace the opening and closing angle brackets with proper HTML entities. The {$title|escape:”url”} url-encodes the variable’s value before insertion. These are called variable modifiers. Default Smarty installation has a vast variety of modifiers for different uses: capitalize, count word, truncate, etc.
- Branching: {if $article.title@strlen < 1}No title{else}{$srticle.title}{/if}
- Looping through collections of data (arrays or objects) as shown in the example above. Smarty has built-in {foreach} and {section} blocks for that.
- Inclusion of another template with a simple instruction like {include file=”another.tpl”} .
The power of Smarty is not limited only to nice template language syntax. Here is an itemized overview of Smarty’s most powerful features:
- It is fast. When Smarty reads template for the first time, it compiles the template into php source code and stores it in a separate folder. When Smarty is called later for the same template, it checks whether the template has been changed since the last instance it was compiled. If not, Smarty will include the compiled version of the template. Since the built-in “include” directive is used to render the compiled templates, it work almost as fast as php itself.
- Smarty is very extensible. With Smarty an application developers are able to define their own functions (like {my_include param1=”true”} ), own blocks (like {my_block}{/my_block} ), own variable modifiers (like {$variable|my_modifier} . All these can be defined during the runtime or as a Smarty plug-in.
- Pluggable template resources. Smarty can use templates from any arbitrary source, not just files. One can easily create template source and feed templates to Smarty from a database, remote servers, or even build templates on the fly.
- Template inheritance (since version 3.0). Smarty is one of few template engines that support template inheritance. It improves maintainability of web site templates by reducing the duplicate template source code. Instead of repeating the common part of the page in each template, this part of HTML can be inherited from a parent template. Child templates can define which part of the parent template they inherit, and which they override.
- Built-in caching mechanism, which is simple, but yet quite sufficient for most of applications. Caching allows speeding up the page generation by storing the rendered page or its parts on disk and sending it to the user once requested (without executing the templates).
Beyond the above technical advantages of Smarty, it has another big advantage, its popularity. Most of PHP developers are more or less acquainted with Smarty. This makes it easy to find developers that know Smarty and Smarty experts on the market.
However, there cannot be so many pro’s without con’s, can there? The Smarty’s con’s are:
- Smarty distribution has about a hundred files, which have to be deployed together with the application. This is too much for a small application comprised of 2-3 php files.
- No built-in support for internationalization. Smarty does not provide a built-in interface to popular translation and localization libraries such as gettext or similar.
PHPTAL Template Engine
PHPTAL is an implementation of the TAL concept in php. TAL stands for Template Attribute Language. PHPTAL is not the only implementation of TAL, but is the most popular implementation of it in php. In the TAL concept, template processing instructions are expressed as attributes of HTML (or XML) tags. Here is the above example rewritten for PHPTAL engine:
<html xmlns:tal="
http://xml.zope.org/namespaces/tal
">
<head>
<title tal:content="title">fake title</title>
</head>
<body>
<div class="menu"> ... </div>
<div class="content">
<h1 class="page_title" tal:content="title"> fake title </h1>
<div tal:repeat="article artickes" class="article">
<h2 class="article_title" tal:content="article/title"></h2>
<p tal:content="article/title"></p>
</div>
</div>
</body>
</html>
The idea behind the TAL has its own internal beauty. Instead of introducing a new syntax above HTML or XML, TAL engines embed the processing instructions into HTML code itself. As you can see, the template source code became even more concise.
Here are the basics of PHPTAL template language:
- Processing instructions are tags’ attributes which have a separate namespace (“tal” in the example above).
- The tal:content attribute instructs the template engine to replace the content of the tag according to the attribute’s value. In the example above the tal:content attribute tell engine to replace the contents of the <title> tag with the value of title variable.
- Loops are implemented with the help of tal:repeat attribute. In the example above the <div ..> tag will be repeated for each element of articles array. Current item is accessible by name article .
- The article properties (the title and the text) are inserted into the tags’ contents with the use of tal:content attribute.
- A tal:condition attribute can be used to specify condition (branching). If condition is not satisfied, the tag is excluded from the output.
There are many other TAL attributes for different tasks, like defining constants, adding attributes to tags, etc.
PHPTAL also supports definitions of macros. Macros are reusable parts of the template that can be imported and used in different templates, just like php functions. PHPTAL comes with a built-in internationalization support. It integrates out-of the box with gettext. Other translation providers can be implemented with PHPTAL_TranslationService interface. Just like Smarty (and many other template engines) PHPTAL compiles templates into php code, which makes it fast and even faster then Smarty.
Another advantage of PHPTAL is that it forces all templates should be valid XML documents, which allows to use XML tools (like XSLT, XML editor and similar) to maintain application’s template set.
PHPTAL’s disadvantage is limited language abilities compared to Smarty and other template engines. Despite the beauty of TAL, it still misses many capabilities. Many template engines (not just php-based) augment TAL with there own additional syntax to overcome the limitations. PHPTAL however limits its language to attributes only. Nevertheless, PHPTAL is quite suitable for business-class applications.
Recommendations for Template Engines Usage
The choice of the template engine for your projects is one of the most important choices you will have to make. Moreover, in 99.9% of cases the choice has to be made on the very early stage of the project. The influence of the template engine on the development of the application is quite substantial. Thus, the right choice of the template engine can be a critical factor for the project’s success.
Things to consider when making a choice:
- Template
maintenance is the first thing to consider. How easy is it going to be
to develop, enhance, bug fix and re-factor the application’s templates?
As explained in the beginning of the article, the use of template engine
is to assist in better application development and maintenance.The
questions that will help clear out this point are:
- Is template syntax legible and clear enough for the team and you? Will it be hard for you to code templates, read others’ code, or spot bugs in the template?
- Can template files be organized? How these files fit into your project structure?
- Can you use SCM tools to control template changes?
- Performance is another important consideration. Although it is hard to tell in advance what the exact number of templates will there be, and what is the required speed of template rendering, one should estimate these values and estimate or measure candidate engine’s performance in similar or forecasted production conditions. Once template engine is integrated into the application, there will be limited capability to improve its speed. (The most common solution is caching).
- Deployment of templates and template engines. As said in previous sections of the article, many template engines compile templates and store the compiled templates in a separate directory. Thus, there must be a writable directory on the production server. One should remember to set up the template engine correctly as well as give writing permissions to the compiled templates directory for the HTTP-server process. Additionally, writable directory weakens the application security.
- Extendibility. The bigger the project, the more chances there are to demand more functionality from the template engine. Modifying the template engine’s source code is a bad idea (unless it is a custom template engine built exclusively for the project). If you change the template engine’s source code, you will lose the ability to upgrade the template engine when a newer version is out. Therefore, the template engine should provide extension points to add the desired functionality on top of what the engine has out-of-the-box. Typical case for such functionality is the internationalization capabilities.
As for my personal choices of application template engines, I would say that for a small application with 10-30 classes and 5-10 templates, I would use a simple php-based template engine class as the one showed in the beginning of the article. I would be able to add functionality to this engine by adding methods to the class as my demands grow to some extend. For anything bigger, I would recommend using Smarty.
Links and Further Reading
Php-based template wrapper class: http://www.massassi.com/php/articles/template_engines/
Smarty: http://www.smarty.net/
PHPTAL: http://phptal.org/
Overview of most popular php template engines: http://www.webresourcesdepot.com/19-promising-php-template-engines/
TAL community page: http://wiki.zope.org/ZPT/TAL
Author: Max K.
Worksforweb Development Team Leader
文章评论
- 登录后评论
点击排行
-
php-fpm安装、配置与优化
转载自:https://www.zybuluo.com/phper/note/89081 1、php中...
-
centos下postgresql的安装与配置
一、安装(以root身份进行)1、检出最新的postgresql的yum配置从ht...
-
Mysql的大小写敏感性
MYSQL在默认的情况下查询是不区分大小写的,例如:CREATE TABLE...
-
关于URL编码
转载自:http://www.ruanyifeng.com/blog/2010/02/url_encoding....
-
header中的Cache-control
网页的缓存是由HTTP消息头中的“Cache-control”来控制的,常见的...