[Template-Klasse] Parsen von Blöcken

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • [Template-Klasse] Parsen von Blöcken

    Hi,

    nachdem man mir erfolgreich eval ausgeredet hat, habe ich bis jetzt sowas als vorübergehende template klasse geschrieben :


    (Hinweis: ich mixe atm noch deutsch und englisch, aber diese klasse ist bis jetzt nichts weiter als ein persönliches brainstorming)


    PHP-Code:
    class tpl
    {
        var 
    $template_dir '';
        var 
    $pattern = array();
        var 
    $replace = array();
        var 
    $delimiter '/'// Delimiter for regular expression
        
    var $option 'i'// i = ignore Upper/Lower Case
        
        
    function tpl($dir '')
        {
            
    $this->template_dir $dir;
        }
        
        function 
    insert_key($key$value)
        {
            
    // Key schon vorhanden ?
            
    $found false;
            
    $c count($pattern);
            
            for(
    $i=0$i<$c$i++) // key suchen
            
    {
                if(
    $pattern[$i] == $pattern) {
                    
    $replace[$i] = $value;
                    
    $found true;
                    break;
                }
            }
            
            if(!
    $found) { // neuen Key einsetzen
                
    $this->pattern[] = $delimiter.$key.$delimiter.$option;
                
    $this->replace[] = $delimiter.$value.$delimiter.$option;
            }
        }
        
        function 
    reset_keys()
        {
            
    // alle Suchmuster + Ersetzungen löschen
            
    $this->pattern = array();
            
    $this->replace = array();
        }
        
        function 
    parse_file($file)
        {
            
    // Datei einlesen und Suchmuster durch Ersetzungen ersetzen
            
    $inhalt preg_quote(file_get_contents($this->template_dir.$file), '/');
            
    $inhalt preg_replace($patterns$replaces$inhalt);
            return 
    $inhalt;
        }

    Also was bisher geht, ist einfach einen beliebigen Schlüssel im Template durch eine beliebige Variabale zu ersetzen.
    So weit, so langweilig...


    Wie Parse ich jetzt am besten so blöcke wie <!-- if(bedingung --> ... <!-- endif(bedingung) -->

    oder noch schlimmer : <!-- for(startwert, bedingung, var-veränderung --> <!-- endfor -->


    Klar, ich könnte jetzt den Quelltext von Smarty durcharbeiten, aber das is mir zuviel Arbeit die ganzen Dateien auseinanderzunehmen, und ich wollte schon einen eigenen Ansatz versuchen...
    Wie ich mit REGEX an die tags komme ist kein Problem, nur geht es mir ganz allgemein darum, wie ich diese blöcke finden soll und wie ich diese Suche am effizientesten aufbaue...

    hat da jmd. vielleicht paar Allgemeine Ideen für einen Ansatz ?

    Soll ich mit rekursiven schleifen (wegen verschachtelung) nach solchen tags suchen, oder gibs da nen besseren weg ?


    cya max


    An mich bitte keine unaufgeforderten E-Mails senden (ausser ihr seid bereit geld zu zahlen, dann gerne )

  • #2
    Re: [Template-Klasse] Parsen von Blöcken

    Original geschrieben von MaxP0W3R
    Wie Parse ich jetzt am besten so blöcke wie <!-- if(bedingung --> ... <!-- endif(bedingung) -->

    oder noch schlimmer : <!-- for(startwert, bedingung, var-veränderung --> <!-- endfor -->
    garnicht, das ist Programmlogik und hat im Template nichts zu suchen.

    Du kannst im Template die Blöcke definieren

    {block abc}
    .....
    {/block abc}

    ob dieser jedoch ausgefüllt wird, oder verworfen entscheidet das PHP Script
    TBT

    Die zwei wichtigsten Regeln für eine berufliche Karriere:
    1. Verrate niemals alles was du weißt!


    PHP 2 AllPatrizier II Browsergame

    Kommentar


    • #3
      in anderen Threads heisst es immern, sachen wie <!-- if ... wären das nützlichste überhaupt...


      da scheiden sich wohl immer noch die geister...

      ich meine wenn man das nicht benutzt , dann wäre die klasse ja "fertig", fehlt bloss noch ein cache system


      An mich bitte keine unaufgeforderten E-Mails senden (ausser ihr seid bereit geld zu zahlen, dann gerne )

      Kommentar


      • #4
        aktueller stand des "projekts"

        PHP-Code:
        <?php
        class tpl
        {
            var 
        $template_dir '';
            var 
        $pattern = array();
            var 
        $replace = array();
            var 
        $delimiter '/'// Delimiter for regular expression
            
        var $option 'i'// i = ignore Upper/Lower Case
            
            
        function tpl($dir '')
            {
                
        $this->template_dir $dir// Verzeichnis zuweisen
                // Standard Variablen festlegen
                # 1. Zeiger auf die aktuelle Datei
                
        $this->pattern[] = $delimiter.'{PHP_SELF}'.$delimiter.$option;
                
        $this->replace[] = $delimiter.$_SERVER['PHP_SELF'].$delimiter.$option;
                
        # 2. Aktuelles Datum
                
        $this->pattern[] = $delimiter.'{datum'}.$delimiter.$option;
                
        $this->replace[] = $delimiter.date('d.m.Y').$delimiter.$option;
                
        # 3. Aktuelle Uhrzeit
                
        $this->pattern[] = $delimiter.'{uhrzeit}'.$delimiter.$option;
                
        $this->replace[] = $delimiter.date('H:i:s').$delimiter.$option;
            }
            
            function 
        insert_key($key$value)
            {
                
        // Key schon vorhanden ?
                
        $found false;
                
        $c count($pattern);
                
                for(
        $i=0$i<$c$i++) // key suchen
                
        {
                    if(
        $pattern[$i] == $pattern) {
                        
        $replace[$i] = $value;
                        
        $found true;
                        break;
                    }
                }
                
                if(!
        $found) { // neuen Key einsetzen
                    
        $this->pattern[] = $delimiter.$key.$delimiter.$option;
                    
        $this->replace[] = $delimiter.$value.$delimiter.$option;
                }
            }
            
            function 
        reset_keys()
            {
                
        // alle Suchmuster + Ersetzungen löschen
                
        $this->pattern = array();
                
        $this->replace = array();
            }
            
            function 
        parse_file($file)
            {
                
        // Datei einlesen und Suchmuster durch Ersetzungen ersetzen
                
        $inhalt preg_quote(file_get_contents($this->template_dir.$file), '/');
                
        $inhalt preg_replace($patterns$replaces$inhalt);
                
        // include bearbeiten
                
        $include preg_grep("/<!-- include(+) -->/");
                foreach(
        $include as $include_file)
                {
                    
        // Inhalt der zu includierenden Datei holen
                    
        $ifile str_replace('<!-- include('''$include_file);
                    
        $ifile str_replace(') -->'''$ifile);
                    
        $include_content file_get_contents($i_file);
                    
        // includierte datei in Template einfügen
                    
        $inhalt preg_replace($include_file$include_content$inhalt);
                }
                    
                }
                return 
        $inhalt;
            }
        }
        ?>
        Beispieldatei:

        Code:
        <html>
        <head>
        	<title>Beispiel für ein Template</title>
        </head>
        <body>
        <h3 align="center">Dies ist ein Beispiel für ein normales Template.</h3>
        
        <p>Die verschiedenen Funktionen werde hier alle mit einem Beispiel gezeigt und
        erklärt.</p>
        
        <p><b>1. <u>Variablen</u> </b>
        Variablen Ersetzung
        
        Die Variable Name hat den Wert {name}.
        
        Die Template Klasse ersetzt {name} durch den Wert, der {name} im PHP
        Skript zugewiesen wurde. Wurde für {name} kein Wert definiert, so wird {name}
        direkt ausgegeben.
        
        Diese Datei heisst {PHP_SELF}. 
        
        Man kann PHP_SELF benutzen, um einen Link zur aktuellen Datei zu machen, z.B.
        wenn das Formular und das Formularauswerteskript ein und die selbe Datei sind:
        
        Beispiel:
        
        <form action="{PHP_SELF}" method="POST">
        <input type="submit" name="Submit" value="Ruf dich selbst auf!">
        </form>
        
        Heute ist der {datum}. Es ist {uhrzeit} Uhr.
        
        datum und uhrzeit stellen immer das aktuelle Datum und die aktuelle Uhrzeit dar.
        </p>
        
        <p><b>1. <u>Dateien einbinden</u> </b>
        Manchmal ist es erforderlich, andere Dateien einzubinden.
        
        Dies kann mit dem Befehl <!-- include(test.php) --> gemacht werden.
        
        <!-- --> stellt gleichzeitig auch einen HTML Kommentar dar, so dass der Include
        Befehl in Programmen wie Dreamweaver nicht in der Vorschau-Ansicht zu sehen ist.
        Dies soll der Übersicht und einfachen Bearbeitbarkeit von Template-Dateien dienen.
        
        Im obigen Beispiel wird nun an genau dieser Stelle die Datei test.php eingebunden.
        </p>
        </body>
        </html>

        habe mich nun entschieden, keine schleifen und kein if zu machen, mein chef meint brauchen wir nicht, der andere coder meint auch dass wir das nich brauchen...


        An mich bitte keine unaufgeforderten E-Mails senden (ausser ihr seid bereit geld zu zahlen, dann gerne )

        Kommentar


        • #5
          habe mich nun entschieden, keine schleifen und kein if zu machen,
          :thumbup:

          aber 'blöcke' baust du noch ein, oder?
          Die Zeit hat ihre Kinder längst gefressen

          Kommentar


          • #6
            was meinst du jetzt damit ?

            also aktueller stand is:

            - variablen (einige vordefiniert, wie PHP_SELF, datum, uhrzeit)
            - includen von dateien
            - eval (aber standardmässig aus, nur für sonderfälle)

            jetzt mache ich gerade tabellen, es soll so sein, dass die zeilen alternieren können, z.B. einmal heller huntergrund einmal dunkel usw

            bin da gerade ein wenig am tüfteln...


            An mich bitte keine unaufgeforderten E-Mails senden (ausser ihr seid bereit geld zu zahlen, dann gerne )

            Kommentar


            • #7
              was meinst du jetzt damit ?
              *grrr* schau in den gestrigen thread zum thema, wills nicht nochmal ausführen, halt sich wiederholende, bzw. bedingte html-blöcke, die dir die möglichkeit von schleifen/bedingten parsen geben ... -> imho essenziell

              brauchst du auch für
              dass die zeilen alternieren können, z.B. einmal heller huntergrund einmal dunkel usw
              aber: die logik des alternierens kommt in die jeweilige php-datei! setz halt modulo-mäßig nen anderen rewriter ... nicht, daß du das ins tpl einbaust ...
              Die Zeit hat ihre Kinder längst gefressen

              Kommentar


              • #8
                hab mir das im template so gedacht :

                Code:
                <table align="center" cellspacing="0" cellpadding="0">
                <tr>
                	<th>blabla</th>
                	<th>blubb<7th>
                	<th>hjhjh</th>
                </tr>
                <!-- datensatzreihe(queryname) -->
                
                <tr <!-- alternierend(farbe1, farbe2) -->>
                	<td>{datensatz1}</td>
                	<td>{datensatz2}</td>
                	<td>{datensatz3}</td>
                <!-- datensatzreihe ende -->
                </tr>
                </table>
                oder findest du dass das ne schlechte idee ist ?

                die Template klasse sucht das query über nen namen, führt diesen aus, parst die tr zeile und bei alternierend wird dann immer was anderes eingesetzt

                z.B.

                <tr style="bg-color=<!--alternierend(navy,#FFF,#CCC) -->">
                ...

                der alternierend kommentar wird dann durch die "aktuelle farbe" ersetzt

                so dachte ich mir das zumindest

                edit: so nach mehrmaligem durchdenken finde ich die lösung aber so auch nicht ganz optimal

                hat jmd. eine idee, wie das im template selbst aussehen soll ?

                wäre cool, wenn ein reiner htmler mir mal posten würde, wie er das gerne hätte ^^

                Zuletzt geändert von MaxP0W3R; 12.10.2004, 15:18.


                An mich bitte keine unaufgeforderten E-Mails senden (ausser ihr seid bereit geld zu zahlen, dann gerne )

                Kommentar


                • #9
                  hi MaxP0W3R

                  Wie du an meinem Thread siehst, interessier ich mich auch für templates. Im Moment zumindest.

                  PHP-Code:
                  $include preg_grep("/<!-- include(+) -->/");
                          foreach(
                  $include as $include_file)
                          {
                              
                  // Inhalt der zu includierenden Datei holen
                              
                  $ifile str_replace('<!-- include('''$include_file);
                              
                  $ifile str_replace(') -->'''$ifile);
                              
                  $include_content file_get_contents($i_file);
                              
                  // includierte datei in Template einfügen
                              
                  $inhalt preg_replace($include_file$include_content$inhalt);
                          } 
                  2 Fragen. Laut php.net benötigt preg_grep() ein array als Argument, in welchem es nach dem angegebenen string sucht. Wo ist das bei dir?
                  Außerdem verstehe ich nciht, wo bei dir die Variable $i_file herkommt.

                  MfG Oli

                  Kommentar


                  • #10
                    hi, hab glaub ich die funktion verwechselt, dachte preg_grep durchsucht nen string...


                    hab mir eben smarty durchgesehen, mir gefällt die idee, ein template zu parsen und dann in eine reine php datei umzuwandeln...


                    An mich bitte keine unaufgeforderten E-Mails senden (ausser ihr seid bereit geld zu zahlen, dann gerne )

                    Kommentar


                    • #11
                      die funktion die ich brauch eis preg_match_all

                      das is der aktuelle stand, aber ich spiele mit dem gedanken, die templates in php dateien zu parsen...

                      Hinweis: die funktionen sind weder vollständig, noch logisch zu ende gedacht noch getestet

                      alles nur brainstorming bis jetzt für den groben ablauf
                      PHP-Code:
                      class tpl
                      {
                          var 
                      $template_dir '';
                          var 
                      $pattern = array();
                          var 
                      $replace = array();
                          var 
                      $delimiter '/'// Delimiter for regular expression
                          
                      var $option 'i'// i = ignore Upper/Lower Case
                          
                      var eval_allowed false// eval in Templates standardmässig aus
                          
                          #--------------------------#
                          
                      var db_handle false// Verbindung zur datenbank
                          
                      var querys = array(); // Die Query
                          
                          
                      function tpl($dir '')
                          {
                              
                      $this->template_dir $dir// Verzeichnis zuweisen
                              // Standard Variablen festlegen
                              # 1. Zeiger auf die aktuelle Datei
                              
                      $this->pattern[] = $delimiter.'{PHP_SELF}'.$delimiter.$option;
                              
                      $this->replace[] = $delimiter.$_SERVER['PHP_SELF'].$delimiter.$option;
                              
                      # 2. Aktuelles Datum
                              
                      $this->pattern[] = $delimiter.'{datum'}.$delimiter.$option;
                              
                      $this->replace[] = $delimiter.date('d.m.Y').$delimiter.$option;
                              
                      # 3. Aktuelle Uhrzeit
                              
                      $this->pattern[] = $delimiter.'{uhrzeit}'.$delimiter.$option;
                              
                      $this->replace[] = $delimiter.date('H:i:s').$delimiter.$option;
                          }
                          
                          function 
                      insert_key($key$value)
                          {
                              
                      // Key schon vorhanden ?
                              
                      $found false;
                              
                      $c count($pattern);
                              
                              for(
                      $i=0$i<$c$i++) // key suchen
                              
                      {
                                  if(
                      $pattern[$i] == $pattern) {
                                      
                      $replace[$i] = $value;
                                      
                      $found true;
                                      break;
                                  }
                              }
                              
                              if(!
                      $found) { // neuen Key einsetzen
                                  
                      $this->pattern[] = $delimiter.$key.$delimiter.$option;
                                  
                      $this->replace[] = $delimiter.$value.$delimiter.$option;
                              }
                          }
                          
                          function 
                      reset_keys()
                          {
                              
                      // alle Suchmuster + Ersetzungen löschen
                              
                      $this->pattern = array();
                              
                      $this->replace = array();
                          }
                          
                          function 
                      parse_file($file)
                          {
                              
                      // Datei einlesen und Suchmuster durch Ersetzungen ersetzen
                              
                      $inhalt preg_quote(file_get_contents($this->template_dir.$file), '/');
                              
                      $inhalt preg_replace($patterns$replaces$inhalt);
                              
                      // include bearbeiten
                              
                      preg_match_all('/<!-- include(+) -->/'$inhalt$include);
                              foreach(
                      $include as $include_file)
                              {
                                  
                      // Inhalt der zu includierenden Datei holen
                                  
                      $ifile str_replace('<!-- include('''$include_file);
                                  
                      $ifile str_replace(') -->'''$ifile);
                                  
                      $include_content file_get_contents($i_file);
                                  
                      // includierte datei in Template einfügen
                                  
                      $inhalt preg_replace($include_file$include_content$inhalt);
                              }
                              
                      // eval bearbeiten
                              
                      if($this->eval_allowed) {
                                  
                      $eval preg_grep('/<!-- eval(+) -->/');
                                  foreach(
                      $eval as $code)
                                  {
                                      
                      $clean_code str_replace('<!-- eval('''$code);
                                      
                      $clean_code str_replace(')-->'''$code);
                                      eval(
                      str_replace('"','',$clean_code);
                                      
                      preg_replace($code''$inhalt)
                                  }
                              }
                              
                      // tabellen mit datenbankinformationen füllen
                              
                      $inhalt parse_tables($inhalt);
                                  
                              }
                              return 
                      $inhalt;
                          }
                          
                      //|---------------------------------------------------------------------------
                          //|                     Funktionen mit Datenbankunterstützung
                          //|---------------------------------------------------------------------------
                          
                      function set_db_handle($db_handle)
                          {
                              
                      // das handle, das benutzt werden soll
                              
                      $this->db_handle $db_handle;
                          }
                          
                          function 
                      insert_query($name$query)
                          {
                              
                      // fügt einen QUery hinzu, der im Template benutzt wird
                              
                      $this->querys[$name] = $query;
                          }
                          
                          function 
                      parse_tables($inhalt)
                          {
                              
                      preg_match_all('/<!-- datensatzreihe(+) -->*<!-- datensatzreihe
                               ende -->/'
                      $inhalt$data);
                              foreach(
                      $data as $row)
                              {
                                  
                      // alternierende farben ?
                                  
                      $anzahl_alternierend 0;
                                  if(
                      preg_match('<!-- alternierend(farbe1, farbe2) -->'$row)) {
                                      
                      $farben str_replace('<!-- alternierend('''$row);
                                      
                      $farben str_replace(') -->'''$farben);
                                      
                      $farben_array explode($farben',');
                                      
                      $anzahl_alternieren count($farben);
                                  }
                                  
                      // query ausführen
                                  
                      $query 
                                  
                      $ergebnis mysql_query($query
                                  
                      // zeilen zusammensetzen
                                  // zeilen einfügen
                              
                      }



                      An mich bitte keine unaufgeforderten E-Mails senden (ausser ihr seid bereit geld zu zahlen, dann gerne )

                      Kommentar


                      • #12
                        oder findest du dass das ne schlechte idee ist ?
                        ehrlich gesagt, ja

                        bei mir steht z.b. einfach
                        Code:
                        <tr class="{{CLASS}}">
                        und in der zugehörigen php-datei wird dann halt
                        PHP-Code:
                                  'CLASS'    => ($i++%2==0) ? 'odd' 'even' 
                        übergeben ... diese funktion extra ins tpl zu packen wäre mir zu aufwendig und auch zu speziell ... außerdem sollte die tpl-klasse wohl kaum queries ausführen! ...

                        edit: die tpl-klasse kann praktisch nichts selber, außer in einem ausgewählten block alle unterblöcke finden, platzhalter ersetzen, ausgabe erstellen ...

                        bei mir wird halt alles in der zugehörigen php-datei gemacht, ... (unter)block auswählen, rewriter setzen (die ich mir z.b. vorher aus der db hole), parsen anstoßen, ausgabe anstoßen ...
                        Zuletzt geändert von derHund; 12.10.2004, 17:43.
                        Die Zeit hat ihre Kinder längst gefressen

                        Kommentar


                        • #13
                          naja, wenn man mit templates arbeitet um anwendungs- und ablauflogik von der präsentationslogik zu trennen, dann doch hin und wieder wohl auch aus dem grund, dass der entwickler sich nicht auch noch um die grafische darstellung kümmern muss und der html-and-css-highly-qualified-specialist-engineer keine ahnung von programmierung hat

                          in anbetracht dieser tatsache fände ich
                          Code:
                          <tr class="{CYCLE name=(farbwechsel_1) values=(green,black,something_else)}">
                          toller so müssen die css-klassen nicht im php-code stehen, wo sie ja eigentlich auch nichts zu suchen haben und der designer muss sich nicht drum kümmern die klassennamen irgendwo in einer datenbank auszulesen, auf dass sie dann vom skript ausgelesen werden

                          das name=(farbwechsel_1) hab ich mir ausgedacht, weil es ja hin und wieder vorkommen soll, dass man sowas in der art machen will/soll/muss/darf:
                          [color=red]1 - 1 2 - 1 3 - 1 4 - 1 [/color]
                          [color=blue]1 - 1 2 - 1 3 - 1 4 - 1 [/color]
                          [color=red]1 - 1 2 - 1 3 - 1 4 - 1 [/color]
                          [color=blue]1 - 1 2 - 1 3 - 1 4 - 1 [/color]
                          man also zwei sachen (hier: farbe und font-style) wechseln will

                          die templateklasse sollte das natürlich auslesen und in einem array der art
                          Code:
                          Array
                          (
                              [farbwechsel_1] => Array
                                  (
                                      [0] => green
                                      [1] => black
                                      [2] => something_else
                                  )
                              [schriftwechsel_1] => Array
                                  (
                                      [0] => standardschrift
                                      [1] => kursiv
                                  )
                          )
                          speichern, von wo die werte dann beim eigentlichen parsen gezogen werden
                          Zuletzt geändert von mrhappiness; 13.10.2004, 07:02.
                          Ich denke, also bin ich. - Einige sind trotzdem...

                          Kommentar

                          Lädt...
                          X