Template Klasse - Rekursiv Pattern

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

  • #31
    /edit2: Ok, ich habs hingekriegt.
    Zuletzt geändert von OliOli; 14.10.2004, 21:05.

    Kommentar


    • #32
      Original geschrieben von TheBo
      wenn die Klasse von rythmus (oder so) zumindest funktionieren würde ... mein Post bei seiner Klasse wird ignorier ... und in ICQ antwortet er auch nicht ...

      ich "muss" auch andauernd support für meine scripte geben, und tuhe das auch nicht immer so gerne, aber ich weiss das ich anderen helfe.

      Also, bitte melde dich mal bei mir ! (162424599)
      Oh, hab den Post "drüben" nicht gesehen und lese fast nur hier im Brainstorming. ICQ bleibt zwecks Arbeitsmoral aus

      Schreib doch am besten mal ne email.

      Kommentar


      • #33
        So, weiter gehts mit Problemen.
        Ich hab die Klasse jetzt auf folgendem Stand:

        PHP-Code:
        class template {

            var 
        $open// Starttag der Platzhalter
            
        var $close// Endtag der Platzhalter
            
        var $clearopen// Starttag _ohne_ escape!
            
        var $clearclose// Endtag _ohne_ escape!
            
        var $values// Werte der zu ersetzenden Strings
            
        var $tplF// Template Verzeichnis
            
        var $fileType// Endung der Templates (.tpl, .htm o.ä.)

            // Definieren von Variablen
            
        function template($open='{'$close='}'$fileType='.tpl'$tplF='./') {
                
        $this->open preg_quote($open'/');
                
        $this->close preg_quote($close'/');
                
        $this->clearopen $open;
                
        $this->clearclose $close;
                
        $this->values = array();
                
        $this->fileType $fileType;
                
        $this->tplF $tplF;
            }

            
        // Den Platzhaltern Werte zuweisen
            // Wenn isFile = true, wird versucht eine Datei als Wert einzubinden
            
        function assign($var$value$isFile=false$tplFolder=false) {
                if(
        $tplFolder == false$tplFolder $this->tplF;
                if(
        $isFile == true) {
                    if(!
        is_readable($tplFolder.$value.$this->fileType)) {
                        
        trigger_error('File <b>'.$tplFolder.$value.$this->fileType.'</b> is not readable.',ERROR);
                    } else {
                        
        $this->values[$var] = file_get_contents($tplFolder.$value.$this->fileType);
                    }
                } else {
                    
        $this->values[$var] = $value;
                }
            }

            
        // Ausgabe der Templates
            
        function output($tpl) {
                if(!
        is_readable($this->tplF.$tpl.$this->fileType)) {
                    
        trigger_error('File <b>'.$this->tplF.$tpl.$this->fileType.'</b> is not readable.',FATAL);
                } else {
                    
        $content file_get_contents($this->tplF.$tpl.$this->fileType);
                    echo 
        $this->parse($content);
                }
            }

            
        // replace var
            
        function replace_var($key) {
                return 
        $this->values[$key[1]];
            }

            
        // Array ersetzen
            
        function replace_array($ar) {

                
        $pattern '/'.$this->open.'(.*?)'.$this->close.'/iU';
                
        $pattern2 '/'.$this->open.'array name=([^'.$this->close.']+)'.$this->close.'(.*?)'.$this->open.'\/array'.$this->close.'/iUm';

                
        $return '';
                for(
        $i=0;$i<count($this->values[$ar[1]]);$i++) {

                    
        $string $ar[2];
                    if(
        preg_match($pattern2$string)) $string $this->parse($string$only=2);

                    foreach(
        $this->values[$ar[1]][$i] AS $key => $val) {
                        
        $string str_replace($this->clearopen.$key.$this->clearclose,$val,$string);
                    }
                    
        // $string = $this->parse($string, $only=1);

                    
        $return .= $string;
                }

                return 
        $return;
            }

            
        // Parsen
            
        function parse($string$only=3) {
                if(
        $only != 2) {
                    
        // Ersetzen von Schleifen
                    
        $pattern '/'.$this->open.'array name=([^'.$this->close.']+)'.$this->close.'(.*?)'.$this->open.'\/array'.$this->close.'/iUm';
                    
        $string preg_replace_callback($pattern,array(&$this'replace_array'),$string);
                }

                if(
        $only != 1) {
                    
        // Ersetzen von einfachen Platzhaltern
                    
        $pattern '/'.$this->open.'(.*?)'.$this->close.'/i';
                    
        $string preg_replace_callback($pattern,array(&$this'replace_var'),$string);
                    
        $string $this->parse($string$only=1);
                }

                return 
        $string;
            }


        Derzeit habe ich noch 2 Probleme:
        1. Das Script sucht beim Ersetzen eines Arrays nach dem ersten Vorkommen von {array name=xxx} und nach dem letzten {/array}, egal ob die zusammengehören. Die ? sind im Regexp vorhanden, ich wüsste nicht, wo ich da noch eins zwischenbauen sollte...
        2. Wenn zwischen {array name=xxx} und {/array} ein Zeilenumbruch ist, trifft das Suchmuster nicht mehr zu, trotz Modifier "m".

        Vielen Dank für Hilfe im Vorraus.

        MfG Oli

        Kommentar


        • #34
          zu 1. unter den annahme, du benutzt keine verschachtelungen, U
          zu 2. m erfüllt andere zwecke, nimm s

          habe mir, btw, dein pattern nicht angeschaut ...
          Die Zeit hat ihre Kinder längst gefressen

          Kommentar


          • #35
            U verwende ich bereits als Modifier.
            Davon abgesehen, dass Verschachtelungen möglich sein sollen, gehts auch ohne nicht.

            s bei Zeilenumbrüchen funktioniert, danke.
            http://www.php-resource.de/tutorials/read/10/1/ laut diesem Tutorial ist m dafür aber geeignet, s wäre genau das Gegenteil.

            Kommentar


            • #36
              Davon abgesehen, dass Verschachtelungen möglich sein sollen, gehts auch ohne nicht.
              eventuell solltest du dann mal ein klartext-pattern zeigen ...

              für verschachtelungen solltest du dir mal (?R) anschauen ... dient erstmal nur dazu, die richtige verschachtelung zu finden.

              Code:
              #{array name=(.+)}(.+){/array}#isU
              matched bei meinen tests auf deine gegebenheit

              die { brauchst du scheinbar nicht slashen, weil php das wohl unterscheiden kann ...
              Zuletzt geändert von derHund; 15.10.2004, 22:22.
              Die Zeit hat ihre Kinder längst gefressen

              Kommentar


              • #37
                hi derHund,

                also dein Suchmuster funktioniert soweit.

                Das mit dem (?R) hab ich allerdings nicht verstanden.
                Ich hab mich mal hier (http://www.php-faq.de/ch/ch-regexp.html) umgesehen, aber da nichts darüber gefunden.

                MfG Oli

                Kommentar


                • #38
                  Ich denke mal, dass der Hund ausschließende Rules(=R) meint. Siehe das Tut auf dieser Seite (von Sky)

                  Kommentar


                  • #39
                    Das mit dem (?R) hab ich allerdings nicht verstanden.
                    http://www.php-resource.de/manual.ph...pattern.syntax

                    ganz unten, vorletzter abschnitt ... damit du den zugehörigen, schließenden tag findest ...
                    Die Zeit hat ihre Kinder längst gefressen

                    Kommentar


                    • #40
                      so, da bin ich wieder.

                      Also so wie ich derHund verstanden habe, muss ich mein Pattern so aufbauen:

                      Suche nach alle {array name=x} ... {/array}, wo in ... kein weiteres {array name=x} enthalten ist.

                      Das wäre zumindest die Lösung, da er dann Verschachtelungen von Innen nach außen ersetzt.

                      Mit den Assertions ist das allerdings ein bisschen komisch.

                      Mein Suchmuster sieht so aus:

                      Code:
                      #{array name=(.*?)} (.*) {/array}#isU
                      Jetzt muss ich es mit diesen Assertions schaffen, dass es nur zutrifft, wenn zwischen den Tags kein weiteres {array name=(.*?)} steht.

                      Code:
                      #{array name=(.*?)} (.*(?!:{array name=(.*?)})) {/array}#isU
                      Mein Denkansatz. Funktioniert leider nicht.

                      Ich hoffe, ich hab dich richtig verstanden, derHund.

                      MfG Oli
                      Zuletzt geändert von OliOli; 20.10.2004, 16:36.

                      Kommentar


                      • #41
                        Hallo,

                        Leider bin ich nach etlich langem rumprobieren immer noch zu keiner Lösung gekommen. Ich fasse mal zusammen, wo ich derzeit stehe:

                        Ich suche nach wie vor, einen pattern, der in einem templates zeichenketten wie {array name=(.*)} (.*) {/array} ersetzt durch den Rückgabewert einer Funktion.

                        Mein code:
                        PHP-Code:
                        $pattern '/'.$this->open.'array'.$add.' name=(.*)'.$this->close.'(.*)'.$this->open.'\/array'.$this->close.'/isU';
                                        
                        $string preg_replace_callback($pattern,array(&$this'replace_array'),$string); 
                        Folgende Probleme habe ich:
                        • Ich komme mit dem greedy nicht so ganz zurecht. Wenn ich einerseits verschachtelte, aber auch aufeinander folgende arrays habe, dann wird logischerweise immer was falsch gemacht. Bsp:
                          {array name=asdj} ich bin ein verschachtelrtes {array name=zweites} array {/array} und und und {/array} <br> {array name=drittes} Ich stehe hinter den beiden anderen {/array}
                          Wenn ich den modifier U oder ein ? nicht verwende, dann nimmt der das {array name=xxx} vom allerersten array, und das {/array} vom allerletzten. Die gehören dummerweise nicht zueinander. Wenn ich den modifier benutze, dann nimmt er logischerweise das erste {array name=xxx} und das erste {/array}, die ja auch nicht zueinander gehören. Hier hab ich nur einen Lösungsansatz: Wenn ich den regex so wenig wie möglich fressen lasse, ihm aber sage, dass zwischen den tags kein array name=xxx} vorkommen darf, dann müsste er sich von innen nach außen vorarbeiten können. Wie ich das mache, ist mir aber schleierhaft.
                        • Verschachtelungen sind zwar, das habe ich inzwischen soweit verstanden, mit (?R) also recursive pattern lösbar, aber wie genau das auszusehen hat, weiß ich noch nicht.


                        Wäre super nett, wenn ihr versucht mir nochmal zu helfen.
                        Immer bedenken, dass ich php (noch) nicht gut kann.

                        MfG Oli

                        Kommentar


                        • #42
                          Ich suche nach wie vor, einen pattern, der in einem templates zeichenketten wie {array name=(.*)} (.*) {/array} ersetzt durch den Rückgabewert einer Funktion.
                          anderer vorschlag:

                          lass es einfach durch block_$1 ersetzen.

                          Kommentar


                          • #43
                            hab ich auch schon dran gedacht, aber erstmal muss er ja das passende {/array} zum {array name=xxx} finden

                            Kommentar


                            • #44
                              hab ich auch schon dran gedacht, aber erstmal muss er ja das passende {/array} zum {array name=xxx} finden
                              das passende findest du mit hilfe von ?R. dazu ist es da.

                              kuckst du: http://pcre.nophia.de/evaluate/267c6...dex.php#output bzw. http://pcre.nophia.de/evaluate/1a7b9...dex.php#output

                              in \1 findest du den namen, in \2 den inhalt, den du erneut - vorzugsweise rekursiv - parsen mußt. siehe auch das beispiel in den codeschnipseln.
                              Zuletzt geändert von derHund; 31.10.2004, 13:10.
                              Die Zeit hat ihre Kinder längst gefressen

                              Kommentar


                              • #45
                                Vielen lieben Dank, alle zusammen.

                                Die Klasse funktioniert jetzt so, wie sie soll.

                                Hier nochmal das ganze:

                                PHP-Code:
                                <?php class template {

                                    var 
                                $open// Starttag der Platzhalter
                                    
                                var $close// Endtag der Platzhalter
                                    
                                var $values// Werte der zu ersetzenden Strings
                                    
                                var $tplF// Template Verzeichnis
                                    
                                var $fileType// Endung der Templates (.tpl, .htm o.ä.)
                                    
                                var $m// Zähler für Arrays

                                    // Definieren von Variablen
                                    
                                function template($open='{'$close='}'$fileType='.tpl'$tplF='./') {
                                        
                                $this->open $open;
                                        
                                $this->close $close;
                                        
                                $this->values = array();
                                        
                                $this->fileType $fileType;
                                        
                                $this->tplF $tplF;
                                        
                                $this->0;
                                    }

                                    
                                // Den Platzhaltern Werte zuweisen
                                    // Wenn isFile = true, wird versucht eine Datei als Wert einzubinden
                                    
                                function assign($var$value$isFile=false$tplFolder=false) {
                                        if(
                                $tplFolder == false$tplFolder $this->tplF;
                                        if(
                                $isFile == true) {
                                            if(!
                                is_readable($tplFolder.$value.$this->fileType)) {
                                                
                                trigger_error('File <b>'.$tplFolder.$value.$this->fileType.'</b> is not readable.',ERROR);
                                            } else {
                                                
                                $this->values[$var] = $this->parse(file_get_contents($tplFolder.$value.$this->fileType),2);
                                            }
                                        } else {
                                            
                                $this->values[$var] = $value;
                                        }
                                    }

                                    
                                // Ausgabe der Templates
                                    
                                function output($tpl) {
                                        if(!
                                is_readable($this->tplF.$tpl.$this->fileType)) {
                                            
                                trigger_error('File <b>'.$this->tplF.$tpl.$this->fileType.'</b> is not readable.',FATAL);
                                        } else {
                                            
                                $content file_get_contents($this->tplF.$tpl.$this->fileType);
                                            echo 
                                $this->parse($content);
                                        }
                                    }

                                    
                                // replace var
                                    
                                function replace_var($key) {
                                        return 
                                $this->values[$key[1]];
                                    }

                                    
                                // Array ersetzen
                                    
                                function replace_array($ar) {
                                        
                                $pattern '/'.$this->open.'array name=(.*?)'.$this->close.'(.*)'.$this->open.'\/array'.$this->close.'/is';

                                        
                                $return '';
                                        for(
                                $i=0;$i<count($this->values[$ar[1]]);$i++) {
                                            
                                $string $ar[2];
                                            if(
                                preg_match($pattern$string)) 
                                                
                                $string $this->parse($string$only=1);
                                            foreach(
                                $this->values[$ar[1]][$i] AS $key => $val) {
                                                
                                $string str_replace($this->open.$key.$this->close,$val,$string);
                                            }
                                            
                                $return .= $string;
                                        }

                                        return 
                                $return;
                                    }

                                    
                                // Parsen
                                    
                                function parse($string$only=3) {
                                        if(
                                $only != 1) {
                                            foreach(
                                $this->values AS $key => $val) {
                                                if(!
                                is_array($val)) {
                                                    
                                $string str_replace($this->clearopen.$key.$this->clearclose,$val,$string);
                                                }
                                            }
                                        }
                                        if(
                                $only != 2) {
                                            
                                $pattern '/'.$this->open.'array name=(.*)'.$this->close.'(((?R)|(.*))*)'.$this->open.'\/array'.$this->close.'/isU';
                                            
                                $string preg_replace_callback($pattern,array(&$this'replace_array'),$string);
                                        }
                                        return 
                                $string;
                                    }
                                ?>
                                Was kann die Klasse?
                                • Normale Platzhalter entweder durch strings oder durch Dateien ersetzen, in denen wiederum Platzhalter entahlten sein dürfen. (AFAIK unendlich tiefe verschachtelung möglich)
                                • Ersetzen von arrays, nach dem Schema {array name=ARRAY_NAME} text {ARRAY_ITEM} {/array}. Verschachtelungen beliebig tief möglich.


                                MfG Oli

                                Kommentar

                                Lädt...
                                X