+<?php\r
+\r
+#\r
+# Template (Version 2.0)\r
+#\r
+# Klasse zum Parsen von Templates\r
+#\r
+# Autor: Patrick Canterino <patrick@patshaping.de>\r
+# Letzte Aenderung: 3.7.2006\r
+#\r
+\r
+class Template\r
+{\r
+ var $file;\r
+ var $template;\r
+ var $original;\r
+ var $vars = array();\r
+ var $defined_vars = array();\r
+ var $loop_vars = array();\r
+\r
+ # get_template()\r
+ #\r
+ # Kompletten Vorlagentext zurueckgeben\r
+ #\r
+ # Parameter: -keine-\r
+ #\r
+ # Rueckgabe: Kompletter Vorlagentext (String)\r
+\r
+ function get_template()\r
+ {\r
+ return $this->template;\r
+ }\r
+\r
+ # set_template()\r
+ #\r
+ # Kompletten Vorlagentext aendern\r
+ #\r
+ # Parameter: Vorlagentext\r
+ #\r
+ # Rueckgabe: -nichts- (Template-Objekt wird modifiziert)\r
+\r
+ function set_template($text)\r
+ {\r
+ $this->template = $text;\r
+ }\r
+\r
+ # add_text()\r
+ #\r
+ # Vorlagentext ans Template-Objekt anhaengen\r
+ #\r
+ # Parameter: Vorlagentext\r
+ #\r
+ # Rueckgabe: -nichts- (Template-Objekt wird modifiziert)\r
+\r
+ function add_text($text)\r
+ {\r
+ $this->set_template($this->get_template().$text);\r
+ }\r
+\r
+ # read_file()\r
+ #\r
+ # Einlesen einer Vorlagendatei und {INCLUDE}-Anweisungen ggf. verarbeiten\r
+ # (Text wird an bereits vorhandenen Text angehaengt)\r
+ #\r
+ # Parameter: 1. Datei zum Einlesen\r
+ # 2. Status-Code (Boolean):\r
+ # true => {INCLUDE}-Anweisungen nicht verarbeiten\r
+ # false => {INCLUDE}-Anweisungen verarbeiten (Standard)\r
+ #\r
+ # Rueckgabe: -nichts- (Template-Objekt wird modifiziert)\r
+\r
+ function read_file($file,$not_include=0)\r
+ {\r
+ $this->file = $file;\r
+\r
+ if(filesize($file) > 0)\r
+ {\r
+ $fp = fopen($file,'r');\r
+ if(!$fp) die;\r
+ $content = fread($fp,filesize($file));\r
+ fclose($fp);\r
+ }\r
+ else $content = '';\r
+\r
+ $this->add_text($content);\r
+ $this->save_state();\r
+\r
+ if(!$not_include) $this->parse_includes();\r
+ }\r
+\r
+ # set_var()\r
+ #\r
+ # Wert einer Variable setzen\r
+ #\r
+ # Parameter: 1. Name der Variable\r
+ # 2. Wert, den die Variable erhalten soll\r
+ #\r
+ # Rueckgabe: -nichts- (Template-Objekt wird modifiziert)\r
+\r
+ function set_var($var,$content)\r
+ {\r
+ $this->vars[$var] = $content;\r
+ }\r
+\r
+ # get_var()\r
+ #\r
+ # Wert einer Variable zurueckgeben\r
+ #\r
+ # Parameter: (optional) Variablenname\r
+ #\r
+ # Rueckgabe: Wert der Variable;\r
+ # wenn die Variable nicht existiert, false;\r
+ # wenn kein Variablenname angegeben wurde, wird ein\r
+ # Array mit den Variablennamen zurueckgegeben\r
+\r
+ function get_var($var=false)\r
+ {\r
+ if($var !== false)\r
+ {\r
+ if(isset($this->vars[$var]))\r
+ {\r
+ return $this->vars[$var];\r
+ }\r
+ else\r
+ {\r
+ return false;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ return array_keys($this->vars);\r
+ }\r
+ }\r
+\r
+ # set_loop_data()\r
+ #\r
+ # Daten fuer eine Schleife setzen\r
+ #\r
+ # Parameter: 1. Name der Schleife\r
+ # 2. Array mit den Arrays mit den Variablen fuer\r
+ # die Schleifendurchgaenge\r
+ #\r
+ # Rueckgabe: -nichts- (Template-Objekt wird modifiziert)\r
+\r
+ function set_loop_data($loop,$data)\r
+ {\r
+ $this->loop_vars[$loop] = $data;\r
+ }\r
+\r
+ # add_loop_data()\r
+ #\r
+ # Daten fuer einen Schleifendurchgang hinzufuegen\r
+ #\r
+ # Parameter: 1. Name der Schleife\r
+ # 2. Array mit den Variablen fuer den\r
+ # Schleifendurchgang\r
+ #\r
+ # Rueckgabe: -nichts- (Template-Objekt wird modifiziert)\r
+\r
+ function add_loop_data($loop,$data)\r
+ {\r
+ if(isset($this->loop_vars[$loop]) && is_array($this->loop_vars[$loop]))\r
+ {\r
+ array_push($this->loop_vars[$loop],$data);\r
+ }\r
+ else\r
+ {\r
+ $this->loop_vars[$loop] = array($data);\r
+ }\r
+ }\r
+\r
+ # parse()\r
+ #\r
+ # In der Template definierte Variablen auslesen, Variablen\r
+ # ersetzen, {IF}- und {TRIM}-Bloecke parsen\r
+ #\r
+ # Parameter: -nichts-\r
+ #\r
+ # Rueckgabe: -nichts- (Template-Objekt wird modifiziert)\r
+\r
+ function parse()\r
+ {\r
+ # Zuerst die Schleifen parsen\r
+\r
+ if(is_array($this->loop_vars) && ($loops = array_keys($this->loop_vars)))\r
+ {\r
+ foreach($loops as $loop)\r
+ {\r
+ $this->parse_loop($loop);\r
+ }\r
+ }\r
+\r
+ # Normale Variablen durchgehen\r
+\r
+ if(($vars = $this->get_var()) !== false && is_array($vars))\r
+ {\r
+ foreach($vars as $var)\r
+ {\r
+ $val = $this->get_var($var);\r
+\r
+ $this->parse_if_block($var,$val);\r
+\r
+ if(is_array($val))\r
+ {\r
+ $this->fillin_array($var,$val);\r
+ }\r
+ else\r
+ {\r
+ $this->fillin($var,$val);\r
+ }\r
+\r
+ unset($val);\r
+ }\r
+ }\r
+\r
+ # Jetzt dasselbe mit denen, die direkt in der Template-Datei definiert\r
+ # sind, machen. Ich weiss, dass das eine ziemlich unsaubere Loesung ist,\r
+ # aber es funktioniert\r
+\r
+ $this->get_defined_vars();\r
+\r
+ foreach($this->defined_vars as $var)\r
+ {\r
+ $val = $this->get_var($var);\r
+\r
+ $this->parse_if_block($var,$val);\r
+ $this->fillin($var,$val);\r
+\r
+ unset($val);\r
+ }\r
+\r
+ # {TRIM}-Bloecke entfernen\r
+\r
+ $this->parse_trim_blocks();\r
+ }\r
+\r
+ # fillin()\r
+ #\r
+ # Variablen durch Text ersetzen\r
+ #\r
+ # Parameter: 1. Variable zum Ersetzen\r
+ # 2. Text, durch den die Variable ersetzt werden soll\r
+ #\r
+ # Rueckgabe: -nichts- (Template-Objekt wird modifiziert)\r
+\r
+ function fillin($var,$text)\r
+ {\r
+ $template = $this->get_template();\r
+ $template = str_replace('{'.$var.'}',$text,$template);\r
+\r
+ $this->set_template($template);\r
+ }\r
+\r
+ # fillin_array()\r
+ #\r
+ # Variable durch Array ersetzen\r
+ #\r
+ # Parameter: 1. Variable zum Ersetzen\r
+ # 2. Array, durch das die Variable ersetzt werden soll\r
+ # 3. Zeichenkette, mit der das Array verbunden werden soll\r
+ # (Standard: '')\r
+ #\r
+ # Rueckgabe: -nichts- (Template-Objekt wird modifiziert)\r
+\r
+ function fillin_array($var,$array,$glue='')\r
+ {\r
+ $this->fillin($var,implode($glue,$array));\r
+ }\r
+\r
+ # to_file()\r
+ #\r
+ # Template in Datei schreiben\r
+ #\r
+ # Parameter: Datei-Handle\r
+ #\r
+ # Rueckgabe: Status-Code (Boolean)\r
+\r
+ function to_file($handle)\r
+ {\r
+ return @fwrite($handle,$this->get_template());\r
+ }\r
+\r
+ # reset()\r
+ #\r
+ # Den gesicherten Stand des Template-Textes sichern\r
+ #\r
+ # Parameter: -nichts-\r
+ #\r
+ # Rueckgabe: -nichts- (Template-Objekt wird modifiziert)\r
+\r
+ function reset()\r
+ {\r
+ $this->template = $this->original;\r
+ }\r
+\r
+ # save_state()\r
+ #\r
+ # Aktuellen Stand des Template-Textes sichern\r
+ # (alte Sicherung wird ueberschrieben)\r
+ #\r
+ # Parameter: -nichts-\r
+ #\r
+ # Rueckgabe: -nichts- (Template-Objekt wird modifiziert)\r
+\r
+ function save_state()\r
+ {\r
+ $this->original = $this->template;\r
+ }\r
+\r
+ # parse_loop()\r
+ #\r
+ # Eine Schleife parsen\r
+ #\r
+ # Parameter: Name der Schleife\r
+ #\r
+ # Rueckgabe: -nichts- (Template-Objekt wird modifiziert)\r
+\r
+ function parse_loop($name)\r
+ {\r
+ $template = $this->get_template();\r
+ if(strpos($template,'{LOOP '.$name.'}') === false) return;\r
+\r
+ $offset = 0;\r
+ $name_len = strlen($name);\r
+\r
+ while(($begin = strpos($template,'{LOOP '.$name.'}',$offset)) !== false)\r
+ {\r
+ if(($end = strpos($template,'{ENDLOOP}',$begin+6+$name_len)) !== false)\r
+ {\r
+ $block = substr($template,$begin,$end+9-$begin);\r
+ $content = substr($block,$name_len+7,-9);\r
+\r
+ $parsed_block = '';\r
+\r
+ for($x=0;$x<count($this->loop_vars[$name]);$x++)\r
+ {\r
+ $loop_data = $this->loop_vars[$name][$x];\r
+ $loop_vars = array_keys($loop_data);\r
+\r
+ $ctpl = new Template;\r
+ $ctpl->set_template($content);\r
+\r
+ foreach($loop_vars as $loop_var)\r
+ {\r
+ $ctpl->set_var($name.'.'.$loop_var,$loop_data[$loop_var]);\r
+ }\r
+\r
+ $ctpl->parse();\r
+ $parsed_block .= $ctpl->get_template();\r
+\r
+ unset($ctpl);\r
+ }\r
+\r
+ $template = str_replace($block,$parsed_block,$template);\r
+ $offset = $begin+strlen($parsed_block);\r
+ }\r
+ else break;\r
+ }\r
+\r
+ $this->set_template($template);\r
+ }\r
+\r
+ # get_defined_vars()\r
+ #\r
+ # In der Template-Datei definierte Variablen auslesen\r
+ #\r
+ # Parameter: -nichts-\r
+ #\r
+ # Rueckgabe: -nichts- (Template-Objekt wird modifiziert)\r
+\r
+ function get_defined_vars()\r
+ {\r
+ $template = $this->get_template();\r
+ if(strpos($template,'{DEFINE ') === false) return;\r
+\r
+ $offset = 0;\r
+\r
+ while(strpos($template,'{DEFINE ',$offset) !== false)\r
+ {\r
+ $begin = strpos($template,'{DEFINE ',$offset)+8;\r
+ $offset = $begin;\r
+\r
+ $name = '';\r
+ $content = '';\r
+\r
+ $var_open = 0;\r
+ $name_found = 0;\r
+ $define_block = 0;\r
+\r
+ for($x=$begin;$x<strlen($template);$x++)\r
+ {\r
+ if($template[$x] == "\012" || $template[$x] == "\015")\r
+ {\r
+ # Wenn in einem {DEFINE}-Block ein Zeilenumbruch gefunden wird,\r
+ # brechen wir mit dem Parsen des Blockes ab\r
+\r
+ break;\r
+ }\r
+\r
+ if($var_open == 1)\r
+ {\r
+ if($template[$x] == '"')\r
+ {\r
+ # Der Inhalt der Variable ist hier zu Ende\r
+\r
+ $var_open = 0;\r
+\r
+ if($template[$x+1] == '}')\r
+ {\r
+ # Hier ist der Block zu Ende\r
+\r
+ if($this->get_var($name) === false)\r
+ {\r
+ # Die Variable wird nur gesetzt, wenn sie nicht bereits gesetzt ist\r
+\r
+ $this->set_var($name,$content);\r
+ array_push($this->defined_vars,$name);\r
+ }\r
+\r
+ # {DEFINE}-Block entfernen\r
+\r
+ $pre = substr($template,0,$begin-8);\r
+ $post = substr($template,$x+2);\r
+\r
+ $template = $pre.$post;\r
+\r
+ # Fertig!\r
+\r
+ $offset = strlen($pre);\r
+ break;\r
+ }\r
+ }\r
+ elseif($template[$x] == '\\')\r
+ {\r
+ # Ein Backslash wurde gefunden, er dient zum Escapen von Zeichen\r
+\r
+ if($template[$x+1] == 'n')\r
+ {\r
+ # "\n" in Zeilenumbrueche umwandeln\r
+\r
+ $content .= "\n";\r
+ }\r
+ else $content .= $template[$x+1];\r
+\r
+ $x++;\r
+ }\r
+ else $content .= $template[$x];\r
+ }\r
+ else\r
+ {\r
+ if($name_found == 1)\r
+ {\r
+ if($var_open == 0)\r
+ {\r
+ if($template[$x] == '"') $var_open = 1;\r
+ else break;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ # Variablennamen auslesen\r
+\r
+ if($template[$x] == '}' && $name != '')\r
+ {\r
+ # Wir haben einen {DEFINE}-Block\r
+\r
+ $name_found = 1;\r
+ $define_block = 1;\r
+\r
+ # Alles ab hier sollte mit dem Teil verbunden werden, der das\r
+ # {DEFINE} in einer Zeile verarbeitet\r
+\r
+ # Der Parser fuer {DEFINE}-Bloecke ist nicht rekursiv, was auch\r
+ # nicht noetig sein sollte\r
+\r
+ if(($end = strpos($template,'{ENDDEFINE}',$x)) !== false)\r
+ {\r
+ $x++;\r
+\r
+ $content = substr($template,$x,$end-$x);\r
+\r
+ if($this->get_var($name) === false)\r
+ {\r
+ # Die Variable wird nur gesetzt, wenn sie nicht bereits gesetzt ist\r
+\r
+ $this->set_var($name,$content);\r
+ array_push($this->defined_vars,$name);\r
+ }\r
+\r
+ $pre = substr($template,0,$begin-8);\r
+ $post = substr($template,$end+11);\r
+\r
+ $template = $pre.$post;\r
+\r
+ # Fertig!\r
+\r
+ $offset = strlen($pre);\r
+ break;\r
+ }\r
+ else break;\r
+ }\r
+ elseif($template[$x] != ' ')\r
+ {\r
+ $name .= $template[$x];\r
+ }\r
+ elseif($name != '')\r
+ {\r
+ $name_found = 1;\r
+ }\r
+ else break;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ $this->set_template($template);\r
+ }\r
+\r
+ # parse_if_block()\r
+ #\r
+ # IF-Bloecke verarbeiten\r
+ #\r
+ # Parameter: 1. Name des IF-Blocks (das, was nach dem IF steht)\r
+ # 2. Status-Code (true => Inhalt anzeigen\r
+ # false => Inhalt nicht anzeigen\r
+ # 3. true => Verneinten Block nicht parsen\r
+ # false => Verneinten Block parsen (Standard)\r
+ #\r
+ # Rueckgabe: -nichts- (Template-Objekt wird modifiziert)\r
+\r
+ function parse_if_block($name,$state,$no_negate=0)\r
+ {\r
+ $template = $this->get_template();\r
+\r
+ $count = 0;\r
+\r
+ while(strpos($template,'{IF '.$name.'}') !== false)\r
+ {\r
+ # Das alles hier ist nicht wirklich elegant geloest...\r
+ # ... aber solange es funktioniert... ;-)\r
+\r
+ $count++;\r
+\r
+ $start = strpos($template,'{IF '.$name.'}');\r
+ $tpl_tmp = substr($template,$start);\r
+ $splitted = explode('{ENDIF}',$tpl_tmp);\r
+\r
+ $block = ''; # Kompletter bedingter Block\r
+ $ifs = 0; # IF-Zaehler (wird fuer jedes IF erhoeht und fuer jedes ENDIF erniedrigt)\r
+\r
+ # {IF}\r
+\r
+ for($x=0;$x<count($splitted);$x++)\r
+ {\r
+ if($x == count($splitted)-1) die('Nesting error found while parsing IF block "'.$name.'" nr. '.$count.' in template file "'.$this->file.'"');\r
+\r
+ $ifs += substr_count($splitted[$x],'{IF '); # Zum Zaehler jedes Vorkommen von IF hinzuzaehlen\r
+ $ifs--; # Zaehler um 1 erniedrigen\r
+ $block .= $splitted[$x].'{ENDIF}'; # Daten zum Block hinzufuegen\r
+\r
+ if($ifs == 0)\r
+ {\r
+ # Zaehler wieder 0, also haben wir das Ende des IF-Blocks gefunden :-))\r
+\r
+ break;\r
+ }\r
+ }\r
+\r
+ $if_block = substr($block,strlen($name)+5,-7); # Alles zwischen {IF} und {ENDIF}\r
+\r
+ # {ELSE}\r
+\r
+ $else_block = ''; # Alles ab {ELSE}\r
+ $ifs = 0; # IF-Zaehler\r
+\r
+ $splitted = explode('{ELSE}',$if_block);\r
+\r
+ for($x=0;$x<count($splitted);$x++)\r
+ {\r
+ $ifs += substr_count($splitted[$x],'{IF '); # Zum Zaehler jedes Vorkommen von IF hinzuzaehlen\r
+ $ifs -= substr_count($splitted[$x],'{ENDIF}'); # Vom Zaehler jedes Vorkommen von ENDIF abziehen\r
+\r
+ if($ifs == 0)\r
+ {\r
+ # Zaehler 0, also haben wir das Ende des IF-Abschnitts gefunden\r
+\r
+ # Aus dem Rest den ELSE-Block zusammenbauen\r
+\r
+ for($y=$x+1;$y<count($splitted);$y++)\r
+ {\r
+ $else_block .= '{ELSE}'.$splitted[$y];\r
+ }\r
+\r
+ if($else_block)\r
+ {\r
+ $if_block = substr($if_block,0,strlen($if_block)-strlen($else_block));\r
+ $else_block = substr($else_block,6);\r
+ }\r
+\r
+ break;\r
+ }\r
+ }\r
+\r
+ # Block durch die jeweiligen Daten ersetzen\r
+\r
+ $replacement = ($state) ? $if_block : $else_block;\r
+\r
+ $template = str_replace($block,$replacement,$template);\r
+ }\r
+\r
+ $this->set_template($template);\r
+\r
+ # Evtl. verneinte Form parsen\r
+\r
+ if(!$no_negate)\r
+ {\r
+ $this->parse_if_block('!'.$name,!$state,1);\r
+ }\r
+ }\r
+\r
+ # parse_trim_blocks()\r
+ #\r
+ # {TRIM}-Bloecke parsen\r
+ #\r
+ # Dieser Parser ist nicht rekursiv, was auch nicht\r
+ # noetig sein sollte.\r
+ #\r
+ # Parameter: -nichts-\r
+ #\r
+ # Rueckgabe: -nichts- (Template-Objekt wird modifiziert)\r
+\r
+ function parse_trim_blocks()\r
+ {\r
+ $template = $this->get_template();\r
+ if(strpos($template,'{TRIM}') === false) return;\r
+\r
+ $offset = 0;\r
+\r
+ while(($begin = strpos($template,'{TRIM}',$offset)) !== false)\r
+ {\r
+ if(($end = strpos($template,'{ENDTRIM}',$begin+6)) !== false)\r
+ {\r
+ $block = substr($template,$begin,$end+9-$begin);\r
+ $content = substr($block,6,-9);\r
+\r
+ $trimmed = trim($content);\r
+\r
+ $template = str_replace($block,$trimmed,$template);\r
+\r
+ $offset = $begin+strlen($trimmed);\r
+ }\r
+ else break;\r
+ }\r
+\r
+ $this->set_template($template);\r
+ }\r
+\r
+ # parse_condtag()\r
+ #\r
+ # Bedingungstags in einem Vorlagentext verarbeiten\r
+ #\r
+ # Parameter: 1. Tagname\r
+ # 2. Status-Code (true => Tag-Inhalt anzeigen\r
+ # false => Tag-Inhalt nicht anzeigen\r
+ #\r
+ # Rueckgabe: -nichts- (Template-Objekt wird modifiziert)\r
+\r
+ function parse_condtag($condtag,$state)\r
+ {\r
+ $template = $this->get_template();\r
+\r
+ while(strpos($template,'<'.$condtag.'>') !== false)\r
+ {\r
+ $start = strpos($template,'<'.$condtag.'>'); # Beginn des Blocks\r
+ $end = strpos($template,'</'.$condtag.'>')+strlen($condtag)+3; # Ende des Blocks\r
+\r
+ $extract = substr($template,$start,$end-$start); # Kompletten Bedingungsblock extrahieren...\r
+\r
+ $replacement = ($state) ? substr($extract,strlen($condtag)+2,0-strlen($condtag)-3) : '';\r
+\r
+ $template = str_replace($extract,$replacement,$template); # Block durch neue Daten ersetzen\r
+ }\r
+ $this->set_template($template);\r
+ }\r
+\r
+ # parse_includes()\r
+ #\r
+ # {INCLUDE}-Anweisungen verarbeiten\r
+ #\r
+ # Parameter: -nichts-\r
+ #\r
+ # Rueckgabe: -nichts- (Template-Objekt wird modifiziert)\r
+\r
+ function parse_includes()\r
+ {\r
+ $template = $this->get_template();\r
+ if(strpos($template,'{INCLUDE ') === false) return;\r
+\r
+ $offset = 0;\r
+\r
+ $y = 0;\r
+\r
+ while(($begin = strpos($template,'{INCLUDE ',$offset)) !== false)\r
+ {\r
+ $y++;\r
+\r
+ $start = $begin+9;\r
+ $offset = $start;\r
+ $long = 0;\r
+\r
+ if($template[$start] == '"')\r
+ {\r
+ $long = 1;\r
+ $start++;\r
+ }\r
+\r
+ $file = '';\r
+ $skip = 0;\r
+\r
+ for($x=$start;$x<strlen($template);$x++)\r
+ {\r
+ if($template[$x] == "\012" || $template[$x] == "\015")\r
+ {\r
+ $skip = 1;\r
+ break;\r
+ }\r
+ elseif($long == 0 && $template[$x] == ' ')\r
+ {\r
+ $skip = 1;\r
+ break;\r
+ }\r
+ elseif($long == 1 && $template[$x] == '"')\r
+ {\r
+ if($template[$x+1] != '}') $skip = 1;\r
+ break;\r
+ }\r
+ elseif($long == 0 && $template[$x] == '}')\r
+ {\r
+ break;\r
+ }\r
+ else\r
+ {\r
+ $file .= $template[$x];\r
+ }\r
+ }\r
+\r
+ if($skip == 1) continue;\r
+\r
+ if($file != '')\r
+ {\r
+ $filepath = $file;\r
+\r
+ $is_absolute = (strtoupper(substr(PHP_OS,0,3)) === 'WIN')\r
+ ? preg_match('!^([a-z]:)?/!i',$file)\r
+ : preg_match('!^/!',$file);\r
+\r
+ if(!$is_absolute)\r
+ {\r
+ if(!empty($this->file)) $dir = dirname($this->file);\r
+ else $dir = '.';\r
+\r
+ $dir = str_replace('\\','/',$dir);\r
+\r
+ if(!preg_match('!/+$!',$dir)) $dir .= '/';\r
+\r
+ $filepath = $dir.$file;\r
+ }\r
+\r
+ if(is_file($filepath))\r
+ {\r
+ $inc = new Template;\r
+ $inc->read_file($filepath);\r
+\r
+ $end = ($long == 1)\r
+ ? $start + strlen($file) + 2\r
+ : $start + strlen($file) + 1;\r
+\r
+ $pre = substr($template,0,$begin);\r
+ $post = substr($template,$end);\r
+\r
+ $template = $pre.$inc->get_template().$post;\r
+ $offset = strlen($pre)+strlen($inc->get_template());\r
+\r
+ unset($inc);\r
+ }\r
+ }\r
+ }\r
+\r
+ $this->set_template($template);\r
+ }\r
+}\r
+\r
+#\r
+### Ende ###\r
+\r
+?>
\ No newline at end of file