2008年12月4日星期四

create a simple template engine

template.php
==================================================================================================
/**
* @filename :firephp.php
* @author :xusong lie
* @e-mail :liexusong@yahoo.com.cn
* @date :2008-05-03
*/

class Firephp {
var $tpl_vars;
var $template_c = 'template_c/';

function Firephp() {
$this->tpl_vars = array();
}//end of firephp()

function assign($key,$val=null) {
if(!isset($key)) return false;
if(is_array($key) && !isset($val)) {
if(sizeof($this->tpl_vars) > 0) {
$this->tpl_vars = array_merge($this->tpl_vars,$key);
} else {
$this->tpl_vars = $key;
}
} else {
$this->tpl_vars[$key] = $val;
}
return true;
}//end of assign()

function parse($filename) {
if(!file_exists($filename)) die('Template is not exists.');
$content = ''."\n";
$content .= file_get_contents($filename);
$pattern = "/\\$[a-zA-Z_]{1,}[a-zA-Z0-9_]{0,}/";
preg_match_all($pattern,$content,$matchs);

foreach($matchs[0] as $match) {
if(!isset($this->tpl_vars[substr($match,1,strlen($match))])) die("Variable {$match} had not defined.");
}

$content = preg_replace("/\\{\\$([a-zA-Z_]{1,}[a-zA-Z0-9_]{0,})\\}/",'tpl_vars["\\1"]; ?>',$content);
//start if
$content = preg_replace('/\{if \\$([a-zA-Z_]{1,}[a-zA-Z0-9_]{0,})\s{0,}==\s{0,}\\$([a-zA-Z_]{1,}[a-zA-Z0-9_]{0,})\}/','tpl_vars["\\1"] == $this->tpl_vars["\\2"]):?>',$content);
$content = preg_replace('/\{if \\$([a-zA-Z_]{1,}[a-zA-Z0-9_]{0,})\s{0,}>\s{0,}\\$([a-zA-Z_]{1,}[a-zA-Z0-9_]{0,})\}/','tpl_vars["\\1"] > $this->tpl_vars["\\2"]):?>',$content);
$content = preg_replace('/\{if \\$([a-zA-Z_]{1,}[a-zA-Z0-9_]{0,})\s{0,}>=\s{0,}\\$([a-zA-Z_]{1,}[a-zA-Z0-9_]{0,})\}/','tpl_vars["\\1"] >= $this->tpl_vars["\\2"]):?>',$content);
$content = preg_replace('/\{if \\$([a-zA-Z_]{1,}[a-zA-Z0-9_]{0,})\s{0,}<\s{0,}\\$([a-zA-Z_]{1,}[a-zA-Z0-9_]{0,})\}/','tpl_vars["\\1"] < $this->tpl_vars["\\2"]):?>',$content);
$content = preg_replace('/\{if \\$([a-zA-Z_]{1,}[a-zA-Z0-9_]{0,})\s{0,}<=\s{0,}\\$([a-zA-Z_]{1,}[a-zA-Z0-9_]{0,})\}/','tpl_vars["\\1"] <= $this->tpl_vars["\\2"]):?>',$content);
$content = preg_replace('/\{if \\$([a-zA-Z_]{1,}[a-zA-Z0-9_]{0,})\s{0,}!=\s{0,}\\$([a-zA-Z_]{1,}[a-zA-Z0-9_]{0,})\}/','tpl_vars["\\1"] != $this->tpl_vars["\\2"]):?>',$content);
$content = preg_replace('/\{if \\$([a-zA-Z_]{1,}[a-zA-Z0-9_]{0,})\s{0,}===\s{0,}\\$([a-zA-Z_]{1,}[a-zA-Z0-9_]{0,})\}/','tpl_vars["\\1"] === $this->tpl_vars["\\2"]):?>',$content);

$content = preg_replace('/\{if \\$([a-zA-Z_]{1,}[a-zA-Z0-9_]{0,})\s{0,}==\s{0,}(\S{1,})\}/','tpl_vars["\\1"] == \\2):?>',$content);
$content = preg_replace('/\{if \\$([a-zA-Z_]{1,}[a-zA-Z0-9_]{0,})\s{0,}>\s{0,}(\S{1,})\}/','tpl_vars["\\1"] > \\2):?>',$content);
$content = preg_replace('/\{if \\$([a-zA-Z_]{1,}[a-zA-Z0-9_]{0,})\s{0,}>=\s{0,}(\S{1,})\}/','tpl_vars["\\1"] >= \\2):?>',$content);
$content = preg_replace('/\{if \\$([a-zA-Z_]{1,}[a-zA-Z0-9_]{0,})\s{0,}<\s{0,}(\S{1,})\}/','tpl_vars["\\1"] < \\2):?>',$content);
$content = preg_replace('/\{if \\$([a-zA-Z_]{1,}[a-zA-Z0-9_]{0,})\s{0,}<=\s{0,}(\S{1,})\}/','tpl_vars["\\1"] <= \\2):?>',$content);
$content = preg_replace('/\{if \\$([a-zA-Z_]{1,}[a-zA-Z0-9_]{0,})\s{0,}!=\s{0,}(\S{1,})\}/','tpl_vars["\\1"] != \\2):?>',$content);
$content = preg_replace('/\{if \\$([a-zA-Z_]{1,}[a-zA-Z0-9_]{0,})\s{0,}===\s{0,}(\S{1,})\}/','tpl_vars["\\1"] === \\2):?>',$content);
$content = preg_replace('/\{if \S{1,}\}/','',$content);
//end if

//start else if
$content = preg_replace('/\{elseif \\$([a-zA-Z_]{1,}[a-zA-Z0-9_]{0,})\s{0,}==\s{0,}\\$([a-zA-Z_]{1,}[a-zA-Z0-9_]{0,})\}/','tpl_vars["\\1"] == $this->tpl_vars["\\2"]):?>',$content);
$content = preg_replace('/\{elseif \\$([a-zA-Z_]{1,}[a-zA-Z0-9_]{0,})\s{0,}>\s{0,}\\$([a-zA-Z_]{1,}[a-zA-Z0-9_]{0,})\}/','tpl_vars["\\1"] > $this->tpl_vars["\\2"]):?>',$content);
$content = preg_replace('/\{elseif \\$([a-zA-Z_]{1,}[a-zA-Z0-9_]{0,})\s{0,}>=\s{0,}\\$([a-zA-Z_]{1,}[a-zA-Z0-9_]{0,})\}/','tpl_vars["\\1"] >= $this->tpl_vars["\\2"]):?>',$content);
$content = preg_replace('/\{elseif \\$([a-zA-Z_]{1,}[a-zA-Z0-9_]{0,})\s{0,}<\s{0,}\\$([a-zA-Z_]{1,}[a-zA-Z0-9_]{0,})\}/','tpl_vars["\\1"] < $this->tpl_vars["\\2"]):?>',$content);
$content = preg_replace('/\{elseif \\$([a-zA-Z_]{1,}[a-zA-Z0-9_]{0,})\s{0,}<=\s{0,}\\$([a-zA-Z_]{1,}[a-zA-Z0-9_]{0,})\}/','tpl_vars["\\1"] <= $this->tpl_vars["\\2"]):?>',$content);
$content = preg_replace('/\{elseif \\$([a-zA-Z_]{1,}[a-zA-Z0-9_]{0,})\s{0,}!=\s{0,}\\$([a-zA-Z_]{1,}[a-zA-Z0-9_]{0,})\}/','tpl_vars["\\1"] != $this->tpl_vars["\\2"]):?>',$content);
$content = preg_replace('/\{elseif \\$([a-zA-Z_]{1,}[a-zA-Z0-9_]{0,})\s{0,}===\s{0,}\\$([a-zA-Z_]{1,}[a-zA-Z0-9_]{0,})\}/','tpl_vars["\\1"] === $this->tpl_vars["\\2"]):?>',$content);

$content = preg_replace('/\{elseif \\$([a-zA-Z_]{1,}[a-zA-Z0-9_]{0,})\s{0,}==\s{0,}(\S{1,})\}/','tpl_vars["\\1"] == \\2):?>',$content);
$content = preg_replace('/\{elseif \\$([a-zA-Z_]{1,}[a-zA-Z0-9_]{0,})\s{0,}>\s{0,}(\S{1,})\}/','tpl_vars["\\1"] > \\2):?>',$content);
$content = preg_replace('/\{elseif \\$([a-zA-Z_]{1,}[a-zA-Z0-9_]{0,})\s{0,}>=\s{0,}(\S{1,})\}/','tpl_vars["\\1"] >= \\2):?>',$content);
$content = preg_replace('/\{elseif \\$([a-zA-Z_]{1,}[a-zA-Z0-9_]{0,})\s{0,}<\s{0,}(\S{1,})\}/','tpl_vars["\\1"] < \\2):?>',$content);
$content = preg_replace('/\{elseif \\$([a-zA-Z_]{1,}[a-zA-Z0-9_]{0,})\s{0,}<=\s{0,}(\S{1,})\}/','tpl_vars["\\1"] <= \\2):?>',$content);
$content = preg_replace('/\{elseif \\$([a-zA-Z_]{1,}[a-zA-Z0-9_]{0,})\s{0,}!=\s{0,}(\S{1,})\}/','tpl_vars["\\1"] != \\2):?>',$content);
$content = preg_replace('/\{elseif \\$([a-zA-Z_]{1,}[a-zA-Z0-9_]{0,})\s{0,}===\s{0,}(\S{1,})\}/','tpl_vars["\\1"] === \\2):?>',$content);
$content = preg_replace('/\{if \S{1,}\}/','',$content);
//end else if

//start foreach
$content = preg_replace('/\{section \$([a-zA-Z_]{1,}[a-zA-Z0-9_]{0,}) in @([a-zA-Z_]{1,}[a-zA-Z0-9_]{0,})\}/','tpl_vars["\\1"] as \$\\2): ?>',$content);
$content = preg_replace('/\{@([a-zA-Z_]{1,}[a-zA-Z0-9_]{0,})\}/','',$content);
//end foreach
$content = preg_replace('/\{include ([^\{\}]+)\}/','',$content);
/*
$content = preg_replace('/\{foreach (\S{1,})\}/','',$content);
*/
$content = str_replace(array('{else}','{/if}','{/section}'),array('','',''),$content);

$fp = fopen($this->template_c.md5($filename).'.php','w');
fwrite($fp,$content);
}//end of parse();

function display($filename) {
$cacheFile = $this->template_c.md5($filename).'.php';
if(file_exists($cacheFile)) {
if(filemtime($filename) > filemtime($cacheFile)) {
$this->parse($filename);
}
} else {
$this->parse($filename);
}
include_once($cacheFile);
}//end of display()
}
?>



test page
==================================================================================================
include_once("template.php");
$tpl = new Firephp();
$tpl->assign('a','hello');
$tpl->assign('b','world');
$tpl->assign('c','hello');
$tpl->assign('array',array('t','o','n','y'));
$tpl->display('tpl.html');
?>


sample board
==================================================================================================
{$a} {$b} {if $a == 'hello'} hello {/if} {if $b != $a} world {/if}

{section $array in @a}
{@a}
{/section}

=========================================
key in: hello world hello world tony

没有评论: