PHP Templating

Tagged:  

If you've done any developing with PHP (especially with open source PHP projects) you will have probably at least seen some templating. A commonly used template engine for PHP is Smarty. Smarty does a good job of helping your PHP applications adhere to a Model View Controller design.

As you probably know Model View Controller is a way of abstracting portions of an applications so that you can have multiple people working on their part of the project without stepping on other peoples toes. Which in any decent sized organization (or even in a startup) is very helpful to the development process. If you develop in PHP I recommend that you use templating, even in Ajax applications with PHP on the backend I recommend using templating, as it helps abstract the design from both the backend code and the data (which is exactly what we want).

Just to get you started with templating I've included a portion of a good tutorial on templating using Smarty below.

Basic Templating

At the most basic level, templating can be achieved by removing the common HTML code into separate files and including them into any php file:

<?php include("header.php"); ?>
some content and html goes here
<?php include("footer.php"); ?>

This approach is fine for most purposes and does help reusing common HTML (and/or php) code, for menu generation and setting of page footers and headers. Unfortunately, it does not adapt particularly well to all situations. In the event of the page dealing with form handling or session usage, life becomes slightly more complex.

The relatively simple form below shows how the code can become relatively messy and difficult to follow.

<?php
session_start();
require_once("header.php");

if(isset($_SESSION['username'])) {
   echo "Logged in as : " . $_SESSION['username'];
}
if(isset($_POST['id'])) {
   $results = database_query("SELECT * FROM blah WHERE id = ?", Array($_POST['id']));
   if(sizeof($results>0)) {
      echo "<p>The following matches were found:</p>";
      echo "<ul>\n";
      foreach($results as $item) {
         echo "<li>" . $item . "</li>\n";
      }
      echo "</ul>\n";
   }
   else {
      echo "<p>No matches found.</p>";
   }
}
?>
<p>Please enter an ID to search for</p>
<form method='post'>
<input type='text' name='id' value=''>
<input type='submit'>
</form>
<?php
require_once("footer.php");
?>

Fom looking at the above code, we have the following problems :

* We have to do some things before we can include the header page (e.g. session_start() or header() calls).
* Ideally we should only be outputting HTML at the last possible moment
* We have a mixture of PHP and HTML code, which makes the file bulky and difficult to edit
* It wouldn't be very easy to use the same underlying code to generate a page as a .pdf or other format
* Upon adding more logic, it's likely that it will become harder to follow the flow of execution
* The over complex nature of the page means it's highly likely that bugs will be introduced

We can help to solve the above problems by splitting the page into two distinct parts :

* Logic (dealing with form parameters and data retrieval)
* Display (HTML or other output).

Smarty has the answer...

There are numerous templating engines available for PHP, and some projects have the discipline to use native PHP embedded within a file for display of logic. I found Smarty's existing documentation and framework to make the migration far easier, as well as forcing me to resist the temptation to embed PHP based logic within the template.

Smarty is written in PHP, and installation is a matter of downloading a compressed file, extracting it somewhere appropriate (E.g. /usr/local/lib/php) and creating the necessary directory structure within your project. In order to use Smarty from within a PHP page, the following is required :

<?php
require_once("path/to/Smarty.class.php");
$smarty = new Smarty();
....
?>

Jumping straight to the refactored example, the way Smarty can be used, and the benefits of it should become clear.

First, the template file which is used by Smarty (this will normally live in a directory called 'templates'). This file contains HTML markup and some simple Smarty specific syntax. This file has a suffix of .tpl. An example one follows :

{include file='header.php'}
<p>Welcome to the application</p>

{if isset $logged_in_as}
    <p>{$logged_in_as}</p>
{/if}

{if sizeof($results > 0)}
    <ul>
    {foreach from=$results item=i}
       <li>{$i}</li>
    {/foreach}
    </ul>
{/if}
<p>Please enter an ID to search for</p>
<form method='post'>
  <input type='text' name='id' value=''>
  <input type='submit'>
</form>
{include file='footer.php'}

As you can see, Smarty provides constructs for looping and checking for the existence of variables. Smarty's template language is very similar to PHP in many respects.

In order to populate this template, the following php code could be used :

<?php
require_once("path/to/Smarty.class.php");
$smarty = new Smarty();
if(isset($_SESSION['username'])) {
   $smarty->assign("logged_in_as", "You are logged in as " . $_SESSION['username']);
}
if(isset($_POST['id'])) {
   $results = database_query("SELECT * FROM blah WHERE id = ?", Array($_POST['id']));
   $smarty->assign("results", $results);
}
$smarty->display("our_template.tpl");
?>

As should be apparent, the assign function is used to pass data to the template for display, and the 'display' function is used to select which template we wish to use. Because there is no output to the browser until 'display' is called, we can use any of the functions that output HTTP headers to the browser throughout nearly all of the file without getting the 'headers already sent' error.

In addition to the above you can find more useful resources below.

This is the tutorial that the above was taken from.
This resource is from the Smarty web site and is extremely useful.

As always if you have any questions on this post you can either leave a comment or contact me through Social Ajaxonomy.

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <pre> <div> <blockquote> <object> <embed> <img> <param>
  • Lines and paragraphs break automatically.
  • Web page addresses and e-mail addresses turn into links automatically.

More information about formatting options

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
Copy the characters (respecting upper/lower case) from the image.