Location: PHPKode > scripts > Dextep Template Engine > Dextep-php4.class.php
<?
/**
* Dextep - simple template engine for PHP.
* Version 1.0 (2010-11-02)
* 2010 (c) Alexey Burkov
* Licensed under the terms of the BSD License.
*/
class Dextep{

	var $VARIABLE = '(?:\$|%|\$%)[\w]+(?:\.%?[\w]+)*';	// regexp for variables
	var $OPERATOR = '[\s!|><&)(:^?%.\/*+=-]';			// regexp for operators
	var $NUMBER = '[0-9.]+?';							// regexp for numbers

	var $pool;		// stack for checking inclusions
	var $vars;		// storage for passed variables

	/**
	* Configuration variables
	*/
	var $cacheEnabled = true;			// true = caching enabled, false = disabled
	var $cachePath = 'cache/';			// path to cache folder
	var $templatePath = 'templates/';	// path to templates folder
	var $templateExt = '.html';			// templates extension

	/**
	* Object constructor
	*/
	function template(){
		$this->vars = array();
	}

	/**
	* Returns template variable with name $key
	*/
	function getVar($key){
		$value = &$this->vars;
		foreach(explode('.', $key) as $v){
			if (!isset($value[$v])) return null;
			$value = &$value[$v];
		}
		return $value;
	}

	/**
	* Sets template variable with name $key to $value
	*/
	function setVar($key, $value){
		$vars = &$this->vars;
		$parts = explode('.', $key);
		for($i=0, $len=count($parts); $i<$len-1; $i++){
			if (!isset($vars[$parts[$i]]) || !is_array($vars[$parts[$i]])) $vars[$parts[$i]] = array();
			$vars = &$vars[$parts[$i]];
		}
		$vars[$parts[count($parts)-1]] = $value;
	}

	/**
	* Executes and returns template $name
	* If $recache = true then overrides cache (if caching is used)
	*/
	function getTemplate($name, $recache = false){
		$cachefile = $this->cachePath . str_replace('/','-',$name).'.cache';
		if (!$this->cacheEnabled || $recache || !file_exists($cachefile)){
			if (!$template = $this->preprocessing($name)) return false;	// parse comments and {include}
			$template = 'ob_start();' . PHP_EOL . 'echo \''.strtr($template, array("\\"=>"\\\\","'"=>"\'")).'\';' . PHP_EOL . '$result = ob_get_clean();' . PHP_EOL;
			$template = preg_replace_callback('/{@?(('.$this->OPERATOR.'|'.$this->NUMBER.'|'.$this->VARIABLE.')+)}/U', array($this, 'callbackExpression'), $template); // parse expressions
			$template = preg_replace_callback('/{foreach\s+('.$this->VARIABLE.')\s+as\s+(?:%([\w]+)\s*=>\s*)?%([\w]+)\s*}/U', array($this, 'callbackForeach'), $template); // parse {foreach}
			$template = preg_replace_callback('/{for\s+var\s*=\s*(%[\w]+)\s+from\s*=((?:'.$this->OPERATOR.'|'.$this->NUMBER.'|'.$this->VARIABLE.')+)\s+to\s*=((?:'.$this->OPERATOR.'|'.$this->NUMBER.'|'.$this->VARIABLE.')+)\s+step\s*=\s*(-?'.$this->NUMBER.')\s*}/U', array($this, 'callbackFor'), $template); // parse {for}
			$template = preg_replace_callback('/{(else)?if\s+(('.$this->OPERATOR.'|'.$this->NUMBER.'|'.$this->VARIABLE.')+)}/U', array($this, 'callbackIf'), $template); // parse {if}, {elseif}
			$template = preg_replace('/{else\s*}/', '\';' . PHP_EOL . '} else {' . PHP_EOL . 'echo \'', $template); // parse {else}
			$template = preg_replace('/{\/(foreach|if|for)\s*}/', '\';' . PHP_EOL . '}' . PHP_EOL . 'echo \'', $template); // parse closing tags
			$template = preg_replace('/{\s*lb\s*}/', '{', $template); // parse {lb}
			$template = preg_replace('/{\s*rb\s*}/', '}', $template); // parse {rb}
			if ($this->cacheEnabled) file_put_contents($cachefile, $template); // save cache
		} else $template = file_get_contents($cachefile); // load from cache

		eval($template);		
		return isset($result) ? $result : false;
	}
	
	/**
	* Processes error. $str - error message.
	*/
	function error($str){
		die($str);
	}	

	/**
	* Parses template comments and {include} tags
	*/
	function preprocessing($name, $included = array()){
		$tplfile = $this->templatePath . $name . $this->templateExt;
		if (!file_exists($tplfile)) $this->error('Template &laquo;<code>'.$tplfile.'</code>&raquo; not found.');
		$template = file_get_contents($tplfile);
		if ($template){
			$template = preg_replace('/{\*(.*)\*}/sU', '', $template); // parse comments
			$this->pool = count($included) ? $included : array($name); // use pool to check for self-inclusions
			$template = preg_replace_callback('/{include\s+([\'"]?)([\w\/]+)\1\s*}/U', array($this, 'callbackIncludes'), $template); // parse {include}
		}
		return $template;
	}

	/**
	* Callback functions used with regular expressions
	*/
	
	function callbackIncludes($param){
		$name = $param[2];
		$pool = $this->pool;
		if (in_array($name, $this->pool)) $this->error('Self-inclusion of &laquo;<code>'.$name.'</code>&raquo; template.');
		$result = $this->preprocessing($name, array_merge($this->pool, array($name)));
		$this->pool = $pool;
		return $result;
	}

	function callbackForeach($param){
		$result = '\';' . PHP_EOL;
		$result .= 'foreach('.$this->getVariableStr($param[1]).' as '.(strlen($param[2]) ? '$_'.$param[2].' => ' : '').'$_'.$param[3].'){' . PHP_EOL;
		$result .= 'echo \'';
		return $result;
	}

	function callbackIf($param){
		$result = '\';' . PHP_EOL;
		$result .= ($param[1]=='else'?'}else':'').'if('.preg_replace_callback('/'.$this->VARIABLE.'/', array($this, 'callbackExpressionVariables'), $param[2]).'){' . PHP_EOL;
		$result .= 'echo \'';
		return $result;
	}

	function callbackFor($param){
		$var = $this->getVariableStr($param[1]);
		$step = $param[4];
		$result = '\';' . PHP_EOL;
		$result .= 'for('.$var.'=('.preg_replace_callback('/'.$this->VARIABLE.'/', array($this, 'callbackExpressionVariables'), $param[2]).');'.$var.($step>0?'<=':'>=').'('.preg_replace_callback('/'.$this->VARIABLE.'/', array($this, 'callbackExpressionVariables'), $param[3]).');'.$var.'='.$var.'+('.$step.')){' . PHP_EOL;
		$result .= 'echo \'';
		return $result;
	}

	function callbackExpression($param){
		$result = preg_replace_callback('/'.$this->VARIABLE.'/', array($this, 'callbackExpressionVariables'), $param[1]);
		return $param[0]{1} == '@' ? '\';'.$result.';echo \'' : '\'.('. $result .').\'';
	}

	function callbackExpressionVariables($param){
		return $this->getVariableStr($param[0]);
	}

	function getVariableStr($s){
		$global = $s{0} == '$' ? true : false;
		if ($global) $s = substr($s, 1);
		$result = $global ? '$this->vars' : '';
		$p = explode('.', $s);
		for($i=0; $i<count($p); $i++) $result .= $p[$i]{0} == '%' ? (!$i && !$global ? '$_'.substr($p[$i], 1) : '[$_'.substr($p[$i], 1).']') : "['".$p[$i]."']";
		return $result;
	}

}
?>
Return current item: Dextep Template Engine