]> git.p6c8.net - form-email.git/blobdiff - form-email/class.Template.php
- Neuen Code ein bisschen kommentiert
[form-email.git] / form-email / class.Template.php
index ad6dc0ecc98875c3f38d32d2a53b3e5b6291d946..5b43d0b5ff9d4d7b62f5142d2a7819182ab5ccbe 100644 (file)
 <?php\r
 \r
 #\r
-# Template (Version 2.0)\r
+# Template (Version 2.5)\r
 #\r
 # Klasse zum Parsen von Templates\r
 #\r
 # Autor:            Patrick Canterino <patrick@patshaping.de>\r
-# Letzte Aenderung: 3.7.2006\r
+# Letzte Aenderung: 25.11.2011\r
+#\r
+# Copyright (C) 2002-2011 Patrick Canterino\r
+#\r
+# Diese Datei kann unter den Bedingungen der "Artistic License 2.0"\r
+# weitergegeben und / oder veraendert werden.\r
+# Siehe:\r
+# http://www.opensource.org/licenses/artistic-license-2.0\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
+class Template {\r
+    var $file;\r
+    var $template;\r
+    var $original;\r
+    var $old_parsing = 0;\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
+        return $this->template;\r
     }\r
-    else\r
-    {\r
-     $this->fillin($var,$val);\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
+        $this->template = $text;\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
+    # 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
+        $this->set_template($this->get_template().$text);\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
+    # 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
+        $this->file = $file;\r
+\r
+        if(filesize($file) > 0) {\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
-    if($var_open == 1)\r
-    {\r
-     if($template[$x] == '"')\r
-     {\r
-      # Der Inhalt der Variable ist hier zu Ende\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
+        $this->vars[$var] = $content;\r
+    }\r
 \r
-      $var_open = 0;\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
+        if($var !== false) {\r
+            if(isset($this->vars[$var])) {\r
+                return $this->vars[$var];\r
+            }\r
+            else {\r
+                return false;\r
+            }\r
+        }\r
+        else {\r
+            return array_keys($this->vars);\r
+        }\r
+    }\r
 \r
-      if($template[$x+1] == '}')\r
-      {\r
-       # Hier ist der Block zu Ende\r
+    # set_vars()\r
+    #\r
+    # Komplettes Variablen-Array mit einem anderen Array ueberschreiben\r
+    #\r
+    # Parameter: Array\r
+    #\r
+    # Rueckgabe: -nichts- (Template-Objekt wird modifiziert)\r
 \r
-       if($this->get_var($name) === false)\r
-       {\r
-        # Die Variable wird nur gesetzt, wenn sie nicht bereits gesetzt ist\r
+    function set_vars($vars) {\r
+        $this->vars = $vars;\r
+    }\r
 \r
-        $this->set_var($name,$content);\r
-        array_push($this->defined_vars,$name);\r
-       }\r
+    # add_vars()\r
+    #\r
+    # Zum bestehenden Variablen-Array weitere Variablen in Form eines Arrays\r
+    # hinzufuegen\r
+    #\r
+    # Parameter: Array\r
+    #\r
+    # Rueckgabe: -nichts- (Template-Objekt wird modifiziert)\r
+\r
+    function add_vars($vars) {\r
+        $this->vars = array_merge($this->vars,$vars);\r
+    }\r
 \r
-       # {DEFINE}-Block entfernen\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
+        $this->loop_vars[$loop] = $data;\r
+    }\r
 \r
-       $pre  = substr($template,0,$begin-8);\r
-       $post = substr($template,$x+2);\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
+        if(isset($this->loop_vars[$loop]) && is_array($this->loop_vars[$loop])) {\r
+            array_push($this->loop_vars[$loop],$data);\r
+        }\r
+        else {\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
+        if($this->old_parsing) return $this->parse_old();\r
+\r
+        # Zuerst die Schleifen parsen\r
+\r
+        if(is_array($this->loop_vars) && ($loops = array_keys($this->loop_vars))) {\r
+            foreach($loops as $loop) {\r
+                $this->parse_loop($loop);\r
+            }\r
+        }\r
 \r
-       $template = $pre.$post;\r
+        # In Template-Datei definierte Variablen auslesen\r
 \r
-       # Fertig!\r
+        $this->get_defined_vars();\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
+        # Variablen ersetzen\r
 \r
-      if($template[$x+1] == 'n')\r
-      {\r
-       # "\n" in Zeilenumbrueche umwandeln\r
+        if(($vars = $this->get_var()) !== false && is_array($vars)) {\r
+            $this->parse_if_blocks();\r
+            $this->replace_vars();\r
+        }\r
 \r
-       $content .= "\n";\r
-      }\r
-      else $content .= $template[$x+1];\r
+        # {TRIM}-Bloecke entfernen\r
 \r
-      $x++;\r
-     }\r
-     else $content .= $template[$x];\r
+        $this->parse_trim_blocks();\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
+    # parse_old()\r
+    #\r
+    # In der Template definierte Variablen auslesen, Variablen\r
+    # ersetzen, {IF}- und {TRIM}-Bloecke parsen\r
+    # (alte Methode)\r
+    #\r
+    # Parameter: -nichts-\r
+    #\r
+    # Rueckgabe: -nichts- (Template-Objekt wird modifiziert)\r
+\r
+    function parse_old() {\r
+        # Zuerst die Schleifen parsen\r
+\r
+        if(is_array($this->loop_vars) && ($loops = array_keys($this->loop_vars))) {\r
+            foreach($loops as $loop) {\r
+                $this->parse_loop($loop);\r
+            }\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
+        # Normale Variablen durchgehen\r
 \r
-  $this->set_template($template);\r
- }\r
+        if(($vars = $this->get_var()) !== false && is_array($vars)) {\r
+            foreach($vars as $var) {\r
+                $val = $this->get_var($var);\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
+                $this->parse_if_block($var,$val);\r
 \r
- function parse_if_block($name,$state,$no_negate=0)\r
- {\r
-  $template = $this->get_template();\r
+                if(is_array($val)) {\r
+                    $this->fillin_array($var,$val);\r
+                }\r
+                else {\r
+                    $this->fillin($var,$val);\r
+                }\r
 \r
-  $count = 0;\r
+                unset($val);\r
+            }\r
+        }\r
 \r
-  while(strpos($template,'{IF '.$name.'}') !== false)\r
-  {\r
-   # Das alles hier ist nicht wirklich elegant geloest...\r
-   # ... aber solange es funktioniert... ;-)\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
-   $count++;\r
+        $this->get_defined_vars();\r
 \r
-   $start    = strpos($template,'{IF '.$name.'}');\r
-   $tpl_tmp  = substr($template,$start);\r
-   $splitted = explode('{ENDIF}',$tpl_tmp);\r
+        foreach($this->defined_vars as $var) {\r
+            $val = $this->get_var($var);\r
 \r
-   $block = ''; # Kompletter bedingter Block\r
-   $ifs   = 0;  # IF-Zaehler (wird fuer jedes IF erhoeht und fuer jedes ENDIF erniedrigt)\r
+            $this->parse_if_block($var,$val);\r
+            $this->fillin($var,$val);\r
 \r
-   # {IF}\r
+            unset($val);\r
+        }\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
+        # {TRIM}-Bloecke entfernen\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
+        $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
-    if($ifs == 0)\r
-    {\r
-     # Zaehler wieder 0, also haben wir das Ende des IF-Blocks gefunden :-))\r
+    function fillin($var,$text) {\r
+        $template = $this->get_template();\r
+        $template = str_replace('{'.$var.'}',$text,$template);\r
 \r
-     break;\r
+        $this->set_template($template);\r
     }\r
-   }\r
 \r
-   $if_block = substr($block,strlen($name)+5,-7); # Alles zwischen {IF} und {ENDIF}\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
+        $this->fillin($var,implode($glue,$array));\r
+    }\r
 \r
-   # {ELSE}\r
+    # replace_vars()\r
+    #\r
+    # Variablen eine nach der anderen ersetzen. Sollte in einer Variable eine\r
+    # andere Variable auftauchen, so wird diese nicht ersetzt.\r
+    #\r
+    # Parameter: Array mit zu parsenden Variablen (optional)\r
+    #\r
+    # Rueckgabe: -nichts- (Template-Objekt wird modifiziert)\r
 \r
-   $else_block = ''; # Alles ab {ELSE}\r
-   $ifs        = 0;  # IF-Zaehler\r
+    function replace_vars($valid=array()) {\r
+        $template = $this->get_template();\r
 \r
-   $splitted = explode('{ELSE}',$if_block);\r
+        $valid_vars = (empty($valid)) ? $this->get_var() : $valid;\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
+        for($x=0;$x<strlen($template);$x++) {\r
+            if($template[$x] == '{') {\r
+                foreach($valid_vars as $var) {\r
+                    # Pruefen, ob hier eine gueltige Variable beginnt\r
 \r
-    if($ifs == 0)\r
-    {\r
-     # Zaehler 0, also haben wir das Ende des IF-Abschnitts gefunden\r
+                    if(substr($template,$x+1,strlen($var)+1) == $var.'}') {\r
+                        if(is_array($this->get_var($var))) {\r
+                            $content = implode('',$this->get_var($var));\r
+                        }\r
+                        else {\r
+                            $content = $this->get_var($var);\r
+                        }\r
 \r
-     # Aus dem Rest den ELSE-Block zusammenbauen\r
+                        # Daten vor und nach der Variable\r
 \r
-     for($y=$x+1;$y<count($splitted);$y++)\r
-     {\r
-      $else_block .= '{ELSE}'.$splitted[$y];\r
-     }\r
+                        $pre  = substr($template,0,$x);\r
+                        $post = substr($template,strlen($pre)+2+strlen($var));\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
+                        # Alles neu zusammensetzen\r
 \r
-     break;\r
-    }\r
-   }\r
+                        $template = $pre.$content.$post;\r
+\r
+                        # Zaehler aendern\r
+\r
+                        $x = strlen($pre.$content)-1;\r
+                    }\r
+                }\r
+            }\r
+        }\r
 \r
-   # Block durch die jeweiligen Daten ersetzen\r
-\r
-   $replacement = ($state) ? $if_block : $else_block;\r
+        $this->set_template($template);\r
+    }\r
 \r
-   $template = str_replace($block,$replacement,$template);\r
-  }\r
+    # to_file()\r
+    #\r
+    # Template in Datei schreiben\r
+    #\r
+    # Parameter: Datei-Handle\r
+    #\r
+    # Rueckgabe: Status-Code (Boolean)\r
 \r
-  $this->set_template($template);\r
+    function to_file($handle) {\r
+        return @fwrite($handle,$this->get_template());\r
+    }\r
 \r
-  # Evtl. verneinte Form parsen\r
-\r
-  if(!$no_negate)\r
-  {\r
-   $this->parse_if_block('!'.$name,!$state,1);\r
-  }\r
- }\r
+    # reset()\r
+    #\r
+    # Den gesicherten Stand des Template-Textes wiederherstellen\r
+    #\r
+    # Parameter: -nichts-\r
+    #\r
+    # Rueckgabe: -nichts- (Template-Objekt wird modifiziert)\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
+    function reset() {\r
+        $this->template = $this->original;\r
     }\r
-    elseif($long == 0 && $template[$x] == ' ')\r
-    {\r
-     $skip = 1;\r
-     break;\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
+        $this->original = $this->template;\r
     }\r
-    elseif($long == 1 && $template[$x] == '"')\r
-    {\r
-     if($template[$x+1] != '}') $skip = 1;\r
-     break;\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
+        $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
+            if(($end = strpos($template,'{ENDLOOP}',$begin+6+$name_len)) !== false) {\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
+                    $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
+                        $ctpl->set_var($name.'.'.$loop_var,$loop_data[$loop_var]);\r
+                    }\r
+\r
+                    if($this->old_parsing) {\r
+                        $ctpl->parse_old();\r
+                    }\r
+                    else {\r
+                        $ctpl->parse();\r
+                    }\r
+\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
+            $template = $this->get_template();\r
+            if(strpos($template,'{DEFINE ') === false) return;\r
+\r
+            $offset = 0;\r
+\r
+            while(strpos($template,'{DEFINE ',$offset) !== false) {\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
+                    if($template[$x] == "\012" || $template[$x] == "\015") {\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
+                        if($template[$x] == '"') {\r
+                            # Der Inhalt der Variable ist hier zu Ende\r
+\r
+                            $var_open = 0;\r
+\r
+                            if($template[$x+1] == '}') {\r
+                                # Hier ist der Block zu Ende\r
+\r
+                                if($this->get_var($name) === false) {\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
+                        # Ein Backslash wurde gefunden, er dient zum Escapen von Zeichen\r
+\r
+                        if($template[$x+1] == 'n') {\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
+                    if($name_found == 1) {\r
+                        if($var_open == 0) {\r
+                            if($template[$x] == '"') $var_open = 1;\r
+                            else break;\r
+                        }\r
+                    }\r
+                    else {\r
+                        # Variablennamen auslesen\r
+\r
+                        if($template[$x] == '}' && $name != '') {\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
+                                $x++;\r
+\r
+                                $content = substr($template,$x,$end-$x);\r
+\r
+                                if($this->get_var($name) === false) {\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
+                            $name .= $template[$x];\r
+                        }\r
+                        elseif($name != '') {\r
+                            $name_found = 1;\r
+                        }\r
+                        else break;\r
+                    }\r
+                }\r
+            }\r
+        }\r
+\r
+        $this->set_template($template);\r
     }\r
-    elseif($long == 0 && $template[$x] == '}')\r
-    {\r
-     break;\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
+        $template = $this->get_template();\r
+\r
+        $count = 0;\r
+\r
+        while(strpos($template,'{IF '.$name.'}') !== false) {\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
+                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
+                    # 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
+                $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
+                    # 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
+                        $else_block .= '{ELSE}'.$splitted[$y];\r
+                    }\r
+\r
+                    if($else_block) {\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
+            $this->parse_if_block('!'.$name,!$state,1);\r
+        }\r
     }\r
-    else\r
-    {\r
-     $file .= $template[$x];\r
+\r
+    # parse_if_blocks()\r
+    #\r
+    # IF-Bloecke zu allen definierten Variablen verarbeiten\r
+    #\r
+    # Parameter: Array mit zu verarbeitenden IF-Bloecken (optional)\r
+    #\r
+    # Rueckgabe: -nichts- (Template-Objekt wird modifiziert)\r
+\r
+    function parse_if_blocks($valid=array()) {\r
+        $valid_vars = (empty($valid)) ? $this->get_var() : $valid;\r
+\r
+        foreach($valid_vars as $valid_var) {\r
+            $this->parse_if_block($valid_var,$this->get_var($valid_var));\r
+        }\r
     }\r
-   }\r
 \r
-   if($skip == 1) continue;\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
-   if($file != '')\r
-   {\r
-    $filepath = $file;\r
+    function parse_trim_blocks() {\r
+        $template = $this->get_template();\r
+        if(strpos($template,'{TRIM}') === false) return;\r
 \r
-    $is_absolute = (strtoupper(substr(PHP_OS,0,3)) === 'WIN')\r
-                 ? preg_match('!^([a-z]:)?/!i',$file)\r
-                 : preg_match('!^/!',$file);\r
+        $offset = 0;\r
 \r
-    if(!$is_absolute)\r
-    {\r
-     if(!empty($this->file)) $dir = dirname($this->file);\r
-     else $dir = '.';\r
+        while(($begin = strpos($template,'{TRIM}',$offset)) !== false) {\r
+            if(($end = strpos($template,'{ENDTRIM}',$begin+6)) !== false) {\r
+                $block    = substr($template,$begin,$end+9-$begin);\r
+                $content  = substr($block,6,-9);\r
 \r
-     $dir = str_replace('\\','/',$dir);\r
+                $trimmed  = trim($content);\r
 \r
-     if(!preg_match('!/+$!',$dir)) $dir .= '/';\r
+                $template = str_replace($block,$trimmed,$template);\r
 \r
-     $filepath = $dir.$file;\r
+                $offset   = $begin+strlen($trimmed);\r
+            }\r
+            else break;\r
+        }\r
+\r
+        $this->set_template($template);\r
     }\r
 \r
-    if(is_file($filepath))\r
-    {\r
-     $inc = new Template;\r
-     $inc->read_file($filepath);\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
+        $template = $this->get_template();\r
 \r
-     $end = ($long == 1)\r
-          ? $start + strlen($file) + 2\r
-          : $start + strlen($file) + 1;\r
+        while(strpos($template,'<'.$condtag.'>') !== false) {\r
+            $start = strpos($template,'<'.$condtag.'>');                                        # Beginn des Blocks\r
+            $end   = strpos($template,'</'.$condtag.'>')+strlen($condtag)+3;                    # Ende des Blocks\r
 \r
-     $pre  = substr($template,0,$begin);\r
-     $post = substr($template,$end);\r
+            $extract = substr($template,$start,$end-$start);                                    # Kompletten Bedingungsblock extrahieren...\r
 \r
-     $template = $pre.$inc->get_template().$post;\r
-     $offset   = strlen($pre)+strlen($inc->get_template());\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
 \r
-     unset($inc);\r
+        $this->set_template($template);\r
     }\r
-   }\r
-  }\r
 \r
-  $this->set_template($template);\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
+        $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
+            $y++;\r
+\r
+            $start  = $begin+9;\r
+            $offset = $start;\r
+            $long   = 0;\r
+\r
+            if($template[$start] == '"') {\r
+                $long = 1;\r
+                $start++;\r
+            }\r
+\r
+            $file = '';\r
+            $skip = 0;\r
+\r
+            for($x=$start;$x<strlen($template);$x++) {\r
+                if($template[$x] == "\012" || $template[$x] == "\015") {\r
+                    $skip = 1;\r
+                    break;\r
+                }\r
+                elseif($long == 0 && $template[$x] == ' ') {\r
+                    $skip = 1;\r
+                    break;\r
+                }\r
+                elseif($long == 1 && $template[$x] == '"') {\r
+                    if($template[$x+1] != '}') $skip = 1;\r
+                    break;\r
+                }\r
+                elseif($long == 0 && $template[$x] == '}') {\r
+                    break;\r
+                }\r
+                else {\r
+                    $file .= $template[$x];\r
+                }\r
+            }\r
+\r
+            if($skip == 1) continue;\r
+\r
+            if($file != '') {\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
+                    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
+                    $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

patrick-canterino.de