Template Engine: Schleifeniterationen erkennen bzw. Auslassen nach Bedarf

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

  • Template Engine: Schleifeniterationen erkennen bzw. Auslassen nach Bedarf

    Hi,

    ich hoffe diese Community kann mir bei meinem Problem einen Tipp geben.

    Ich habe eine kleine Template Engine programmiert bei der mir noch eine kleine Idee fehlt und zwar wie ich einzelne Schleifen Iterationen erkenne die ausgelassen werden sollen.

    Einfaches Bsp. zur Veranschaulichung:
    Der erste Block A wird 20 mal wiederholt und dabei sollte nach jedem 2. A Block der Subblock A1 erscheinen

    Template:
    Code:
    <Block A>
    <table>
    <Block A.1>
    <tr>
    <td></td>
    </tr>
    <Block A.1>
    </table>
    </Block A>
    Anweisung
    PHP-Code:
    for ($i=0$i<20$i++)
      {
        
    $template->assign_block('A');
        if (
    $i%2==1)
          
    $template->assign_block('A.1');
      } 
    Die Problemmatik die sich hierbei stellt ist wie ich meine Template Engine erkennen lasse, ob der Subblock X geparst oder ausgelassen werden soll.

    Meine Template Eninge ermittelt zunächst alle gültigen Blöcke mit Hilfe eines rekursiven Pattern. Und legt diese in einem Array ab:

    Schema für dieses Beispiel:
    PHP-Code:
    $blocks['A']='<table>{INSERT BLOCK A.1}</table>';
    $blocks['A.1']='<tr><td></td></tr>'
    Wie man erkennen kann, liegt mein einziges Problem darin Schleifen Iterationen der Template Engine begrifflich zumachen und eine performance schonende Templatezusammenstellung zu generieren.

    Möglichkeiten wie die Rootblöcke in der Template File durch Template Blöcke Einfügemarken zuersetzen und dann wiederrum rekursiv zusammenzubauen fressen Performance....

    Ich hoffe ihr habt für mich ein paar Ideen die mich weiterbringen bzw. neue Gedankengänge offerieren...

    Vielen Dank vorab

  • #2
    Was passiert denn, wenn für den Block A.1 keine Daten vorhanden sind?
    Dann wird der Block doch wohl ignoriert, oder?
    Ich denke, also bin ich. - Einige sind trotzdem...

    Kommentar


    • #3
      Original geschrieben von mrhappiness
      Was passiert denn, wenn für den Block A.1 keine Daten vorhanden sind?
      Dann wird der Block doch wohl ignoriert, oder?
      Das mag sein, hilft mir aber nicht wirklich weiter......

      Denn wenn man davon ausgeht das in der Templatefile stets dieser Block vorhanden ist (nicht leer) und mithilfe einer Templateblockzuweisung nun die Templatengine ermitteln muss wann der Block übersprungen bzw. geparst werden soll.

      Tut sich mir die Höllenpforte auf...Ich hoffe du kannst mir folgen.....

      Im Grunde brauche ich nur eine Lösung bzw. Anregung wie ich die Situation User konform handle:

      1. Subblöcke die immer existieren
      2. Subblöcke die n mal in einer Schleife geparst werden können
      3. Subblöcke die in einer Schleife ausgelassen werden können
      4. Subblöcke die welche wenn sie ausgelassen wurde, irgendwie der Template Engine vermerkt werden, so dass die Reihenfolge bzw. das Auslassen/Parsen chronologisch beibehalten werden kann.

      Punkt 3 und 4 sind mein Problem weil ich mir hierfür keine Superidee
      ausmalen kann.

      Schönen Gruß und sorry fürs verspätete Posting war mir nicht früher möglich

      Kommentar


      • #4
        Möglicherweise denkst du zu kompliziert. Ein Block ist ein Block, auch wenn er in einem anderen Block steht. Sonst hast du automatisch ein Limitierung der Verschachtelungstiefe, was wohl keiner will.

        Deswegen gibt es eigentlich keine "Sublöcke"!


        (Was du genau machst, weiß ich nicht. Deshalb ist das nur ein Hinweis.)

        Kommentar


        • #5
          Original geschrieben von onemorenerd
          Möglicherweise denkst du zu kompliziert. Ein Block ist ein Block, auch wenn er in einem anderen Block steht.
          Ich habe bereits ein nested block Modell am start, was auch alle Blöcke ermittelt und entsprechend parst. Leidiges Problem ist eben n Block parsen und manchmal überspringen weils im Schleifendurchlauf nicht vorgesehen ist.

          Im Grunde einfach ausgedrückt Template Engine Schleifen Iterationen Handling ist bei mir mein Knackpunkt....

          Wenn ich hier Klarheit hätte wäre meine Engine 100% produktiv einsetzbar und ich bin in hoffnungsvoller Erwartung das einer von euch meine Schlafstörung beseitigen könnte....

          Kommentar


          • #6
            Gib uns doch mal ein praktisches Beispiel, also ein echtes Template mit Blöcken, von denen der innere nicht immer ausgegeben werden soll. Außerdem wäre natürlich interessant, wie deine TE das Template füllt.

            Das da oben ist jedenfalls kein gutes Beispiel, weil das Template völlig statisch ist und erst das if in der for-Schleife bestimmt, wann A.1 ausgegeben wird.

            Kommentar


            • #7
              Original geschrieben von onemorenerd
              Gib uns doch mal ein praktisches Beispiel, also ein echtes Template mit Blöcken, von denen der innere nicht immer ausgegeben werden soll. Außerdem wäre natürlich interessant, wie deine TE das Template füllt.

              Das da oben ist jedenfalls kein gutes Beispiel, weil das Template völlig statisch ist und erst das if in der for-Schleife bestimmt, wann A.1 ausgegeben wird.
              Also nunja obiges Beispiel beruht auf einer wahren Begebenheit.
              Wenn man sich z.B. ein Gästebuch vorstellt bei denen die Benutzer ihre eMail Adresse public anzeigen lassen können oder nicht kannst du die Situation vll. nachvollziehen.

              Code:
              <Block_gbeintrag>
              Name: $name
              Vorname: $vorname
              <Block_email>
              eMail: <a href="mailto:$email">$email</a>
              </Block_email>
              </Block_gbeintrag>
              Meiner Meinung nach habe Bedingungen in Templates nichts zu suchen und wie du jetzt sicherlich erkennst werden die GBeinträge u.A. zeilenweise aus der DB gelesen und je nachdem ob in der aktuellen SchleifeBlock_email gesetzt wurde soll dieser entweder angezeigt werden oder nicht.

              Soweit so gut...
              Im moment lasse ich einfach mal rekursiv das Template durchgehen und ermittele sämtliche Blöcke was ich dann in einer Art Array abbilde:

              $blocks['gbeintrag']='Name: $name Vorname: $vorname';
              $blocks['email']='eMail: <a href="mailto:$email">$email</a>';

              So und nun versuche ich die Schleife abzubilden auf mein Block Array aber genau hier hab ich nicht die ultimative Lösung gefunden....

              Hast du hierfür einen Vorschlag?

              Kommentar


              • #8
                Was denn für eine Schleife abbilden? Ich sehe keine, weder in den Daten, noch im Template ... weißt du, worauf ich hinaus möchte? Anderenfalls kannst du vielleicht die "reale Begebenheit" mal auf das Nötigste einkochen und komplett posten.

                Kommentar


                • #9
                  @onemorenerd verstehst du mich nun?

                  PHP-Code:
                  while ( $row=mysql_fetch_assoc($res) )
                    {
                       
                  $tpl->add_block'gbeintrag',array('vorname'=>$row['vorname'],
                                      
                  'name'=>$row['name']) );
                      if (
                  $row['show_email'])
                         
                  $tpl->add_block'email',array('email'=>$row['user _email']) );
                    } 

                  Kommentar


                  • #10
                    Ja, ich denke schon.
                    PHP-Code:
                    add_block($name$vals) {
                        
                    // in $blocks[$name] die Platzhalter gemäß $vals ersetzen
                        // und das dann der Ausgabe anhängen
                        
                    $this->output .= replace($this->blocks[$name], $vals);

                    Dein Problem ist nun, dass du beim Parsen des Templates die Verschachtelung verlierst:

                    $blocks['gbeintrag']='Name: $name Vorname: $vorname';
                    $blocks['email']='eMail: <a href="mailto:$email">$email</a>';

                    statt, wie es im Template steht

                    $blocks['gbeintrag']="Name: $name Vorname: $vorname $blocks['email']";
                    $blocks['email']='eMail: <a href="mailto:$email">$email</a>';

                    Das mußt du nun nicht so umbauen, soll nur der Veranschaulichung dienen. Du mußt die Verschachtelung irgendwie erhalten, sonst könnte das Beispieltemplate nämlich auch so gefüllt werden:

                    PHP-Code:
                    while ($row mysql_fetch_assoc($res)) {
                        
                    $tpl->add_block('email', array(...));

                    Obwohl der Templatedesigner erreichen wollte, dass ein Block 'email' überhaupt nur innerhalb eines Blocks 'bgeintrag' existieren kann, würde diese Schleife ein $tpl->output erzeugen, dass allein aus lauter 'email'-Blöcken besteht.

                    Hoffentlich konnte ich das Problem deutlich machen. (M)Eine Lösung wäre sowas in der Art:

                    $blocks['gbeintrag'] = "Name: $name Vorname: $vorname {$blocks['gbeintrag']['email']}";
                    $blocks['gbeintrag']['email'] = 'eMail: <a href="mailto:$email">$email</a>';
                    Zuletzt geändert von onemorenerd; 01.02.2006, 01:07.

                    Kommentar


                    • #11
                      Soweit bin ich eigentlich auch hab leider vergessen das kenntlich zu machen, da ich nicht vor meinem Livecode bin...

                      so hab ich es eigentlich:
                      PHP-Code:
                      $blocks['gbeintrag']="Name: $name Vorname: $vorname <!-- include subblock_email -->";
                      $blocks['email']='eMail: <a href="mailto:$email">$email</a>'
                      Das Problem ist der Schleifendurchlauf zu merken, d.h. wurde der email Block beim Hinzufügen des Blockes gbeintrag hinzugefügt ja/nein

                      Weil ich muss der Template Engine ja irgendwie sagen das Blockdurchgang X keinen email Block hatte, aber der Blockdurchgang Y schon.....Und anhand dieser Informationen schließlich das Blockkonstrukt wieder zusammensetzen. Dabei aber verhindern das so etwas zustande kommt:

                      gbeintrag
                      email
                      email
                      gbeintrag

                      ich hoffe ich habe das Problem auf den Nenner gebracht

                      Kommentar


                      • #12
                        Vergleiche mal deins
                        PHP-Code:
                        $blocks['gbeintrag'] = "Name: $name Vorname: $vorname <!-- include subblock_email -->";
                        $blocks['email'] = 'eMail: <a href="mailto:$email">$email</a>'
                        und meins
                        PHP-Code:
                        $blocks['gbeintrag'][0] = "Name: $name Vorname: $vorname {$blocks['gbeintrag']['email']}";
                        $blocks['gbeintrag']['email'] = 'eMail: <a href="mailto:$email">$email</a>'
                        Bei mir spiegelt die Arraystruktur die Blockverschachtelung wieder, so dass man mit einer rekursiven Funktion niemals email-Blöcke ohne umgebenden gbeintrag-Block ausgeben kann.
                        Das löst eines deiner Probleme.

                        Das zweite, nämlich wann email-Block und wann nicht, ist eigentlich keines. Denn sie dir mal den Code von weiter oben an:
                        PHP-Code:
                        while ($row mysql_fetch_assoc($res)) {
                            
                        $tpl->add_block('gbeintrag', array('vorname' => $row['vorname'],
                                            
                        'name' => $row['name']));
                            if (
                        $row['show_email'])
                               
                        $tpl->add_block('email', array('email' => $row['user _email']));

                        Stelle dir dazu folgende Daten vor:
                        Code:
                        Vorname, Name, eMail
                        Hans, Meier, foo
                        Karl, Otto, NULL
                        Inge, Müller, bar
                        Die Ausgabe sieht so aus:
                        Code:
                        Name: Meier Vorname: Hans eMail: <a href="mailto:foo">$email</a>
                        Name: Otto Vorname: Karl 
                        Name: Müller Vorname: Inge eMail: <a href="mailto:$email">bar</a>
                        Hinter Karl Otto steht eigentlich noch {$blocks['gbeintrag']['email']}, denn es wurde nicht durch einen email-Block ersetzt. Aber die output-Methode entfernt natürlich alle unersetzen Platzhalter aus dem Template.

                        Falls du nun immernoch ein Problem siehst, wo keins ist, dann nimm mal eine Template Engine auseinander und schau, wie die es macht.

                        Kommentar


                        • #13
                          Ich denke wohl immer noch zu kompliziert oder wir verstehen uns nicht richtig.....

                          ich registriere also mit
                          $tpl->add_block(); sämtliche Blöcke, so dass ich u.A. ein Array in der Form:

                          PHP-Code:
                          $blocks[$blockname][$blockanzahl
                          erhalte....

                          Stellen wir uns nun vor ich lasse den gbeintrag Block 6 mal durchlaufen und überspringe bei jedem zweiten gbeintrag den email block

                          gbeintrag:
                          1 emailblock
                          2
                          3 emailblock
                          4
                          5 emailblock
                          6

                          Man sieht das Problem. die Engine merkt sich
                          $blocks['email'][1]
                          $blocks['email'][2]
                          $blocks['email'][3]

                          und
                          $blocks['gbeintrag'][1]
                          $blocks['gbeintrag'][2]
                          $blocks['gbeintrag'][3]
                          $blocks['gbeintrag'][4]
                          $blocks['gbeintrag'][5]
                          $blocks['gbeintrag'][6]

                          Das stellt mich vor der Frage wie ich am besten die Blöcke sich registrieren lasse ohne dabei die Information zu verlieren in welchem Schleifendurchlauf der Block geparst werden soll und wann nicht.....

                          Danke dir für deine Mühe

                          Kommentar


                          • #14
                            Deine Engine soll sich die Blöcke so "merken"

                            $blocks['gbeintrag'][1]['_content'] = Inhalt
                            $blocks['gbeintrag'][1]['email'] = Mailadresse

                            $blocks['gbeintrag'][2]['_content'] = Inhalt

                            $blocks['gbeintrag'][3]['_content'] = Inhalt
                            $blocks['gbeintrag'][3]['email'] = Mailadresse

                            $blocks['gbeintrag'][4]['_content'] = Inhalt

                            $blocks['gbeintrag'][5]['_content'] = Inhalt
                            $blocks['gbeintrag'][5]['email'] = Mailadresse

                            $blocks['gbeintrag'][6]['_content'] = Inhalt
                            Ich denke, also bin ich. - Einige sind trotzdem...

                            Kommentar

                            Lädt...
                            X