* Jerome Lavigne * Luca Lizzeri * * $Id$ ******************************************************************************/ class Template { // general properties var $classname = 'Template'; var $root = ''; var $unresolved = 'keep'; var $deep_parsing = false; // utility arrays var $_files = array(); // holds file handles as keys, filenames as values var $_templates = array(); // holds raw templates from files and blocks var $_vars = array(); // holds variable names as keys, values as values function Template($root = '', $unresolved = 'keep', $deep_parsing = true) { // unresolved variables $this->unresolved = $unresolved; //$unresolved; // keep|remove|comment $this->deep_parsing = $deep_parsing; // root directory if (!empty($root)) $this->setRoot($root); } function setRoot($root) { if (empty($root) || !is_dir($root)) return $this->raiseError("root $root not found or not a directory", 'setRoot', __LINE__, E_USER_ERROR); if (substr($root, - 1) != '/') $root .= '/'; $this->root = $root; } function get($name = null) { if (!(substr($name, 0, 1) == '_')) return $this->$name; } function getVars() { return($this->_vars); } function getVar($var) { return $this->_vars[$var]; } function getFile($file) { return $this->_files[$file]; } function getTemplate($template) { return $this->_templates[$template]; } function setFile($handle, $filename = '') { if (is_array($handle)) $this->_files = array_merge($this->_files, $handle); else if (is_string($handle)) $this->_files[$handle] = $filename; else return $this->raiseError("handle $handle is of unsupported type", 'setFile', __LINE__); } function setVar($name, $value = '') { if (is_array($name)) $this->_vars = array_merge($this->_vars, $name); else if (is_string($name)) $this->_vars[$name] = $value; else if (is_int($name)) $this->_vars[$name] = $value . ''; else return $this->raiseError("name $name is of unsupported type", 'setVar', __LINE__); } function loadFile($handle) { if (!isset($this->_files[$handle])) return $this->raiseError("handle $handle is empty", 'loadFile', __LINE__); if (!file_exists($this->root . $this->_files[$handle])) { return $this->raiseError( "file " . $this->root . $this->_files[$handle] . " for handle $handle is non existent", 'loadFile', __LINE__, E_USER_ERROR); } return( join('', file($this->root . $this->_files[$handle])) ); } function setBlock($parent, $handle, $replacement = '', $raise_error=true) { if (empty($this->_templates[$parent])) { $loaded_file = $this->loadFile($parent); if (is_null($loaded_file)) return $loaded_file; $this->_templates[$parent] = $loaded_file; } if (empty($replacement)) $replacement = strtoupper($handle); $re = '/(.*?)/s'; if (!preg_match($re, $this->_templates[$parent], $m)) { return $raise_error ? $this->raiseError("block $handle not found", 'setBlock', __LINE__, E_USER_ERROR) : false; } $this->_templates[$parent] = str_replace($m[0], '{' . $replacement . '}', $this->_templates[$parent]); $this->_templates[$handle] = $m[1]; return true; } function parseBlock($target, $handle, &$vars, $parent = '') { if (!empty($parent)) { $ret = $this->setBlock($parent, $handle, $target); if (is_null($ret)) return $ret; } else if (empty($this->_templates[$handle])) { return $this->raiseError("no block template for handle $handle", 'parseBlock', __LINE__, E_USER_ERROR); } $block = $this->_templates[$handle]; $template = ''; $varnames = array(); $string = true; foreach ($vars as $k => $v) { if (is_array($vars[$k])) { $string = false; foreach ($vars[$k] as $key => $value) { $varnames[] = '{' . $handle . '_' . $key . '}'; } } else if (is_string($vars[$k]) || is_int($vars[$k])) { $varnames[] = '{' . $handle . '_0}'; } else { return $this->raiseError("unknown vars value", 'parseBlock', __LINE__, E_USER_NOTICE); } break; } $varnames[] = '{' . $handle . '_}'; foreach ($vars as $k => $v) { if ($string) { $template .= str_replace($varnames, array($vars[$k], $k), $block); } else { array_push($vars[$k], $k); $template .= str_replace($varnames, $vars[$k], $block); } } $this->_vars[$target] = $template; } function &parse($target, $handle, $append=false, $raise_error=true) { if (empty($this->_templates[$handle])) { $loaded_file = $this->loadFile($handle); if (is_null($loaded_file)) { return ($raise_error ? $loaded_file : ''); } $this->_templates[$handle] = $loaded_file; } $template = preg_replace_callback('/{([A-Za-z0-9_\-]+)}/', array($this, 'subst'), $this->_templates[$handle]); if ($append && isset($this->_vars[$target])) $this->_vars[$target] .= $template; else $this->_vars[$target] = $template; return $template; } function subst($handle) { $handle =& $handle[1]; $vars =& $this->_vars; if (isset($vars[$handle])) { if ($this->deep_parsing) return preg_replace_callback('/{([A-Za-z0-9_\-]+)}/', array($this, 'subst'), $vars[$handle]); else return $vars[$handle]; } switch ($this->unresolved) { case 'comment': return(''); case 'remove': return(''); default: // 'keep', catches non standard values return('{' . $handle . '}'); } } function pparse($target, $handle, $append = false) { $ret = $this->parse($target, $handle, $append); echo($ret); } function raiseError($message, $method, $line, $type=E_USER_WARNING) { trigger_error( sprintf("%s.%s() line %d: %s", get_class($this), $method, $line, $message), $type); } } ?>