uw Thu Jan 18 12:43:26 2001 EDT Modified files: /php4/pear/HTML IT.php Log: Ok, now finally - special thanks to the Karmamaker Sascha - this is the current IT version from the PHPLib. Tabs replaced by spaces. Error handling has to be pearified and I'm not sure if PHPDoc works with this version.
Index: php4/pear/HTML/IT.php diff -u php4/pear/HTML/IT.php:1.1 php4/pear/HTML/IT.php:1.2 --- php4/pear/HTML/IT.php:1.1 Wed Jan 17 08:15:17 2001 +++ php4/pear/HTML/IT.php Thu Jan 18 12:43:25 2001 @@ -13,19 +13,79 @@ // | obtain it through the world-wide-web, please send a note to | // | [EMAIL PROTECTED] so we can mail you a copy immediately. | // +----------------------------------------------------------------------+ -// | Authors: Ulf Wendel <[EMAIL PROTECTED]> | +// | Authors: Ulf Wendel <[EMAIL PROTECTED]> | // +----------------------------------------------------------------------+ // -// $Id: IT.php,v 1.1 2001/01/17 16:15:17 sbergmann Exp $ +// $Id: IT.php,v 1.2 2001/01/18 20:43:25 uw Exp $ // - /** * Integrated Template - IT * * Well there's not much to say about it. I needed a template class that -* supports a single template file with multiple (nested) blocks inside. +* supports a single template file with multiple (nested) blocks inside and +* a simple block API. +* +* The Isotemplate API is somewhat tricky for a beginner although it is the best +* one you can build. template::parse() [phplib template = Isotemplate] requests +* you to name a source and a target where the current block gets parsed into. +* Source and target can be block names or even handler names. This API gives you +* a maximum of fexibility but you always have to know what you do which is +* quite unusual for php skripter like me. +* +* I noticed that I do not any control on which block gets parsed into which one. +* If all blocks are within one file, the script knows how they are nested and in +* which way you have to parse them. IT knows that inner1 is a child of block2, there's +* no need to tell him about this. +* +* <table border> +* <tr> +* <td colspan=2> +* __global__ +* <p> +* (hidden and automatically added) +* </td> +* </tr> +* <tr> +* <td>block1</td> +* <td> +* <table border> +* <tr> +* <td colspan=2>block2</td> +* </tr> +* <tr> +* <td>inner1</td> +* <td>inner2</td> +* </tr> +* </table> +* </td> +* </tr> +* </table> +* +* To add content to block1 you simply type: +* <code>$tpl->setCurrentBlock("block1");</code> +* and repeat this as often as needed: +* <code> +* $tpl->setVariable(...); +* $tpl->parseCurrentBlock(); +* </code> +* +* To add content to block2 you would type something like: +* <code> +* $tpl->setCurrentBlock("inner1"); +* $tpl->setVariable(...); +* $tpl->parseCurrentBlock(); * +* $tpl->setVariable(...); +* $tpl->parseCurrentBlock(); +* +* $tpl->parse("block1"); +* </code> +* +* This will result in one repition of block1 which contains two repitions +* of inner1. inner2 will be removed if $removeEmptyBlock is set to true which is the +default. +* * Usage: +* <code> * $tpl = new IntegratedTemplate( [string filerootdir] ); * * // load a template or set it with setTemplate() @@ -34,641 +94,739 @@ * // set "global" Variables meaning variables not beeing within a (inner) block * $tpl->setVariable( string variablename, mixed value ); * -* // like with the Isotopp Templates there's a second way to use setVariable() +* // like with the Isotemplates there's a second way to use setVariable() * $tpl->setVariable( array ( string varname => mixed value ) ); * * // Let's use any block, even a deeply nested one * $tpl->setCurrentBlock( string blockname ); * -* // repeat this as often as you neer. +* // repeat this as often as you need it. * $tpl->setVariable( array ( string varname => mixed value ) ); * $tpl->parseCurrentBlock(); * * // get the parsed template or print it: $tpl->show() * $tpl->get(); +* </code> * -* @author Ulf Wendel <[EMAIL PROTECTED]> -* @version $Id: IT.php,v 1.1 2001/01/17 16:15:17 sbergmann Exp $ -* @access public -* @package PHPDoc +* @author Ulf Wendel <[EMAIL PROTECTED]> +* @version $Id: IT.php,v 1.2 2001/01/18 20:43:25 uw Exp $ +* @access public */ class IntegratedTemplate { - /** - * Contains the error objects - * @var array - * @access public - * @see halt(), $printError, $haltOnError - */ - var $err = array(); - - /** - * Print error messages? - * @var boolean - * @access public - * @see halt(), $haltOnError, $err - */ - var $printError = false; - - /** - * Call die() on error? - * @var boolean - * @access public - * @see halt(), $printError, $err - */ - var $haltOnError = false; - - /** - * Clear cache on get()? - * @var boolean - */ - var $clearCache = false; - - /** - * First character of a variable placeholder ( _{_VARIABLE} ). - * @var string - * @access public - * @see $closingDelimiter, $blocknameRegExp, $variablenameRegExp - */ - var $openingDelimiter = "{"; - - /** - * Last character of a variable placeholder ( {VARIABLE_}_ ). - * @var string - * @access public - * @see $openingDelimiter, $blocknameRegExp, $variablenameRegExp - */ - var $closingDelimiter = "}"; - - /** - * RegExp matching a block in the template. - * Per default "sm" is used as the regexp modifier, "i" is missing. - * That means a case sensitive search is done. - * @var string - * @access public - * @see $variablenameRegExp, $openingDelimiter, $closingDelimiter - */ - var $blocknameRegExp = "[0-9A-Za-z_-]+"; - - /** - * RegExp matching a variable placeholder in the template. - * Per default "sm" is used as the regexp modifier, "i" is missing. - * That means a case sensitive search is done. - * @var string - * @access public - * @see $blocknameRegExp, $openingDelimiter, $closingDelimiter - */ - var $variablenameRegExp = "[0-9A-Za-z_-]+"; - - /** - * Full RegExp used to find variable placeholder, filled by the constructor. - * @var string Looks somewhat like @(delimiter varname delimiter)@ - * @see IntegratedTemplate() - */ - var $variablesRegExp = ""; - - /** - * Full RegExp used to find blocks an their content, filled by the constructor. - * @var string - * @see IntegratedTemplate() - */ - var $blockRegExp = ""; - - /** - * Name of the current block. - * @var string - */ - var $currentBlock = "__global__"; - - /** - * Content of the template. - * @var string - */ - var $template = ""; - - /** - * Array of all blocks and their content. - * - * @var array - * @see findBlocks() - */ - var $blocklist = array(); + /** + * Contains the error objects + * @var array + * @access public + * @see halt(), $printError, $haltOnError + */ + var $err = array(); + + /** + * Print error messages? + * @var boolean + * @access public + * @see halt(), $haltOnError, $err + */ + var $printError = false; + + /** + * Call die() on error? + * @var boolean + * @access public + * @see halt(), $printError, $err + */ + var $haltOnError = false; + + /** + * Clear cache on get()? + * @var boolean + */ + var $clearCache = false; + + /** + * First character of a variable placeholder ( _{_VARIABLE} ). + * @var string + * @access public + * @see $closingDelimiter, $blocknameRegExp, $variablenameRegExp + */ + var $openingDelimiter = "{"; + + /** + * Last character of a variable placeholder ( {VARIABLE_}_ ). + * @var string + * @access public + * @see $openingDelimiter, $blocknameRegExp, $variablenameRegExp + */ + var $closingDelimiter = "}"; + + /** + * RegExp matching a block in the template. + * Per default "sm" is used as the regexp modifier, "i" is missing. + * That means a case sensitive search is done. + * @var string + * @access public + * @see $variablenameRegExp, $openingDelimiter, $closingDelimiter + */ + var $blocknameRegExp = "[0-9A-Za-z_-]+"; + + /** + * RegExp matching a variable placeholder in the template. + * Per default "sm" is used as the regexp modifier, "i" is missing. + * That means a case sensitive search is done. + * @var string + * @access public + * @see $blocknameRegExp, $openingDelimiter, $closingDelimiter + */ + var $variablenameRegExp = "[0-9A-Za-z_-]+"; + + /** + * RegExp used to find variable placeholder, filled by the constructor. + * @var string Looks somewhat like @(delimiter varname delimiter)@ + * @access public + * @see IntegratedTemplate() + */ + var $variablesRegExp = ""; + + /** + * RegExp used to strip unused variable placeholder. + * @brother $variablesRegExp + */ + var $removeVariablesRegExp = ""; + + /** + * Controls the handling of unknown variables, default is remove. + * @var boolean + * @access public + */ + var $removeUnknownVariables = true; + + /** + * Controls the handling of empty blocks, default is remove. + * @var boolean + * @access public + */ + var $removeEmptyBlocks = true; + + /** + * RegExp used to find blocks an their content, filled by the constructor. + * @var string + * @see IntegratedTemplate() + */ + var $blockRegExp = ""; + + /** + * Name of the current block. + * @var string + */ + var $currentBlock = "__global__"; + + /** + * Content of the template. + * @var string + */ + var $template = ""; + + /** + * Array of all blocks and their content. + * + * @var array + * @see findBlocks() + */ + var $blocklist = array(); - /** - * Array with the parsed content of a block. - * - * @var array - */ - var $blockdata = array(); - - /** - * Array of variables in a block. - * @var array - */ - var $blockvariables = array(); - - /** - * Array of inner blocks of a block. - * @var array - */ - var $blockinner = array(); - - /** - * Future versions will use this... - * @var array - */ - var $blocktypes = array(); + /** + * Array with the parsed content of a block. + * + * @var array + */ + var $blockdata = array(); + + /** + * Array of variables in a block. + * @var array + */ + var $blockvariables = array(); + + /** + * Array of inner blocks of a block. + * @var array + */ + var $blockinner = array(); + + /** + * List of blocks to preverse even if they are "empty". + * + * This is something special. Sometimes you have blocks that + * should be preserved although they are empty (no placeholder replaced). + * Think of a shopping basket. If it's empty you have to drop a message to + * the user. If it's filled you have to show the contents of the shopping baseket. + * Now where do you place the message that the basket is empty? It's no good + * idea to place it in you applications as customers tend to like unecessary minor + * text changes. Having another template file for an empty basket means that it's + * very likely that one fine day the filled and empty basket templates have +different + * layout. I decided to introduce blocks that to not contain any placeholder but +only + * text such as the message "Your shopping basked is empty". + * + * Now if there is no replacement done in such a block the block will be +recognized + * as "empty" and by default ($removeEmptyBlocks = true) be stripped off. To avoid +this + * you can now call touchBlock() to avoid this. + * + * The array $touchedBlocks stores a list of touched block which must not be +removed even + * if they are empty. + * + * @var array $touchedBlocks + * @see touchBlock(), $removeEmptyBlocks + */ + var $touchedBlocks = array(); - /** - * Variable cache. - * - * Variables get cached before any replacement is done. - * Advantage: empty blocks can be removed automatically. - * Disadvantage: might take some more memory - * - * @var array - * @see setVariable(), $clearCacheOnParse - */ - var $variableCache = array(); - - /** - * @var boolean - */ - var $clearCacheOnParse = true; - - /** - * Controls the handling of unknown variables, default is remove. - * @var boolean - */ - var $removeUnknownVariables = true; - - /** - * Controls the handling of empty blocks, default is remove. - * @var boolean - */ - var $removeEmptyBlocks = true; - - /** - * Root directory for all file operations. - * The string gets prefixed to all filenames given. - * @var string - * @see IntegratedTemplate(), setRoot() - */ - var $fileRoot = ""; - - /** - * Internal flag indicating that a blockname was used multiple times. - * @var boolean - */ - var $flagBlocktrouble = false; - - /** - * Flag indicating that the global block was parsed. - * @var boolean - */ - var $flagGlobalParsed = false; - - /** - * Builds some complex regular expressions and optinally sets the file root directory. - * - * Make sure that you call this constructor if you derive your template - * class from this one. - * - * @param string File root directory, prefix for all filenames given to the object. - * @see setRoot() - */ - function IntegratedTemplate($root = "") { - - $this->variablesRegExp = "@".$this->openingDelimiter."(".$this->variablenameRegExp.")".$this->closingDelimiter."@sm"; - $this->blockRegExp = '@!--\s+BEGIN\s+('.$this->blocknameRegExp.')\s+-->(.*)<!--\s+END\s+\1\s+-->@sm'; - - $this->setRoot($root); - - } // end constructor - - /** - * Print a certain block with all replacements done. - * @brother get() - */ - function show($block = "__global__") { - print $this->get($block); - } // end func show - - /** - * Returns a block with all replacements done. - * - * @param string name of the block - * @return string - * @access public - * @see show() - */ - function get($block = "__global__") { - - if ("__global__" == $block && !$this->flagGlobalParsed) - $this->parse("__global__"); - - if (!isset($this->blocklist[$block])) { - $this->halt("The block '$block' was not found in the template.", __FILE__, __LINE__); - return true; - } - - if ($this->clearCache) { - - $data = (isset($this->blockdata[$block])) ? $this->blockdata[$block] : ""; - unset($this->blockdata[$block]); - return $data; - - } else { + /** + * Variable cache. + * + * Variables get cached before any replacement is done. + * Advantage: empty blocks can be removed automatically. + * Disadvantage: might take some more memory + * + * @var array + * @see setVariable(), $clearCacheOnParse + */ + var $variableCache = array(); - return (isset($this->blockdata[$block])) ? $this->blockdata[$block] : ""; - - } + /** + * Clear the variable cache on parse? + * + * If you're not an expert just leave the default false. + * True reduces memory consumption somewhat if you tend to + * add lots of values for unknown placeholder. + * + * @var boolean + */ + var $clearCacheOnParse = false; + + /** + * Root directory for all file operations. + * The string gets prefixed to all filenames given. + * @var string + * @see IntegratedTemplate(), setRoot() + */ + var $fileRoot = ""; + + /** + * Internal flag indicating that a blockname was used multiple times. + * @var boolean + */ + var $flagBlocktrouble = false; + + /** + * Flag indicating that the global block was parsed. + * @var boolean + */ + var $flagGlobalParsed = false; + + /** + * EXPERIMENTAL! FIXME! + * Flag indication that a template gets cached. + * + * Complex templates require some times to be preparsed + * before the replacement can take place. Often I use + * one template file over and over again but I don't know + * before that I will use the same template file again. + * Now IT could notice this and skip the preparse. + * + * @var boolean + */ + var $flagCacheTemplatefile = true; + + /** + * EXPERIMENTAL! FIXME! + */ + var $lastTemplatefile = ""; + + /** + * Builds some complex regular expressions and optinally sets the file root +directory. + * + * Make sure that you call this constructor if you derive your template + * class from this one. + * + * @param string File root directory, prefix for all filenames given to the +object. + * @see setRoot() + */ + function IntegratedTemplate($root = "") { + + $this->variablesRegExp = "@" . $this->openingDelimiter . "(" . +$this->variablenameRegExp . ")" . $this->closingDelimiter . "@sm"; + $this->removeVariablesRegExp = "@" . $this->openingDelimiter . "\s*(" . +$this->variablenameRegExp . ")\s*" . $this->closingDelimiter . "@sm"; + + $this->blockRegExp = '@<!--\s+BEGIN\s+(' . $this->blocknameRegExp . +')\s+-->(.*)<!--\s+END\s+\1\s+-->@sm'; - } // end func get() - - /** - * Parses the given block. - * - * @param string name of the block to be parsed - * @access public - * @see parseCurrentBlock() - */ - function parse($block = "__global__", $flag_recursion = false) { - - if (!isset($this->blocklist[$block])) { - $this->halt("The block '$block' was not found in the template.", __FILE__, __LINE__); - return false; - } - - if ("__global__" == $block) - $this->flagGlobalParsed = true; - - $regs = array(); - $values = array(); - - if ($this->clearCacheOnParse) { - - reset($this->variableCache); - while (list($name, $value)=each($this->variableCache)) { - $regs[] = "@".$this->openingDelimiter.$name.$this->closingDelimiter."@"; - $values[] = $value; - } - $this->variableCache = array(); - - } else { - - reset($this->blockvariables[$block]); - while (list($k, $allowedvar)=each($this->blockvariables[$block])) { - - if (isset($this->variableCache[$allowedvar])) { - $regs[] = "@".$this->openingDelimiter.$allowedvar.$this->closingDelimiter."@"; - $values[] = $this->variableCache[$allowedvar]; - unset($this->variableCache[$allowedvar]); - } - - } - - } - - $outer = (0 == count($regs)) ? $this->blocklist[$block] : preg_replace($regs, $values, $this->blocklist[$block]); - $empty = (0 == count($values)) ? true : false; - - if (isset($this->blockinner[$block])) { - - reset($this->blockinner[$block]); - while (list($k, $innerblock)=each($this->blockinner[$block])) { - - $this->parse($innerblock, true); - if (""!=$this->blockdata[$innerblock]) - $empty = false; - - $placeholder = $this->openingDelimiter."__".$innerblock."__".$this->closingDelimiter; - $outer = str_replace($placeholder, $this->blockdata[$innerblock], $outer); - $this->blockdata[$innerblock] = ""; + $this->setRoot($root); + } // end constructor + + /** + * Print a certain block with all replacements done. + * @brother get() + */ + function show($block = "__global__") { + print $this->get($block); + } // end func show + + /** + * Returns a block with all replacements done. + * + * @param string name of the block + * @return string + * @access public + * @see show() + */ + function get($block = "__global__") { + + if ("__global__" == $block && !$this->flagGlobalParsed) + $this->parse("__global__"); + + if (!isset($this->blocklist[$block])) { + $this->halt("The block '$block' was not found in the template.", +__FILE__, __LINE__); + return true; + } + + if ($this->clearCache) { + + $data = (isset($this->blockdata[$block])) ? $this->blockdata[$block] : ""; + unset($this->blockdata[$block]); + return $data; + + } else { + + return (isset($this->blockdata[$block])) ? $this->blockdata[$block] : ""; + + } + + } // end func get() + + /** + * Parses the given block. + * + * @param string name of the block to be parsed + * @access public + * @see parseCurrentBlock() + */ + function parse($block = "__global__", $flag_recursion = false) { + + if (!isset($this->blocklist[$block])) { + $this->halt("The block '$block' was not found in the template.", +__FILE__, __LINE__); + return false; + } + + if ("__global__" == $block) + $this->flagGlobalParsed = true; + + $regs = array(); + $values = array(); + + if ($this->clearCacheOnParse) { + + foreach ($this->variableCache as $name => $value) { + $regs[] = "@" . $this->openingDelimiter . $name . +$this->closingDelimiter . "@"; + $values[] = $value; + } + $this->variableCache = array(); + + } else { + + foreach ($this->blockvariables[$block] as $allowedvar => $v) { + + if (isset($this->variableCache[$allowedvar])) { + $regs[] = "@".$this->openingDelimiter . $allowedvar . +$this->closingDelimiter . "@"; + $values[] = $this->variableCache[$allowedvar]; + unset($this->variableCache[$allowedvar]); + } + + } + + } + + $outer = (0 == count($regs)) ? $this->blocklist[$block] : preg_replace($regs, +$values, $this->blocklist[$block]); + $empty = (0 == count($values)) ? true : false; + + if (isset($this->blockinner[$block])) { + + foreach ($this->blockinner[$block] as $k => $innerblock) { + + $this->parse($innerblock, true); + if ("" != $this->blockdata[$innerblock]) + $empty = false; + + $placeholder = $this->openingDelimiter . "__" . $innerblock . "__" . +$this->closingDelimiter; + $outer = str_replace($placeholder, $this->blockdata[$innerblock], +$outer); + $this->blockdata[$innerblock] = ""; } + } if ($this->removeUnknownVariables) - $outer = preg_replace($this->variablesRegExp, "", $outer); - - if ($empty) { - - if (!$this->removeEmptyBlocks) - $this->blockdata[$block].= $outer; - - } else { - - $this->blockdata[$block].= $outer; - - } - - return $empty; - } // end func parse - - /** - * Parses the current block - * @see parse(), setCurrentBlock(), $currentBlock - * @access public - */ - function parseCurrentBlock() { - return $this->parse($this->currentBlock); - } // end func parseCurrentBlock - - /** - * Sets a variable value. - * - * The function can be used eighter like setVariable( "varname", "value") - * or with one array $variables["varname"] = "value" given setVariable($variables) - * quite like phplib templates set_var(). - * - * @param mixed string with the variable name or an array %variables["varname"] = "value" - * @param string value of the variable or empty if $variable is an array. - * @param string prefix for variable names - * @access public - */ - function setVariable($variable, $value="") { - - if (is_array($variable)) { - - reset($variable); - while (list($var, $value)=each($variable)) - $this->variableCache[$var] = $value; - - } else { - - $this->variableCache[$variable] = $value; - - } - - } // end func setVariable - - /** - * Sets the name of the current block that is the block where variables are added. - * - * @param string name of the block - * @return boolean false on failure otherwise true - * @access public - */ - function setCurrentBlock($block = "__global__") { - - if (!isset($this->blocklist[$block])) { - $this->halt("Can't find the block '$block' in the template.", __FILE__, __LINE__); - return false; - } - - $this->currentBlock = $block; - - return true; - } // end func setCurrentBlock - - /** - * Clears all datafields of the object and rebuild the internal blocklist - * - * LoadTemplatefile() and setTemplate() automatically call this function - * when a new template is given. Don't use this function - * unless you know what you're doing. - * - * @access public - * @see free() - */ - function init() { - - $this->free(); - $this->findBlocks($this->template); - $this->buildBlockvariablelist(); - - } // end func init - - /** - * Clears all datafields of the object. - * - * Don't use this function unless you know what you're doing. - * - * @access public - * @see init() - */ - function free() { - - $this->err[] = ""; - - $this->currentBlock = "__global__"; - - $this->variableCache = array(); - $this->blocklist = array(); - $this->blockvariables = array(); - $this->blockinner = array(); - $this->blockdata = array(); - $this->blocklookup = array(); - $this->blocktypes = array(); - - $this->flagBlocktrouble = false; - $this->flagGlobalParsed = false; - - } // end func free - - /** - * Sets the template. - * - * You can eighter load a template file from disk with LoadTemplatefile() or set the - * template manually using this function. - * - * @param string template content - * @param boolean Unbekannte, nicht ersetzte Platzhalter entfernen? - * @param boolean remove unknown/unused variables? - * @param boolean remove empty blocks? - * @see LoadTemplatefile(), $template - * @access public - */ - function setTemplate($template, $removeUnknownVariables = true, $removeEmptyBlocks = false) { - if (""==$template) { - $this->halt("The given string is empty.", __FILE__, __LINE__); - return false; - } - - $this->removeUnknownVariables = $removeUnknownVariables; - $this->removeEmptyBlocks = $removeEmptyBlocks; - - $this->template = '<!-- BEGIN __global__ -->'.$template.'<!-- END __global__ -->'; - $this->init(); - - if ($this->flagBlocktrouble) - return false; - - return true; - } // end func setTemplate - - /** - * Reads a template file from the disk. - * - * @param string name of the template file, full path! - * @param boolean remove unknown/unused variables? - * @param boolean remove empty blocks? - * @access public - * @return boolean false on failure, otherwise true - * @see $template, setTemplate() - */ - function loadTemplatefile($filename, $removeUnknownVariables = true, $removeEmptyBlocks = true) { - - $template = $this->getfile($filename); - - return $this->setTemplate($this->getFile($filename), $removeUnknownVariables, $removeEmptyBlocks); - } // end func LoadTemplatefile - - /** - * Sets the file root. The file root gets prefixed to all filenames passed to the object. - * - * Make sure that you override this function when using the class - * on windows. - * - * @param string - * @see IntegratedTemplate() - * @access public - */ - function setRoot($root) { - - if (""!=$root && "/"!= substr($root, -1)) - $root.="/"; - - $this->fileRoot = $root; - - } // end func setRoot - - /** - * Build a list of all variables within a block - */ - function buildBlockvariablelist() { - - reset($this->blocklist); - while (list($name, $content)=each($this->blocklist)) { - preg_match_all( $this->variablesRegExp, $content, $regs ); - $this->blockvariables[$name] = $regs[1]; - } - - } // end func buildBlockvariablelist - - /** - * Returns a list of all - */ - function getGlobalvariables() { - - $regs = array(); - $values = array(); - - reset($this->blockvariables["__global__"]); - while (list($k, $allowedvar)=each($this->blockvariables["__global__"])) { - - if (isset($this->variableCache[$allowedvar])) { - $regs[] = "@".$this->openingDelimiter.$allowedvar.$this->closingDelimiter."@"; - $values[] = $this->variableCache[$allowedvar]; - unset($this->variableCache[$allowedvar]); - } - - } - - return array($regs, $values); - } // end func getGlobalvariables - - /** - * Recusively builds a list of all blocks within the template. - * - * @param string string that gets scanned - * @access private - * @see $blocklist - */ - function findBlocks($string) { - - $blocklist = array(); - - if (preg_match_all($this->blockRegExp, $string, $regs, PREG_SET_ORDER)) { - - reset($regs); - while (list($k, $match)=each($regs)) { - - $blockname = $match[1]; - $blockcontent = $match[2]; - - if (isset($this->blocklist[$blockname])) { - $this->halt("The name of a block must be unique within a template. Found '$blockname' twice. Unpredictable results may appear.", __FILE__, __LINE__); - $this->flagBlocktrouble = true; - } - - $this->blocklist[$blockname] = $blockcontent; - $this->blockdata[$blockname] = ""; - - $blocklist[] = $blockname; - - $inner = $this->findBlocks($blockcontent); - reset($inner); - while (list($k, $name)=each($inner)) { - - $pattern = sprintf('@<!--\s+BEGIN\s+%s\s+-->(.*)<!--\s+END\s+%s\s+-->@sm', - $name, - $name - ); - - $this->blocklist[$blockname] = preg_replace( $pattern, - $this->openingDelimiter."__".$name."__".$this->closingDelimiter, - $this->blocklist[$blockname] - ); - $this->blockinner[$blockname][] = $name; - $this->blockparents[$name] = $blockname; - - } - - } - - } - - return $blocklist; - } // end func findBlocks - - /** - * Reads a file from disk and returns its content. - * @param string Filename - * @return string Filecontent - */ - function getFile($filename) { - - if ("/" == substr($filename, 0, 1)) - $filename = substr($filename, 1); - - $filename = $this->fileRoot.$filename; - - if ( !($fh = @fopen($filename, "r")) ) { - $this->halt("Can't read '$filename'.", __FILE__, __LINE__); - return ""; - } - - $content = fread($fh, filesize($filename)); - fclose($fh); - - return $content; - } // end func getFile - - /** - * Error Handling function. - * @param string error message - * @param mixed File where the error occured - * @param int Line where the error occured - * @see $err - */ - function halt($message, $file="", $line=0) { - - $message = sprintf("IntegratedTemplate Error: %s [File: %s, Line: %d]", - $message, - $file, - $line - ); - - $this->err[] = $message; - - if ($this->printError) - print $message; - - if ($this->haltOnError) - die($message); + $outer = preg_replace($this->removeVariablesRegExp, "", $outer); + + if ($empty) { + + if (!$this->removeEmptyBlocks) { + + $this->blockdata[$block ].= $outer; + + } else { + + if (isset($this->touchedBlocks[$block])) + $this->blockdata[$block] .= $outer; + + } + + } else { + + $this->blockdata[$block] .= $outer; + + } + + return $empty; + } // end func parse + + /** + * Parses the current block + * @see parse(), setCurrentBlock(), $currentBlock + * @access public + */ + function parseCurrentBlock() { + return $this->parse($this->currentBlock); + } // end func parseCurrentBlock + + /** + * Sets a variable value. + * + * The function can be used eighter like setVariable( "varname", "value") + * or with one array $variables["varname"] = "value" given setVariable($variables) + * quite like phplib templates set_var(). + * + * @param mixed string with the variable name or an array +%variables["varname"] = "value" + * @param string value of the variable or empty if $variable is an array. + * @param string prefix for variable names + * @access public + */ + function setVariable($variable, $value = "") { + + if (is_array($variable)) { + + $this->variableCache = array_merge($this->variableCache, $variable); + + } else { + + $this->variableCache[$variable] = $value; + + } + + } // end func setVariable + + /** + * Sets the name of the current block that is the block where variables are added. + * + * @param string name of the block + * @return boolean false on failure, otherwise true + * @access public + */ + function setCurrentBlock($block = "__global__") { + + if (!isset($this->blocklist[$block])) { + $this->halt("Can't find the block '$block' in the template.", __FILE__, +__LINE__); + return false; + } + + $this->currentBlock = $block; + + return true; + } // end func setCurrentBlock + + /** + * Preserves an empty block even if removeEmptyBlocks is true. + * + * @param string name of the block + * @return boolean false on false, otherwise true + * @access public + * @see $removeEmptyBlocks + */ + function touchBlock($block) { + + if (!isset($this->blocklist[$block])) { + $this->halt("Can't find the block '$block' in the template.", __FILE__, +__LINE__); + return false; + } + + $this->touchedBlocks[$block] = true; + + return true; + } // end func touchBlock + + /** + * Clears all datafields of the object and rebuild the internal blocklist + * + * LoadTemplatefile() and setTemplate() automatically call this function + * when a new template is given. Don't use this function + * unless you know what you're doing. + * + * @access public + * @see free() + */ + function init() { + + $this->free(); + $this->findBlocks($this->template); + $this->buildBlockvariablelist(); + + } // end func init + + /** + * Clears all datafields of the object. + * + * Don't use this function unless you know what you're doing. + * + * @access public + * @see init() + */ + function free() { + + $this->err[] = ""; + + $this->currentBlock = "__global__"; + + $this->variableCache = array(); + $this->blocklist = array(); + $this->blockvariables = array(); + $this->blockinner = array(); + $this->blockdata = array(); + $this->blocklookup = array(); + $this->touchedBlocks = array(); + + $this->flagBlocktrouble = false; + $this->flagGlobalParsed = false; + + } // end func free + + /** + * Sets the template. + * + * You can eighter load a template file from disk with LoadTemplatefile() or set +the + * template manually using this function. + * + * @param string template content + * @param boolean Unbekannte, nicht ersetzte Platzhalter entfernen? + * @param boolean remove unknown/unused variables? + * @param boolean remove empty blocks? + * @see LoadTemplatefile(), $template + * @access public + */ + function setTemplate($template, $removeUnknownVariables = true, +$removeEmptyBlocks = true) { + + $this->removeUnknownVariables = $removeUnknownVariables; + $this->removeEmptyBlocks = $removeEmptyBlocks; + + if ("" == $template && $this->flagCacheTemplatefile) { + + $this->variableCache = array(); + $this->blockdata = array(); + $this->touchedBlocks = array(); + $this->currentBlock = "__global__"; + + } else { + + $this->template = '<!-- BEGIN __global__ -->' . $template . '<!-- END +__global__ -->'; + $this->init(); + + } + + if ($this->flagBlocktrouble) + return false; + + return true; + } // end func setTemplate + + /** + * Reads a template file from the disk. + * + * @param string name of the template file + * @param bool How to handle unknown variables. + * @param bool How to handle empty blocks. + * @access public + * @return boolean false on failure, otherwise true + * @see $template, setTemplate(), $removeUnknownVariables, $removeEmptyBlocks + */ + function loadTemplatefile($filename, $removeUnknownVariables = true, +$removeEmptyBlocks = true) { + + $template = ""; + if (!$this->flagCacheTemplatefile || $this->lastTemplatefile != $filename) + $template = $this->getfile($filename); + + $this->lastTemplatefile = $filename; + + return $this->setTemplate($template, $removeUnknownVariables, +$removeEmptyBlocks, true); + } // end func LoadTemplatefile + + /** + * Sets the file root. The file root gets prefixed to all filenames passed to the +object. + * + * Make sure that you override this function when using the class + * on windows. + * + * @param string + * @see IntegratedTemplate() + * @access public + */ + function setRoot($root) { + + if ("" != $root && "/" != substr($root, -1)) + $root .= "/"; + + $this->fileRoot = $root; + + } // end func setRoot + + /** + * Build a list of all variables within of a block + */ + function buildBlockvariablelist() { + + foreach ($this->blocklist as $name => $content) { + preg_match_all( $this->variablesRegExp, $content, $regs ); + + if (0 != count($regs[1])) { + + foreach ($regs[1] as $k => $var) + $this->blockvariables[$name][$var] = true; + + } else { + + $this->blockvariables[$name] = array(); + + } + + } + + } // end func buildBlockvariablelist + + /** + * Returns a list of all + */ + function getGlobalvariables() { + + $regs = array(); + $values = array(); + + foreach ($this->blockvariables["__global__"] as $allowedvar => $v) { + + if (isset($this->variableCache[$allowedvar])) { + $regs[] = "@" . $this->openingDelimiter . $allowedvar . +$this->closingDelimiter."@"; + $values[] = $this->variableCache[$allowedvar]; + unset($this->variableCache[$allowedvar]); + } + + } + + return array($regs, $values); + } // end func getGlobalvariables + + /** + * Recusively builds a list of all blocks within the template. + * + * @param string string that gets scanned + * @access private + * @see $blocklist + */ + function findBlocks($string) { + + $blocklist = array(); + + if (preg_match_all($this->blockRegExp, $string, $regs, PREG_SET_ORDER)) { + + foreach ($regs as $k => $match) { + + $blockname = $match[1]; + $blockcontent = $match[2]; + + if (isset($this->blocklist[$blockname])) { + $this->halt("The name of a block must be unique within a +template. Found '$blockname' twice. Unpredictable results may appear.", __FILE__, +__LINE__); + $this->flagBlocktrouble = true; + } + + $this->blocklist[$blockname] = $blockcontent; + $this->blockdata[$blockname] = ""; + + $blocklist[] = $blockname; + + $inner = $this->findBlocks($blockcontent); + foreach ($inner as $k => $name) { + + $pattern = +sprintf('@<!--\s+BEGIN\s+%s\s+-->(.*)<!--\s+END\s+%s\s+-->@sm', + $name, + $name + ); + + $this->blocklist[$blockname] = preg_replace( $pattern, + +$this->openingDelimiter . "__" . $name . "__" . $this->closingDelimiter, + +$this->blocklist[$blockname] + ); + $this->blockinner[$blockname][] = $name; + $this->blockparents[$name] = $blockname; + + } + + } + + } + + return $blocklist; + } // end func findBlocks + + /** + * Reads a file from disk and returns its content. + * @param string Filename + * @return string Filecontent + */ + function getFile($filename) { + + if ("/" == $filename{0} && "/" == substr($this->fileRoot, -1)) + $filename = substr($filename, 1); + + $filename = $this->fileRoot . $filename; + + if (!($fh = @fopen($filename, "r"))) { + $this->halt("Can't read '$filename'.", __FILE__, __LINE__); + return ""; + } + + $content = fread($fh, filesize($filename)); + fclose($fh); + + return $content; + } // end func getFile + + /** + * Error Handling function. + * @param string error message + * @param mixed File where the error occured + * @param int Line where the error occured + * @see $err + */ + function halt($message, $file = "", $line = 0) { + + + $message = sprintf("IntegratedTemplate Error: %s [File: %s, Line: %d]", + $message, + $file, + $line + ); + + $this->err[] = $message; + + if ($this->printError) + print $message; + + if ($this->haltOnError) + die($message); - } // end func halt - + } // end func halt + } // end class IntegratedTemplate ?>
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] To contact the list administrators, e-mail: [EMAIL PROTECTED]