Template Klasse - Funktionsprinzip

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

  • Template Klasse - Funktionsprinzip

    Ich mache mir seit einigen Tagen Gedanken um die Funktionsweisen von Template Klassen, da ich eine eigene, eher kleine Klasse schreiben möchte. Soweit kein Problem. Was mir nur Kopfzerbrechen bereitet, sind Blöcke.
    Also habe ich mir erstmal die verschiedensten Systeme angesehen und so einige Themen in diesem Forum durchgelesen, bin nur leider noch zu keinem Ergebnis gekommen. Was Blöcke sind und wie sie ersetzt werden, ist dabei nicht das Problem, sondern vielmehr, welches Funktionsprinzip gerade bei verschachtelten Blöcken sinnvoll ist.

    Beispiel:
    PHP-Code:
    $names = array(
        
    => array(
            
    'car' => 'carname_1',
            
    'colors' => array(
                
    => 'color_1',
                
    => 'color_2',
            ),
        ),
        
    => array(
            
    'car' => 'carname_2',
            
    'colors' => array(
                
    => 'color_1',
                
    => 'color_2',
            ),
        ),
    ); 
    Dazugehörige Blockstruktur (Beispiel):
    PHP-Code:
    <!-- block namecars -->
      {
    carname}
      <!-- 
    block namecars.colors -->
        {
    color}
      <!-- 
    end blockcars.colors -->
    <!-- 
    end blockcars --> 

    Die meisten oder zumindest viele Systeme funktionieren ja nach folgendem Prinzip - wenn ich es richtig verstanden habe:
    Ein Parser sucht - meist per preg_match_all, while (preg_match) oder auch per strpos, strlen usw. - nach dem bzw. den Vorkommen von Blöcken. Wurde ein Block gefunden, wird der Name extrahiert, ein Array, in dem alle Variablen abgelegt wurden, mit dem passenden Schlüssel Blockname iteriert und die Platzhalter durch Werte ersetzt. Und hier kommt meine Frage:

    Ist es gerade bei verschachtelten Blöcken wie in meinem Beispiel nicht sinnvoller, die Verarbeitung nach dieser Reihenfolge vorzunehmen:

    Statt erst mit preg_match_all & Co nach Platzhaltern und Blöcken zu suchen, wird das Array, in dem alle Blöcke und Variablen abgelegt sind (z.b. var $block_vars) durchlaufen und dann geprüft, ob zu jedem Blocknamen auch tatsächlich ein Block existiert. Der Vorteil: Ich muss mir erstmal keine Gedanken um verschachtelte Blöcke machen, denn ich muss einfach nur überprüfen, ob $block_vars mit jedem Blocknamen eventuell noch ein multidimensionales Array enthält, was bedeuten würde, dass auch ein verschachtelter Block existieren muss. Das müsste dann um einiges leichter zu verarbeiten seinn. (Ich hoffe das ist halbwegs verständlich).
    Grund für meine Frage: Ich stelle es mir eben ziemlich mühsam und kompliziert vor, erstmal alle Blocknamen beispielsweise nach dem Vorkommen eines Punktes zu überprüfen, bei Erfolg dann den Blocknamen zu exploden, damit ich dann alle weiteren Kinderblöcke abarbeiten kann.

    Was haltet ihr von meiner Idee? Habe ich etwas Grundlegendes außer Acht gelassen? Ich würde mich freuen, eure Meinungen zu hören, besonders, da viele weitaus mehr Erfahrung mit Template Systemen haben als ich und mir dieser Ansatz bisher noch nicht begegnet ist.
    Zuletzt geändert von Griecherus; 23.11.2006, 16:18.
    Nieder mit der Camel Case-Konvention

  • #2
    Meine Meinung: Vergiss das Template-System. PHP selbst ist schon praktisch eine Template-Engine (der Satz stammt nicht von mir), jegliche Tempalte-Engine verlangsamt die Ausführung der Skripte unnötiger weise.
    Per CSS kann man praktisch jegliches XHTML so rücken, dass es so ist wie man es haben will, wieso also auf ein Template-System setzen?

    Ein netter Guide zum übersichtlichen Schreiben von PHP/MySQL-Code!

    bei Klammersetzung bevorzuge ich jedoch die JavaCoding-Standards
    Wie man Fragen richtig stellt

    Kommentar


    • #3
      Dass PHP ursprünglich als eine Art Template-Engine gedacht war, ist mir bewusst. Dass sie sich auch heute noch als solche eignet, natürlich ebenso. Insofern kann und will ich dir da auch nicht widersprechen.
      Mir geht es nur darum, Feedback auf meinen Lösungsansatz zu bekommen, auch wenn man sich über den Sinn von Template-Engines streiten kann (wie es bestimmt noch bis in die Ewigkeit der Fall sein wird). Trotzdem danke.
      Nieder mit der Camel Case-Konvention

      Kommentar


      • #4
        Jetzt wo man mit Simplexml auch einfach Elemente anlegen kann, liegt es schon sehr nahe das zu tun und das ausgegebene XML mit XSLT zu transformieren.

        Kommentar


        • #5
          Ich habe hier und da zwar schon über XML gelesen, nur mich noch nicht wirklich damit auseinandergesetzt... danke erstmal für den Hinweis, ich werde mir das bei Gelegenheit mal genauer anschauen.

          Ich würde mich trotzdem noch über die eine oder andere Meinung zu meiner eigentlichen Frage freuen.
          Nieder mit der Camel Case-Konvention

          Kommentar


          • #6
            Re: Template Klasse - Funktionsprinzip

            Original geschrieben von Griecherus
            Ich stelle es mir eben ziemlich mühsam und kompliziert vor, erstmal alle Blocknamen beispielsweise nach dem Vorkommen eines Punktes zu überprüfen, bei Erfolg dann den Blocknamen zu exploden, damit ich dann alle weiteren Kinderblöcke abarbeiten kann.
            wieso alle blöcke durchsuchen? normalerweise spricht man ja vor/während der zuweisung den zu benutzenden block explizit an. prinzipiell sollte das ganze so ablaufen:
            PHP-Code:
            $tpl->setCurrentBlock('cars'); //Im Haupttemplate zu einem Block wechseln
            foreach($cars as $car)
             {
              
            $tpl->setVar('carname'$car); //Auto dem Block zuweisen
              
            $tpl->setCurrentBlock('colors'); //Innerhalb eines Blockes zu einem Unterblock wechseln
              
            foreach($colors as $color)
               {
                
            $tpl->setVar('color'$color); //Farbe dem Unterblock zuweisen
                
            $tpl->parseBlock(); //Unterblock parsen (dem Block zuweisen)
               
            }
              
            $tpl->parseBlock(); //Block parsen (dem Haupttemplate zuweisen)
             

            wenn ich dich jetzt richtig verstanden habe, möchtest du dem template das geschachtelte array komplett zuweisen und deine template engine erkennt aufgrund der schachtelung die einzelnen blöcke. Intern wird dann sozusagen automatisch setCurrentBlock(), setVar() und parseBlock() aufgerufen.
            ich denke, das ist nicht so flexibel wie o.g. methode und auch komplizierter anfangs erst ein komplex geschachteltes array für die zuweisung aufzubereiten.

            Kommentar


            • #7
              Erstmal danke für deinen Beitrag.

              Genau so habe ich mir das gedacht, ja. Blöcke sollen also nicht explizit geparst werden müssen, da die Klasse intern das Array auseinandernimmt und selbst erkennt, welcher Block sich wo befindet und ob eine Verschachtelung vorliegt oder nicht. Dazu "Inspiriert" hat mich hauptsächlich Smarty (was ausschließlich auf Blöcke bzw. Sektionen bezogen ist).

              Und da es - genau wie du ja gesagt hast - relativ kompliziert ist, das so abzuarbeiten, wie es die phplib Template-Engine und Konsorten tun, habe ich mich gefragt, wieso man das ganze vom Prinzip her nicht umgekehrt angeht. Also nicht erst in einem Template nach einem Block suchen und die Platzhalter dann ersetzen, sondern erstmal (ohne Rücksicht auf jegliche Block-Vorkommen) das Array durchlaufen und bei jedem Blocknamen, der auftacht, den passenden Block suchen. Denn dann müsste ich ja nur überprüfen, ob das Array ab einem bestimmten Punkt noch mehrdimensional ist, um einen verschachtelten Block zu identifizieren.

              Beispiel:
              PHP-Code:
              $block_vars = array(
                  
              'cars' => array(
                      
              'car' => 'carname_1',
                      
              'colors' => array( // und hier wird deutlich, dass ein verschachtelter Block vorliegen -müsste-
                          
              'color_1' => 'white',
                          
              'color_2' => 'black'
                      
              )
                  ),
              ); 
              Inwiefern hälst du das für nicht bzw. weniger flexibel? Denn das ist eine der Fragen, die mich an meiner Herangehensweise beschäftigen.
              Zuletzt geändert von Griecherus; 25.11.2006, 14:54.
              Nieder mit der Camel Case-Konvention

              Kommentar


              • #8
                joh, auch danke für deinen beitrag, hat mich nochmal zum nachdenken angeregt.
                Und da es - genau wie du ja gesagt hast - relativ kompliziert ist, das so abzuarbeiten, wie es die phplib Template-Engine und Konsorten tun,
                das meinte ich genau umgekehrt - dass es so einfacher bzw. intuitiver ist, als dein vorschlag
                aber jetzt denke ich, dass "deine" bzw. "meine" herangehensweise das selbe in grün ist, lediglich die komplexität wurde verschoben:

                du musst zuerst über mehrere schleifen das array aufbauen (das array liegt ja nicht so vor, sondert wird dynamisch aufgrund einer db-abfrage aufgebaut) und hast dann nur eine zuweisung für das template.

                bei "phplib Template-Engine und Konsorten " erfolgen dagegen die zuweisungen und das blockholen für das template über mehrere schleifen.

                das ist doch im grunde kein unterschied, oder wie siehst du das?

                Inwiefern hälst du das für nicht bzw. weniger flexibel?
                die aussage war quatsch, hatte ich nur noch so im hinterkopf aus den erfahrungen, die ich mit meinem template-system hatte.
                aber wie gesagt, beide varianten nehmen/schenken sich m.m. nach nichts.

                Kommentar


                • #9
                  Original geschrieben von 3DMax

                  aber jetzt denke ich, dass "deine" bzw. "meine" herangehensweise das selbe in grün ist, lediglich die komplexität wurde verschoben:

                  ...

                  das ist doch im grunde kein unterschied, oder wie siehst du das?
                  Ich denke da stimme ich dir zu, die Komplexität des Ganzen ist damit einfach nur an einer andere Stelle. Ich habe mich nur einfach gefragt, ob irgendwo ein mehr oder weniger grober Denkfehler steckt, da ich diese Herangehensweise so noch in keiner anderen Template-Engine gesehen habe. Ich werd's einfach mal ausprobieren.

                  Danke nochmal
                  Nieder mit der Camel Case-Konvention

                  Kommentar


                  • #10
                    Original geschrieben von Griecherus
                    Ich habe mich nur einfach gefragt, ob irgendwo ein mehr oder weniger grober Denkfehler steckt, da ich diese Herangehensweise so noch in keiner anderen Template-Engine gesehen habe.
                    vermutlich, weil's andersrum intuitiver/transparenter ist.
                    setCurrentBlock('cars') - jetzt weiß ich, aha, ich habe den block 'cars' aktiviert und alles, was ich jetzt zuweise, betrifft diesen block.
                    anstatt mit einem schwung ein schwerer nachvollziehbares array aufzubauen.

                    Kommentar


                    • #11
                      Da gebe ich dir auch recht, ja. Das einzige, was mich "stört", ist, dass Blöcke in diesem und vergleichbaren Template-Engines immer explizit geparst werden; also noch bevor alles andere geparst wird. Das finde ich persönlich nämlich weniger intuitiv. Ich würde stattdessen simple Platzhalter per $tmpl->set und Blöcke per $tmpl->set_block setzen, nur im Endeffekt alles zusammen parsen, ohne Blöcken dabei eine ganz spezielle Rolle zu geben. Das würde dann dem "Intuitiven", das du angesprochen hast, gerechter werden - zumindest meiner Meinung nach.
                      Nieder mit der Camel Case-Konvention

                      Kommentar


                      • #12
                        Original geschrieben von Griecherus
                        Das einzige, was mich "stört", ist, dass Blöcke in diesem und vergleichbaren Template-Engines immer explizit geparst werden;
                        ---
                        Ich würde stattdessen simple Platzhalter per $tmpl->set und Blöcke per $tmpl->set_block setzen,..., ohne Blöcken dabei eine ganz spezielle Rolle zu geben.
                        in deinem posting erkenne ich einen widerspruch:
                        du hast zwei methoden genannt, eine davon ist set_block(), aber du schreibst, dass du blöcke nicht explizit behandeln möchtest. warum also zwei methoden und nicht konsequenterweise eine "master-assign-methode"?

                        Kommentar


                        • #13
                          Das ist ein Kompromis gewesen, da dieses Argument durchaus einleuchtend ist:
                          Original geschrieben von 3DMax
                          jetzt weiß ich, aha, ich habe den block 'cars' aktiviert und alles, was ich jetzt zuweise, betrifft diesen block.
                          Ursprünglich ist nur eine Methode set gedacht gewesen.
                          Mir geht es halt nur darum, dass simple Platzhalter implizit geparst werden und ich das bei Blöcken nicht anders machen würde, gerade was eine intuitive Handhabung angeht. Oder was meinst du?
                          Nieder mit der Camel Case-Konvention

                          Kommentar


                          • #14
                            Original geschrieben von Griecherus
                            Oder was meinst du?
                            verzichte doch ganz auf methoden und greife direkt auf die public object-members zu.

                            ansonsten denke ich, dass der ansatz zu einer eierlegendenwollmilchsau-methode falsch ist.
                            ... aber du wirst das schon machen/optimieren
                            Zuletzt geändert von 3DMax; 26.11.2006, 01:09.

                            Kommentar


                            • #15
                              Danke nochmal für deine Hilfe.
                              Nieder mit der Camel Case-Konvention

                              Kommentar

                              Lädt...
                              X