Smarty is a template engine for PHP whose main goal is to facilitate a very useful way to separate the business logic from the presentation logic. This article introduces Smarty and demonstrates how to install the template, create an application from scratch and interact with a database.

Installing the Smarty Template Engine

The Smarty template engine can be downloaded from the official website. At this site you will also find complete documentation that will help you to learn more about working with Smarty templates.

To install and use Smarty you should go through the following steps:

  1. Unzip the Smarty archive to the proper directory. I put the Smarty library into the D:/Apache2.2/htdocs/php/ path. You should see the structure below in the Smarty directory.



    Click here for larger image

    Figure 1. The Structure of Smarty/libs Folder

  2. Now, to test if Smarty is correctly installed, you should put the code below into the index.php script. As you can see from the listing below, before checking if all the required working folders can be accessed (using the testInstall() method) , you should create a new Smarty variable:
    <?php
    
    //Put full path to Smarty.class.php
    require('D:/Apache2.2/htdocs/php/Smarty/libs/Smarty.class.php');
    
    //Create new variable $smarty from the class Smarty
    $smarty = new Smarty();
    
    //Verifies that all required working folders of the Smarty installation can //be accessed
    $smarty->testInstall();
    
    ?> 
  3. To see the output of the test, write http://localhost/php/Smarty/demo/index.php into the browser. You should get something like this:
    Smarty Installation test...
    Testing template directory...
    .\templates\ is OK.
    Testing compile directory...
    .\templates_c\ is OK.
    Testing plugins directory...
    D:\Apache2.2\htdocs\php\Smarty\libs\plugins\ is OK.
    Testing cache directory...
    .\cache\ is OK.
    Testing configs directory...
    .\configs\ is OK.
    Tests complete.

Creating a New Simple Smarty Application

In this section you will see how to create your own "Hello World" application. To do that, you should first create a new folder (I named it Smarty_example) in the D:/Apache2.2/htdocs/php/ directory, set the template directory for use with different templates (as you will see below in the index.php script), assign a variable (in this case, name) and then compile and display the template file, index.tpl.

<?php

//Put the full path to Smarty.class.php
require('D:/Apache2.2/htdocs/php/Smarty/libs/Smarty.class.php');

//Create new variable $smarty from the class Smarty
$smarty = new Smarty();

//Set the template directory used for different templates
$smarty->setTemplateDir('/ Smarty_example /templates');
//Set the compile directory 
$smarty->setCompileDir('/ Smarty_example /templates_c');
//Set the cache directory
$smarty->setCacheDir('/ Smarty_example /cache');
//Set the configs directory
$smarty->setConfigDir('/ Smarty_example /configs');

//Set the name variable variables
$smarty->assign('name', 'WORLD');

//Compile and display output of the template file
$smarty->display('index.tpl');

?> 

The template file, index.tpl, looks like this:

<html>
  <head>
    <title>Smarty</title>
  </head>
  <body>
    Hello, {$name}!
  </body>
</html>

The output of the "Hello World" application is:



Click here for larger image

Figure 2. The Output of the First Simple Application "Hello World"

Creating a Complex Smarty Application Using Databases

In this section, I will demonstrate how to create an application that will use a bookstore database and its table, books. The books table structure and content can be seen in Figure 3.



Click here for larger image

Figure 3. The Books Table Structure and Content

This application will connect to the bookstore database to get all the records, put them all into an array, one row next to another, and display the whole table using the template file.

But first, to connect to the bookstore database in PHP 5, I use the DatabaseSingletonClass listed below:

<?php
class DatabaseSingletonClass
{

    //set this constants to connect to your database - the default settings 
    //are just for testing tasks
    const MYSQL_HOST = "127.0.0.1";
    const MYSQL_USER = "root";
    const MYSQL_PASS = "";
    const MYSQL_DB = "bookstore";
   
    //A static member variable representing the class instance
    private static $_instance = null;

    //Locked down the constructor, therefore the class cannot be 
    //instantiated
    private function  __construct() { }

    //Prevent any object or instance of that class to be cloned
    public function  __clone() { 
      trigger_error( "Cannot clone instance of Singleton pattern ...", 
                      E_USER_ERROR );
      }

    //Prevent any object or instance to be deserilized
    public function __wakeup() {
      trigger_error('Cannot deserialize instance of Singleton pattern ...', 
                     E_USER_ERROR );
     }

    //Have a single globally accessible static method
    public static function getInstance()
    {
        if( !is_object(self::$_instance) )
          { //or if( is_null(self::$_instance) ) or if( self::$_instance == 
                     null )          
      self::$_instance = new MySQLi(self::MYSQL_HOST, 
            self::MYSQL_USER, self::MYSQL_PASS, self::MYSQL_DB);
      if(self::$_instance->connect_error)
         {
         throw new Exception('MySQL connection failed: ' . 
                  self::$_instance->connect_error);
         }
           }
        return self::$_instance;
    }
}
?>

The index.php listing uses the above DatabaseSingletonClass.php script to connect to the bookstore database. Then the Smarty template file loops the $row array and outputs each record of it.

<?php

//include the DatabaseSingletonClass class to connect at the bookstore //database
include_once('DatabaseSingletonClass.php');

//Querying the book table
$result = DatabaseSingletonClass::getInstance()->query("SELECT id, title, author, yearofpublication, publisher, price FROM books");

//The commented lines from below list the records from the books table 
//exactly what the Smarty template file index.tpl does in this example
/*
if($result) {
    echo("<table border='1'>");
    while ($row = mysqli_fetch_row($result)) {
       echo("<tr>");
       for($i = 0; $i < count($row); $i++) {
         echo "<td>".$row[$i]."</td>";
       }
       echo("</tr>");
    } 
    echo("</table>");

    $result->close();

  } else { echo("An error occured while processing!"); }
*/

//Include the Smarty.class.php
include_once('D:/Apache2.2/htdocs/php/Smarty/libs/Smarty.class.php');

//Create new variable $smarty from the class Smarty
$tpl = new Smarty;

//list the book table fields
echo'<table cellpadding="4" border="1" width="500" align="center"><tr>';
echo '<td style="border-top:3px #E6E6E6 solid; border-bottom:3px #595959 solid; border-right: 3px #595959 solid; 
border-left:3px #E6E6E6 solid;">Id</td><td style="border-top:3px #E6E6E6 solid; border-bottom:3px #595959 solid;
border-right: 3px #595959 solid; border-left:3px #E6E6E6 solid;">Title</td><td style="border-top:3px #E6E6E6 solid;
border-bottom:3px #595959 solid; border-right: 3px #595959 solid;
border-left:3px #E6E6E6 solid;">Author</td><td style="border-top:3px #E6E6E6 solid; border-bottom:3px #595959 solid; border-right: 3px #595959 solid;
border-left:3px #E6E6E6 solid;">Yearofpublication</td><td style="border-top:3px #E6E6E6 solid; border-bottom:3px #595959 solid;
border-right: 3px #595959 solid; border-left:3px #E6E6E6 solid;">Publisher</td><td style="border-top:3px #E6E6E6 solid;
border-bottom:3px #595959 solid; border-right: 3px #595959 solid; border-left:3px #E6E6E6 solid;">Price</td></tr>'; //Iterate over the book table rows while($row = mysqli_fetch_row($result)) { //Assign each row to the $row array $tpl->assign('row', $row); //Compile and display output of the template file $tpl->display('index.tpl'); } echo '<br /><br />'; ?>

You may notice from the listing below that to iterate an array I used the {section},{sectionelse} syntax. A {section} is for looping over sequentially indexed arrays of data, unlike {foreach}, which is used to loop over a single associative array. Every {section} tag must be paired with a closing {/section} tag. You can learn more about Smarty loop functions from the site documentation. This is the template file index.tpl:

<tr>
{section name=i loop=$row}      
        <td>{$row[i]}</td>
 {sectionelse}
</tr>
<tr><td><b><br>Array $row has no entries</b></td></tr>
{/section}

After putting everything together, the output of the database application using Smarty template engine is shown in Figure 4.



Click here for larger image

Figure 4. The Output of Our Database Complex Application

Conclusion

In this article you have seen how to install and use the Smarty template engine for PHP 5 and how to interact with a database.

About the Author

Octavia Andreea Anghel is a senior PHP developer currently working as a primary trainer for programming teams that participate at national and international software-development contests. She consults on developing educational projects at a national level. She is a coauthor of the book "XML Technologies: XML in Java" (Albastra, ISBN 978-973-650-210-1), for which she wrote the XML portions. In addition to PHP and XML, she's interested in software architecture, web services, UML, and high-performance unit tests. to e-mail her.