| [ Team LiB ] |
|
27.6 TemplatesAnother approach to modularizing PHP applications can be called templatizing. Loose coupling is a fundamental principle of good system design. Aside from avoiding confusing people who don't understand PHP, a separation offers the benefit of switching to a different presentation language, such as XML, without disturbing the business logic. Using templates, interface designers insert simple tags into prototypical files (templates) composed mostly of HTML. They insert short bits of a simple templating language that a PHP script parses in order to replace markers with generated information. As with most solutions, there's a tradeoff. The cost of a templating system is increased work for PHP with each page load. PHP includes an efficient parser written in C by the geniuses at Zend. Writing your own parser in PHP itself is bound to be less than optimal, or so the argument goes. Yet, a simple syntax can help keep parsing fast, and some caching tricks can avoid most of the heavy lifting. I'm optimistic about the average person being able to learn to program in PHP. Templating pessimistically guesses that the average person won't learn PHP but can understand a simpler middle ground between PHP and HTML. I like to teach people to understand PHP, but I also understand there's usually a context for a good tool. FastTemplate is perhaps the oldest of the templating systems. It was ported from the original Perl implementation. It uses .tpl files to hold templates. These templates contain HTML and markers inside curly braces. A PHP script loads a template, sets values for each of the markers, and parses the template to produce a final chunk of HTML ready to send to the browser. Listing 27.3 Main template
<html>
<head><title>{TITLE}</title>
</head>
<body>
<h1>{TITLE}</h1>
<table>
<tr>
<td valign="top">{SIDENAV}</td>
<td valign="top">{MAIN}</td>
</tr>
</table>
</body>
</html>
Listing 27.3 shows a simple template. Look for the markers in curly braces. This template uses three: TITLE, SIDENAV, and MAIN. These are chunks of content generated inside the main PHP script. The first is a simple variable assignment, and the second will contain another template file. The last is a standard name used by FastTemplate to stand for the main content of any screen. Listing 27.4, Listing 27.5, and Listing 27.6 are a few other templates used in this example. Listing 27.4 Side navigation<a href="home.php">Home</a><br> <a href="about.php">About Us</a><br> <a href="contact.php">Contact Us</a><br> Listing 27.5 Table template
<table border="1">
<tr><th>n</th> <th>n^2</th> <th>n^3</th></tr>
{ROWS}
</table>
Listing 27.6 Row template
<tr>
<td>{NUMBER}</td> <td>{SQUARE}</td> <td>{CUBE}</td>
</tr>
The side navigation is a simple set of links to other scripts, as you might expect. The table includes three columns for a number, its square, and its cube. A template stored in row.tpl further defines the rows of the table. The PHP script in Listing 27.7 calls this template for each row of the table. Listing 27.7 Script using templates
<?php
//get FastTemplate class
require_once("class.FastTemplate.php");
//instantiate
//use templates in current directory
$tpl = new FastTemplate(".");
//set list of templates used
$tpl->define(
array(
"main"=>"27-3.tpl",
"side"=>"27-4.tpl",
"table"=>"27-5.tpl",
"row"=>"27-6.tpl"
)
);
//set the value of the TITLE variable
$tpl->assign(array("TITLE"=>"FastTemplate Test"));
//get side navigation
$tpl->parse("SIDENAV", "side");
//create rows for the table
for($n=1; $n <= 10; $n++)
{
//set values
$tpl->assign(
array(
"NUMBER"=>$n,
"SQUARE"=>pow($n,2),
"CUBE"=>pow($n,3)
)
);
//parse row template and append it to ROWS
$tpl->parse("ROWS",".row");
}
//parse table, main and put it in MAIN
$tpl->parse("MAIN", array("table","main"));
//send entire contents to the browser
$tpl->FastPrint("MAIN");
?>
Most of the code in this example ought to be easy to follow. The template files need to be in a subdirectory, as shown in the instantiation. The assign method sets one or more variables to a fixed value, and the parse method parses a template. You must define marker values before parsing a template, of course. This example produces a table of numbers generated in a loop. Each row of the table is appended to the ROWS variable by assigning variable values and parsing the template. Note that the call to parse uses a period before the name of the template, row. This tells FastTemplate to append instead of replace. FastTemplate also uses another syntax for repeating blocks. You mark part of the HTML with HTML comments that must follow a strict form. There's no room for adding extra spacing or breaking the comment onto two lines. These are called dynamic blocks, and they are really embedded templates. PHPLib is a large framework for building Web applications. It includes a class that uses templates very similar to those used by FastTemplate. You must download the entire package to get the template class, but it's usable by itself. Like FastTemplate, PHPLib's template class uses curly braces for markers. It also supports repeating blocks using HTML comment syntax. Other than the differences in method names, this class works like FastTemplate. Two other similar solutions are AvantTemplate and TemplatePower. These classes use the same approach to templating defined by FastTemplate: markers that stand for replaceable values. They also add support for including templates directly instead of using a marker. Choosing between these templating systems is largely one of personal preference. You might prefer the syntax of one of them over others. TemplatePower claims to be faster than FastTemplate by six times. Naturally, if you use PHPLib, its included templating class is your best choice. The consequence of the extra layer keeping HTML and PHP logic separate is a hit to performance. Every page load requires parsing templates and filling in values for markers. It can have a significant effect on the time it takes to assemble a page. Some data must be regenerated with each request, such as the contents of a shopping basket, but most information on a Web site is static. We can save a lot of work if we cache the parsed templates. In computer terms, a cache is temporary, fast storage. Space in the cache is limited, and data placed there is volatile. Caches rely on the idea that a request for data now predicts another request for the same data in the near future. If an application behaves this way and the cache is sufficiently large, you will experience a performance increase by using a cache. The cachedFastTemplate class adds caching to the original PHP FastTemplate implementation. Two new methods allow reading from and writing to text files stored in /tmp. The write_cache method stores fully parsed templates in a directory named after the Web server's host name. The is_cached method will load the contents from the directory if the template was cached previously. The appeal of this class is that it's a drop-in replacement for the original class. You don't need to update your templates. Changes to your PHP scripts are minor, and they will continue to function even without modification. They just won't cache. There are a few other templating systems that use caching, but Smarty is an industrial-strength solution. First, Smarty compiles templates into native PHP. The template file edited by interface designers is parsed only once. Calls to templates cause the PHP engine to run a .php file. This eliminates the overhead of running a parser written in PHP. Compilation of scripts occurs behind the scenes, with no commands in your script. If a page request calls for a template that hasn't been compiled yet, Smarty compiles it. If the template file changes after this compilation, Smarty will recompile the next time your script uses the template. Additionally, Smarty includes caching functionality, increasing the performance for static pages. For those pages with static content, Smarty will process the template into a plaintext file. As with other caching implementations, you can set an expiration time, after which the file will be regenerated. Smarty's templating system includes more than just marker replacement. It also includes sophisticated control flow, such as if-else statements. This allows interface designers to make simple logical decisions without bothering programmers. The system also includes loops and a function for including other templates in place. Templating systems are clearly a satisfying solution for some people; otherwise, they wouldn't be so popular. FastTemplate is simple, and I'm sure anyone comfortable with HTML can handle working around the markers. The complex solutions, such as Smarty, may be nearly as intimidating as PHP itself. This is not to suggest that Smarty has no value. Its approach certainly will be attractive to many programmers, and careful communication with novices can help keep them away from the more complex syntax. Most of these templating systems use {name} as a marker for some value to be placed later by a PHP script. It's only slightly more complicated to write <?php=$name?>. The biggest disadvantage to using PHP tags is that they don't show up visually in browsers, which treat them as unrecognized tags. |
| [ Team LiB ] |
|