Page 1 of 1

my template parser

Posted: Sun Feb 04, 2007 6:34 pm
by dall
Here my template class, please add your comments, critique, thanks.

Code: Select all

<?php

    /**
    * Template class
    *
    * @package     cms
    * @version     0.0.1
    * @author      dall
    * @date        2006-02-05
    * 
    */ 

class Template {

    var $filename;
    var $tags;
    var $file_path;
    var $output;
    var $data;
    var $expire;
    var $is_cached;
    var $cache_filename;
    var $cache_path;
    
    // constructor
    function Template() 
    {
        $tags = array();
    }
    
    // load template
    function load($filename)
    {
        $this->filename = $filename;
        $this->file_path = MODULES_PATH.$this->filename.'/'.'templates/'.$this->filename.'.php';

        $this->fetch_file($this->filename);
        $this->headers();
        return $this->output;
    }
       
    // load cached template
    function load_cache($filename, $expire = 900)
    {
        $this->cache_filename = md5($filename);
        $this->cache_path = CACHE_PATH.$this->cache_filename.'.php';
        
        $this->expire = $expire;
        if($this->cached()) {
            $fp = @fopen($this->cache_path, 'r');
            $this->output = fread($fp, filesize($this->cache_path));
            fclose($fp);
            $this->headers();
            return $this->output;
        } else {
            $data = $this->fetch_file($filename);
            if($fp = @fopen($this->cache_path, 'w+')) {
                fwrite($fp, $data);
                fclose($fp);
            }
            else {
                die('Template->load: Cant write cache file "'.$this->file_path);
            }
            $this->headers();
            return $this->output;
        }
    }
    
    // load file contents
    function fetch_file($filename)
    {
        $this->filename = $filename;
        $this->file_path = MODULES_PATH.$this->filename.'/'.'templates/'.$this->filename.'.php';
        
        if(file_exists($this->file_path))
        {
            extract($this->tags);
            ob_start();
            require_once ($this->file_path);
            $this->output = ob_get_contents();
            ob_end_clean();
            return $this->output;
        }
        else {
            die('Template->load: Template file "'.$this->file_path.'" not found');
        }
    }
    
    // file is cached?
    function cached()
    {
       if($this->is_cached) return true;
       if(!$this->cache_filename) return false;

       if(!file_exists($this->cache_path)) return false;

       if(!($mtime = filemtime($this->cache_path))) return false;
       
       if(($mtime + $this->expire) < time()) {
           @unlink($this->cache_path);
           return false;
       }
       else {
           $this->is_cached = true;
           return true;
       }
    }
    
    // update cache
    function update_cache($filename)
    {
        $this->cache_filename = md5($filename);
        $this->cache_path = CACHE_PATH.$this->cache_filename.'.php';
        
        if(!file_exists($this->cache_path))
        {
            die('Template->update_cache: cache file dont exist');
        }
        
        
        @unlink($this->cache_path);
    }
    
    // set template variable
    function set($name, $value) {
        $this->tags[$name] = $value;
    }
    
    // set template variable (array)
    function set_array($tags, $clear = false) {
        if($clear) {
            $this->tags = $tags;
        }
        else {
            if(is_array($tags)) $this->tags = array_merge($this->tags, $tags);
        }
    }
    
    // gzip data, set headers
    function headers()
    {
        if (substr_count($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip'))
        {
            ob_start("ob_gzhandler");
        } else {
            ob_start();
        }
        header('Content-Type: text/html; charset=UTF-8');
    }
}

?>

Posted: Sun Feb 04, 2007 8:07 pm
by feyd
Shouldn't the default value for $tags in the load method be an empty array()?

While "/" often works across many platforms, DIRECTORY_SEPARATOR is PHP's own constant that should probably be used.

$data in parse() is potentially being misused.

The content type specification in display() may not be optimal. What if you write XML or XUL templates?

Posted: Sun Feb 04, 2007 9:51 pm
by Christopher
You might want to add:

Code: Select all

function set($tag, $value) {
     if ($tag) {
          $this->tags[$tag] = $value;
     }
}
Then you can pass the template object around and still set values.

Posted: Mon Feb 05, 2007 2:28 am
by dall
yes thanks, updated code.

Posted: Mon Feb 05, 2007 4:12 am
by dall
how to remove undefined vars in template?

Posted: Mon Feb 05, 2007 8:50 am
by John Cartwright
In PHP4, this is typically done by having a getter method. If the variable was not found, false is usually returned

Code: Select all

function get($var)
{
   if (array_key_exists($var, $this->data)) 
   {
      return $this->data[$var];
   }

   return false;
}

Posted: Mon Feb 05, 2007 8:53 am
by feyd
dall wrote:how to remove undefined vars in template?
Probably a regular expression.

Posted: Mon Feb 05, 2007 9:10 am
by onion2k
I'd argue that the function update_cache() has the wrong name. It's not updating the version of the page in the cache, it's just wiping out the old version. Obviously the plan is to create a new version next time the code calls load_cache(), but nonetheless if I called update_cache() I would expect an updated version of the file to be generated in the cache. What you have should really be called something like delete_cache().