*/ class Template { var $file = ""; var $rows = array(); var $vars = array(); var $compiled = ""; /** * Set main template file * * Sets basic template file, which defines basic page layout. * @param string $fname Template name without ".tpl" extension * @return void */ function set_file($fname) { $file = "./template/$fname.tpl"; if(is_file($file) && is_readable($file)) { $this->file = $file; return; } die("Fatal Error: can't open template file /template/$fname.tpl."); } /** * Defines array of first-level template variables * * Variables are passed to function as an array: * array('VAR1' => $value1, 'VAR2' => $value2, ... ) * @param array $vars Array of vars * @return void */ function set_vars($vars) { foreach($vars as $var => $val) { $this->vars["{{$var}}"] = $val; } //dbg($this->vars); } /** * Defines loop variables * @param string $row loop name. Nested loop names are separated by comma * @param array $vars Array of vars * @return void */ function set_row_vars($row, $vars) { $row_arr = explode('.',$row); // [$row][$subrow1][$subrow2][#vars] $c = &$this->rows; $last = $row_arr[sizeof($row_arr)-1]; foreach($row_arr as $r) { if(!isset($c['#rows'][$r]) && $r != $last) { return false; } else if($r == $last) { $c['#rows'][$r][] = array( '#vars' => array(), '#rows' => array(), ); } $c = &$c['#rows'][$r][sizeof($c['#rows'][$r])-1]; //$c['#rows'] = $c['#vars'] = array(); } foreach($vars as $var => $val) { $c['#vars']["{{$var}}"] = $val; } } /** * Load file * @param void $file */ function load_file($file) { $c = file_get_contents($file); $matches = array(); preg_match_all('##', $c, $matches, PREG_SET_ORDER); $f = $r = array(); foreach($matches as $inc) { if(!is_file("./template/{$inc[1]}.tpl") || !is_readable("./template/{$inc[1]}.tpl")) { continue; } $f[] = $inc[0]; $r[] = $this->load_file("./template/{$inc[1]}.tpl"); } $c = str_replace($f, $r, $c); return $c; } /** * Complie template */ function compile() { $c = $this->load_file($this->file); $c = str_replace(array_keys($this->vars), array_values($this->vars), $c); //dbg($this->rows); $matches = array(); preg_match_all('##', $c, $matches, PREG_SET_ORDER); $indexes = array(); $loops = array(); $i = 0; foreach($matches as $match) { $indexes[$match[1]] = "\$i_$i"; $rows = explode('.', $match[1]); $loop = "rows['#rows']['$rows[0]']"; for($j = 1; $j < sizeof($rows); $j++) { $in = implode('.', array_slice($rows, 0, $j)); $loop .= "[{$indexes[$in]}]['#rows']['{$rows[$j]}']"; } $loop .= "); {$indexes[$match[1]]}++){ ?>"; $loops[$match[0]] = $loop; $i++; } $c = str_replace(array_keys($loops), array_values($loops), $c); $c = str_replace('', '', $c); $matches = array(); $vars = array(); preg_match_all('#{([A-Za-z_]+\.[A-Za-z_.]+)}#', $c, $matches, PREG_SET_ORDER); foreach($matches as $match) { $rows = explode('.', $match[1]); $var = "rows"; for($j = 0; $j < sizeof($rows)-1; $j++) { $in = implode('.', array_slice($rows, 0, $j+1)); $var .= "['#rows']['{$rows[$j]}'][{$indexes[$in]}]"; } $var .= "['#vars']['{{$rows[$j]}}']) ?>"; $vars[$match[0]] = $var; $i++; } $c = str_replace(array_keys($vars), array_values($vars), $c); $this->compiled = '?>'.$c; } /** * Compile and display template * @return bool */ function display() { $this->compile(); eval($this->compiled); //file_put_contents('./cache/' . md5($this->file) . '.tpl', $this->compiled); //require('./cache/' . md5($this->file) . '.tpl'); } } $template = new Template(); ?>