Saturday, January 17, 2009

Php - Object Oriented Templating using PHP

This is the templating system that I currently use on my site. Ofcourse, I make small changes to make it suit my sites.

Save as class.template.php

<?php

class Template{
    private
$cache = false;
    private
$cacheKey = NULL;
    private
$cachePeriod = 3600;
    private
$cachePath = NULL;
    private
$tplFile = NULL;
   
    function
enableCaching($key = NULL, $ttl = 3600){
       
$this->cache = true;
        if(!
is_null($key)){
           
$this->cacheKey = $key;
        }
       
$this->cachePeriod = $ttl;
    }
   
    function
disableCaching(){
       
$this->cache = false;   
    }
   
    function
setCachePath($path){
       
$this->cachePath = $path;   
    }
   
    function
getCacheFile(){
        if(
is_null($this->cachePath) || !file_exists($this->cachePath)){
           
$this->error('Invalid Cache Path.');   
        }
       
$cacheKey = is_null($this->cacheKey) ? md5($this->tplFile) : $this->cacheKey;
        return
$this->cachePath . '/' . $cacheKey;
    }
   
    function
cacheExist(){
       
$cacheFile = $this->getCacheFile();
        if(
file_exists($cacheFile) && filemtime($cacheFile) > time() - $this->cachePeriod){
            return
true;
        }else{
            return
false;
        }
    }
   
    function
getCache(){
        if(
$this->cache && $this->cacheExist()){
            echo
file_get_contents($this->getCacheFile());
            return
true;
        }else{
            return
false;
        }
    }
   
    function
setTemplate($tpl){
       
$this->tplFile = $tpl;
    }
   
    function
generate(){
        if(!
file_exists($this->tplFile)){
           
$this->error("Template File <i>$this->tplFile</i> not found.");
        }
       
extract(get_object_vars($this), EXTR_REFS | EXTR_PREFIX_ALL, 't');
        if(
$this->cache){
           
$cacheFile = $this->getCacheFile();
           
ob_start();
            include
$this->tplFile;
           
$output = ob_get_clean();
           
file_put_contents($cacheFile, $output);
            echo
$output;
        }else{
            include
$this->tplFile;
        }

    }
    function
error($message = ''){
        if(empty(
$message))$message = 'A fatal error occured. Unable to continue.';
        die(
"<b>Error</b> : $message");
    }
   
}
?>



Run the following query using phpMyAdmin to setup the database for the example script

--
-- Table structure for table `users`
--

CREATE TABLE IF NOT EXISTS `users` (
  `id` int(5) unsigned NOT NULL auto_increment,
  `name` varchar(25) NOT NULL,
  `email` varchar(50) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;

--
-- Dumping data for table `users`
--

INSERT INTO `users` (`id`, `name`, `email`) VALUES
(1, 'Lord Beckett', 'lord@beckett.com'),
(2, 'Davy Jones', 'davy@jones.com'),
(3, 'Jack Sparrow', 'jack@sparrow.com'),
(4, 'Will Turner', 'will@turner.com');



Example template file. Save as template.tpl.php. It is better to make sure that the filename ends in .php, so that it can make use of opcode caches like eaccelerator.

<html>
<head>
<title><?=$t_title?></title>
<link rel="stylesheet" href="style.css" type="text/css" />
</head>
<body>
<h1><?=$t_h1?></h1>
<table border="1">
<tr><td>ID</td><td>Name</td><td>Email</td></tr>
<?php foreach($t_users as $user):?>
<tr><td><?=$user['id']?></td><td><?=$user['name']?></td><td><?=$user['email']?></td></tr>
<?php endforeach;?>
</table>
</body>
</html>



Example script. Save as example.php in the same directory as the class.template.php

<?php
include 'class.template.php';
$tpl = new Template;
$tpl->setTemplate('template.tpl.php');
$tpl->enableCaching();
// Change the path to your cache path
$tpl->setCachePath('/var/www/vhosts/mysite.com/httpdocs/cache/');

if(
$tpl->getCache()){
    echo
'This was loaded from cache.';
}else{
    if(
mysql_connect('localhost', 'root', '')){
       
// Add variables to the template object as you like.
        // You can access these variables in the template file by prefixing it with t_. For example $tpl->h1 becomes $t_h1, $tpl->users becomes $t_users.
       
$tpl->title = 'My Template Example';
       
$tpl->h1 = 'Example';
       
mysql_select_db('test');
       
$result = mysql_query("SELECT * FROM `users`");
        while(
$row = mysql_fetch_assoc($result)){
           
$tpl->users[] = $row;   
        }
    }else{
       
$tpl->error('Could not connect to mysql');   
    }
   
$tpl->generate();
    echo
'This content will be saved to cache';
}

?>


No comments: