3 * Integrated Template Extension - ITX
5 * With this class you get the full power of the phplib template class.
6 * You may have one file with blocks in it but you have as well one main file
7 * and multiple files one for each block. This is quite usefull when you have
8 * user configurable websites. Using blocks not in the main template allows
9 * you to some parts of your layout easily.
11 * Note that you can replace an existing block and add new blocks add runtime.
12 * Adding new blocks means changing a variable placeholder to a block.
14 * @author Ulf Wendel <uw@netuse.de>
19 class IntegratedTemplateExtension extends IntegratedTemplate {
22 * Array with all warnings.
25 * @see $printWarning, $haltOnWarning, warning()
33 * @see $haltOnWarning, $warn, warning()
35 var $printWarning = false;
38 * Call die() on warning?
41 * @see $warn, $printWarning, warning()
43 var $haltOnWarning = false;
46 * RegExp used to test for a valid blockname.
49 var $checkblocknameRegExp = "";
52 * Builds some complex regexps and calls the constructor of the parent class.
54 * Make sure that you call this constructor if you derive you own
55 * template class from this one.
57 * @see IntegratedTemplate()
59 function IntegratedTemplateExtension() {
61 $this->checkblocknameRegExp = "@".$this->blocknameRegExp."@";
62 $this->IntegratedTemplate();
64 } // end func IntegratedTemplateExtension
67 * Replaces an existing block with new content. Warning: not implemented yet.
69 * The Replacement does not affect previously added variables. All data is cached.
70 * In case the new block does contain less or other variable placeholder the previously
71 * passed data that is no longer referenced will be deleted. The internal list
72 * of allowed variables gets updated as well.
74 * In case the original block contains other blocks it must eighter have placeholder
75 * for the inner blocks or contain them. If you want to use placeholder the placeholder must
76 * look like openingDelimiter."__".blockname."__".closingDelimiter .
78 * Due to the cache updates replaceBlock() and replaceBlockfile() are "expensive" operations
79 * which means extensive usage will slow down your script. So try to avoid them and if
80 * you can't do so try to use them before you pass lots of variables to the block you're
83 * @param string Blockname
84 * @param string Blockcontent
86 * @see replaceBlockfile(), addBlock(), addBlockfile()
89 function replaceBlock($block, $template) {
90 if (!isset($this->blocklist[$block])) {
91 $this->halt("The block '$block' does not exist in the template and thus it can't be replaced.", __FILE__, __LINE__);
95 $this->halt("No block content given.", __FILE__, __LINE__);
99 print "This function has not been coded yet.";
102 // add to variablelist
103 // compare variable list
107 } // end func replaceBlock
110 * Replaces an existing block with new content from a file. Warning: not implemented yet.
111 * @brother replaceBlock()
112 * @param string Blockname
113 * @param string Name of the file that contains the blockcontent
115 function replaceBlockfile($block, $filename) {
116 return $this->replaceBlock($block, $this->getFile($filename));
117 } // end func replaceBlockfile
120 * Adds a block to the template changing a variable placeholder to a block placeholder.
122 * Add means "replace a variable placeholder by a new block".
123 * This is different to PHPLibs templates. The function loads a
124 * block, creates a handle for it and assigns it to a certain
125 * variable placeholder. To to the same with PHPLibs templates you would
126 * call set_file() to create the handle and parse() to assign the
127 * parsed block to a variable. By this PHPLibs templates assume that you tend
128 * to assign a block to more than one one placeholder. To assign a parsed block
129 * to more than only the placeholder you specify in this function you have
130 * to use a combination of getBlock() and setVariable().
132 * As no updates to cached data is necessary addBlock() and addBlockfile()
133 * are rather "cheap" meaning quick operations.
135 * The block content must not start with <!-- BEGIN blockname --> and end with
136 * <!-- END blockname --> this would cause overhead and produce an error.
138 * @param string Name of the variable placeholder, the name must be unique within the template.
139 * @param string Name of the block to be added
140 * @param string Content of the block
142 * @see addBlockfile()
145 function addBlock($placeholder, $blockname, $template) {
147 // Don't trust any user even if it's a programmer or yourself...
148 if (""==$placeholder) {
150 $this->halt("No variable placeholder given.", __FILE__, __LINE__);
153 } else if (""==$blockname || !preg_match($this->checkblocknameRegExp, $blockname) ) {
155 print $this->checkblocknameRegExp;
156 $this->halt("No or invalid blockname '$blockname' given.", __FILE__, __LINE__);
159 } else if (""==$template) {
161 $this->halt("No block content given.", __FILE__, __LINE__);
164 } else if (isset($this->blocklist[$blockname])) {
166 $this->halt("The block already exists.", __FILE__, __LINE__);
171 // Hmm, we should do some more tests.
172 $parents = $this->findPlaceholderBlocks($placeholder);
173 if (0==count($parents)) {
175 $this->halt("The variable placeholder '$placeholder' was not found in the template.", __FILE__, __LINE__);
178 } else if ( count($parents)>1 ) {
181 while (list($k, $parent)=each($parents))
183 $msg = substr($parent, -2);
185 $this->halt("The variable placeholder '$placeholder' must be unique, found in multiple blocks '$msg'.", __FILE__, __LINE__);
190 $template = "<!-- BEGIN $blockname -->".$template."<!-- END $blockname -->";
191 $this->findBlocks($template);
192 if ($this->flagBlocktrouble)
193 return false; // findBlocks() already throws an exception
195 $this->blockinner[$parents[0]][] = $blockname;
196 $this->blocklist[$parents[0]] = preg_replace( "@".$this->openingDelimiter.$placeholder.$this->closingDelimiter."@",
197 $this->openingDelimiter."__".$blockname."__".$this->closingDelimiter,
198 $this->blocklist[$parents[0]]
201 $this->deleteFromBlockvariablelist($parents[0], $placeholder);
202 $this->updateBlockvariablelist($blockname);
205 } // end func addBlock
208 * Adds a block taken from a file to the template changing a variable placeholder to a block placeholder.
210 * @param string Name of the variable placeholder to be converted
211 * @param string Name of the block to be added
212 * @param string File that contains the block
213 * @brother addBlock()
215 function addBlockfile($placeholder, $blockname, $filename) {
216 return $this->addBlock($placeholder, $blockname, $this->getFile($filename));
217 } // end func addBlockfile
220 * Deletes one or many variables from the block variable list.
221 * @param string Blockname
222 * @param mixed Name of one variable or array of variables ( array ( name => true ) ) to be stripped.
224 function deleteFromBlockvariablelist($block, $variables) {
226 if (!is_array($variables))
227 $variables = array( $variables => true);
229 reset($this->blockvariables[$block]);
230 while (list($k, $varname)=each($this->blockvariables[$block]))
231 if (isset($variables[$varname]))
232 unset($this->blockvariables[$block][$k]);
234 } // end deleteFromBlockvariablelist
237 * Updates the variable list of a block.
238 * @param string Blockname
240 function updateBlockvariablelist($block) {
242 preg_match_all( $this->variablesRegExp, $this->blocklist[$block], $regs );
243 $this->blockvariables[$block] = $regs[1];
245 } // end func updateBlockvariablelist
248 * Returns an array of blocknames where the given variable placeholder is used.
249 * @param string Variable placeholder
250 * @return array $parents parents[0..n] = blockname
252 function findPlaceholderBlocks($variable) {
256 reset($this->blocklist);
257 while (list($blockname, $content)=each($this->blocklist)) {
259 reset($this->blockvariables[$blockname]);
260 while (list($k, $varname)=each($this->blockvariables[$blockname]))
261 if ($variable == $varname)
262 $parents[] = $blockname;
266 } // end func findPlaceholderBlocks
269 * Handles warnings, saves them to $warn and prints them or calls die() depending on the flags
270 * @param string Warning
271 * @param string File where the warning occured
272 * @param int Linenumber where thr warning occured
273 * @see $warn, $printWarning, $haltOnWarning
275 function warning($message, $file="", $line=0) {
277 $message = sprintf("IntegratedTemplateExtension Warning: %s [File: %s, Line: %d]",
282 $this->warn[] = $message;
284 if ($this->printWarning)
287 if ($this->haltOnError)
290 } // end func warning
292 } // end class IntegratedTemplateExtension