Source for file ITX.php
Documentation is available at ITX.php
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2005 Ulf Wendel, Pierre-Alain Joye |
// +----------------------------------------------------------------------+
// | This source file is subject to the New BSD license, That is bundled |
// | with this package in the file LICENSE, and is available through |
// | the world-wide-web at |
// | http://www.opensource.org/licenses/bsd-license.php |
// | If you did not receive a copy of the new BSD license and are unable |
// | to obtain it through the world-wide-web, please send a note to |
// | pajoye@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Author: Ulf Wendel <ulf.wendel@phpdoc.de> |
// | Pierre-Alain Joye <pajoye@php.net> |
// +----------------------------------------------------------------------+
// $Id: ITX.php,v 1.16 2006/08/17 15:47:22 dsp Exp $
require_once 'HTML/Template/IT.php';
require_once 'HTML/Template/IT_Error.php';
* Integrated Template Extension - ITX
* With this class you get the full power of the phplib template class.
* You may have one file with blocks in it but you have as well one main file
* and multiple files one for each block. This is quite usefull when you have
* user configurable websites. Using blocks not in the main template allows
* you to modify some parts of your layout easily.
* Note that you can replace an existing block and add new blocks at runtime.
* Adding new blocks means changing a variable placeholder to a block.
* @author Ulf Wendel <uw@netuse.de>
* @version $Id: ITX.php,v 1.16 2006/08/17 15:47:22 dsp Exp $
* @package HTML_Template_IT
* Array with all warnings.
* @see $printWarning, $haltOnWarning, warning()
* @see $haltOnWarning, $warn, warning()
* @see $warn, $printWarning, warning()
* RegExp used to test for a valid blockname.
* Functionnameprefix used when searching function calls in the template.
* RegExp used to grep function calls in the template.
* The variable gets set by the constructor.
* @see HTML_Template_IT()
* List of functions found in the template.
* List of callback functions specified by the user.
* Builds some complex regexps and calls the constructor
* Make sure that you call this constructor if you derive your own
* template class from this one.
* @see HTML_Template_IT()
} // end func constructor
$this->buildFunctionlist ();
// we don't need it any more
* Replaces an existing block with new content.
* This function will replace a block of the template and all blocks
* contained in the replaced block and add a new block insted, means
* you can dynamically change your template.
* Note that changing the template structure violates one of the IT[X]
* development goals. I've tried to write a simple to use template engine
* supporting blocks. In contrast to other systems IT[X] analyses the way
* you've nested blocks and knows which block belongs into another block.
* The nesting information helps to make the API short and simple. Replacing
* blocks does not only mean that IT[X] has to update the nesting
* information (relatively time consumpting task) but you have to make sure
* that you do not get confused due to the template change itself.
* @param string Blockname
* @param string Blockcontent
* @param boolean true if the new block inherits the content
* @see replaceBlockfile(), addBlock(), addBlockfile()
function replaceBlock($block, $template, $keep_content = false )
" does not exist in the template and thus it can't be replaced.",
return new IT_Error('No block content given.', __FILE__ , __LINE__ );
// remove all kinds of links to the block / data of the block
$this->removeBlockData ($block);
$template = " <!-- BEGIN $block -->" . $template . " <!-- END $block -->";
$parents = $this->blockparents[$block];
$this->blockparents[$block] = $parents;
// KLUDGE: rebuild the list for all block - could be done faster
// old TODO - I'm not sure if we need this
} // end func replaceBlock
* Replaces an existing block with new content from a file.
* @brother replaceBlock()
* @param string Blockname
* @param string Name of the file that contains the blockcontent
* @param boolean true if the new block inherits the content of the old block
} // end func replaceBlockfile
* Adds a block to the template changing a variable placeholder
* to a block placeholder.
* Add means "replace a variable placeholder by a new block".
* This is different to PHPLibs templates. The function loads a
* block, creates a handle for it and assigns it to a certain
* variable placeholder. To to the same with PHPLibs templates you would
* call set_file() to create the handle and parse() to assign the
* parsed block to a variable. By this PHPLibs templates assume
* that you tend to assign a block to more than one one placeholder.
* To assign a parsed block to more than only the placeholder you specify
* in this function you have to use a combination of getBlock()
* As no updates to cached data is necessary addBlock() and addBlockfile()
* are rather "cheap" meaning quick operations.
* The block content must not start with <!-- BEGIN blockname -->
* and end with <!-- END blockname --> this would cause overhead and
* @param string Name of the variable placeholder, the name must be unique
* @param string Name of the block to be added
* @param string Content of the block
function addBlock($placeholder, $blockname, $template)
// Don't trust any user even if it's a programmer or yourself...
if ($placeholder == '') {
return new IT_Error('No variable placeholder given.',
} elseif ($blockname == '' ||
return new IT_Error(" No or invalid blockname '$blockname' given." ,
} elseif ($template == '') {
return new IT_Error('No block content given.', __FILE__ , __LINE__ );
} elseif (isset ($this->blocklist[$blockname])) {
return new IT_Error('The block already exists.',
// find out where to insert the new block
if (count($parents) == 0 ) {
"The variable placeholder".
" '$placeholder' was not found in the template." ,
} elseif (count($parents) > 1 ) {
while (list ($k, $parent) = each($parents)) {
return new IT_Error("The variable placeholder "." '$placeholder'".
" must be unique, found in multiple blocks '$msg'." ,
$template = " <!-- BEGIN $blockname -->" . $template . " <!-- END $blockname -->";
return false; // findBlocks() already throws an exception
$this->deleteFromBlockvariablelist ($parents[0 ], $placeholder);
$this->updateBlockvariablelist ($blockname);
* Adds a block taken from a file to the template changing a variable
* placeholder to a block placeholder.
* @param string Name of the variable placeholder to be converted
* @param string Name of the block to be added
* @param string File that contains the block
return $this->addBlock($placeholder, $blockname, $this->getFile($filename));
} // end func addBlockfile
* Returns the name of the (first) block that contains
* the specified placeholder.
* @param string Name of the placeholder you're searching
* @param string Name of the block to scan. If left out (default)
* all blocks are scanned.
* @return string Name of the (first) block that contains
* the specified placeholder.
* If the placeholder was not found or an error occured
* an empty string is returned.
if ($placeholder == '') {
new IT_Error('No placeholder name given.', __FILE__ , __LINE__ );
if ($block != '' && !isset ($this->blocklist[$block])) {
new IT_Error(" Unknown block '$block'." , __FILE__ , __LINE__ );
// name of the block where the given placeholder was found
// search the value in the list of blockvariables
while (list ($k, $variable) = each($variables)) {
if ($k == $placeholder) {
// search all blocks and return the name of the first block that
// contains the placeholder
if (is_array($variables) && isset ($variables[$placeholder])) {
} // end func placeholderExists
* Checks the list of function calls in the template and
* calls their callback function.
if (isset ($this->callback[$function['name']])) {
if ($this->callback[$function['name']]['expandParameters']) {
$callFunction = 'call_user_func_array';
$callFunction = 'call_user_func';
if ($this->callback[$function['name']]['object'] != '') {
&$GLOBALS[$this->callback[$function['name']]['object']],
$this->callback[$function['name']]['function']),
$this->callback[$function['name']]['function'],
} // end func performCallback
* Returns a list of all function calls in the current template.
} // end func getFunctioncalls
* Replaces a function call with the given replacement.
* @param string Replacement
$this->variableCache['__function' . $functionID . '__'] = $replacement;
} // end func setFunctioncontent
* Sets a callback function.
* IT[X] templates (note the X) can contain simple function calls.
* "function call" means that the editor of the template can add
* special placeholder to the template like 'func_h1("embedded in h1")'.
* IT[X] will grab this function calls and allow you to define a callback
* This is an absolutely evil feature. If your application makes heavy
* use of such callbacks and you're even implementing if-then etc. on
* the level of a template engine you're reiventing the wheel... - that's
* actually how PHP came into life. Anyway, sometimes it's handy.
* Consider also using XML/XSLT or native PHP. And please do not push
* IT[X] any further into this direction of adding logics to the template
* For those of you ready for the X in IT[X]:
* function h_one($args) {
* return sprintf('<h1>%s</h1>', $args[0]);
* $itx = new HTML_Template_ITX( ... );
* $itx->setCallbackFunction('h1', 'h_one');
* $itx->performCallback();
* func_h1('H1 Headline');
* @param string Function name in the template
* @param string Name of the callback function
* @param string Name of the callback object
* @param boolean If the callback is called with a list of parameters or
* with an array holding the parameters
* @return boolean False on failure.
* @deprecated The $callbackobject parameter is depricated since
* version 1.2 and might be dropped in further versions.
setCallbackFunction($tplfunction, $callbackfunction, $callbackobject = '', $expandCallbackParameters=false )
if ($tplfunction == '' || $callbackfunction == '') {
"No template function "." ('$tplfunction')".
" and/or no callback function ('$callback') given." ,
'function' => $callbackfunction,
'object' => $callbackobject,
'expandParameters' => (boolean) $expandCallbackParameters
} // end func setCallbackFunction
* Sets the Callback function lookup table
* @param array function table
* array[templatefunction] =
* "function" => userfunction,
} // end func setCallbackFunctiontable
* Recursively removes all data assiciated with a block, including all inner blocks
* @param string block to be removed
function removeBlockData ($block)
foreach ($this->blockinner[$block] as $k => $inner) {
$this->removeBlockData ($inner);
} // end func removeBlockinner
* Returns a list of blocknames in the template.
* @return array [blockname => blockname]
foreach ($this->blocklist as $block => $content) {
$blocklist[$block] = $block;
} // end func getBlocklist
* Checks wheter a block exists.
} // end func blockExists
* Returns a list of variables of a block.
* @param string Blockname
* @return array [varname => varname]
* @see BlockvariableExists()
$variables[$variable] = $variable;
} // end func getBlockvariables
* Checks wheter a block variable exists.
* @param string Blockname
* @param string Variablename
* @see getBlockvariables()
} // end func BlockvariableExists
* Builds a functionlist from the template.
function buildFunctionlist ()
$pos = strpos($template, $regs[0 ]);
$head = $this->getValue ($template, ')');
$search = $regs[0 ] . $head . ')';
'__function' . $num . '__' .
while ($head != '' && $args2 = $this->getValue ($head, ',')) {
$args[] = ('"' == $arg2{0 } || "'" == $arg2{0 }) ?
} // end func buildFunctionlist
* Truncates the given code from the first occurence of
* $delimiter but ignores $delimiter enclosed by " or '.
* @param string The code which should be parsed
* @param string The delimiter char
* @see buildFunctionList()
function getValue ($code, $delimiter) {
$delimiter = array ( $delimiter => true );
if (isset ($delimiter[$code[0 ]])) {
for ($i = 0; $i < $len; ++ $i) {
($char == '"' || $char == "'") &&
($char == $enclosed_by || '' == $enclosed_by) &&
(0 == $i || ($i > 0 && '\\' != $code[$i - 1 ]))
if (!$enclosed && isset ($delimiter[$char])) {
* Deletes one or many variables from the block variable list.
* @param string Blockname
* @param mixed Name of one variable or array of variables
* ( array ( name => true ) ) to be stripped.
function deleteFromBlockvariablelist ($block, $variables)
$variables = array ($variables => true );
if (isset ($variables[$varname])) {
} // end deleteFromBlockvariablelist
* Updates the variable list of a block.
* @param string Blockname
function updateBlockvariablelist ($block)
if (count($regs[1 ]) != 0 ) {
foreach ($regs[1 ] as $k => $var) {
// check if any inner blocks were found
* loop through inner blocks, registering the variable
foreach ($this->blockinner[$block] as $childBlock) {
$this->updateBlockvariablelist ($childBlock);
} // end func updateBlockvariablelist
* Returns an array of blocknames where the given variable
* @param string Variable placeholder
* @return array $parents parents[0..n] = blockname
if ($variable == $varname) {
} // end func findPlaceholderBlocks
* Handles warnings, saves them to $warn and prints them or
* calls die() depending on the flags
* @param string File where the warning occured
* @param int Linenumber where the warning occured
* @see $warn, $printWarning, $haltOnWarning
function warning ($message, $file = '', $line = 0 )
'HTML_Template_ITX Warning: %s [File: %s, Line: %d]',
$this->warn[] = $message;
} // end class HTML_Template_ITX
Documentation generated on Mon, 11 Mar 2019 14:43:07 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.
|