Template-System und [if x==y]...[/if]

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

  • Template-System und [if x==y]...[/if]

    Hallo liebe PHP-Community

    Vor längerer Zeit habe ich mit Hilfe von einigen Usern von hier mir eine kleine Templateklasse gebaut.
    Diese funktioniert auch 1a.

    Doch nun möchte / muss ich einen Schritt weiter gehen.

    Aber bevor ich dazu komme hier erstmal kurz das, was meine Klasse schon kann:
    • einfaches ersetzen von {VARIABLEN}
    • Blöcke (Bereiche die sich wiederholen)
    Aber nun möchte ich in den Template-Dateien quasi noch soetwas einbauen:
    PHP-Code:
    [if {VAR} == 1
    ....
    [/if] 
    Nun stelle ich mir das wie folgt vor:

    1. Ich lese die gesamte Template-Datei ein
    2. Ich ersetze alle {VARS} komplett
    3. Ich überprüfe wo eben diese Ausdrücke stimmen oder nicht
    4. Ich parse die Bereiche, die angezeigt werden, wo also quasi diese if-Anweisungen wahr sind

    Was mir fehlt ist nun quasi der Ansatz, wie man ein regex oder eine Funktion schreibt,
    die quasi die Template-Datei nach den eckigen Klammern durchsucht
    [] und den Teil der dazwischen steht, wie zum Beispiel:

    1==1

    zerlegt.

    Nach der Zerlegung müsste quasi syntaktisch folgendes Ergebnis vorliegen:

    ausdruck1 operator ausdruck2

    Das Problem wäre aber dann wieder, dass es ja auch solche Konstruktionen geben soll:

    PHP-Code:
    [if 1==1]
    ....
    [else]
    ....
    [/if] 
    Nun müsste die Funktion überprüfen, ob die if-Anweisung wahr ist
    oder nicht und je nachdem entweder das was zwischen den if-Tags
    steht parsen und die Tags löschen, da sie sonst angezeigt werden,
    oder alles löschen was mit dem if-Tag zusammenhängt.

    Hat jemand von euch eine Idee, wie ich eine solche Funktion realisieren kann?
    Leider komm ich mit der ganzen regex und preg_* Sache nicht so zurecht und versuche nun schon lange soetwas zu realisieren.
    Ich habe auch keine verwendbaren Tutorials oder andere Threads gefunden

    Ich hoffe das ihr meine Ausführungen versteht und mir helfen könnt.

    Mit freundlichen Grüßen Sodan

  • #2
    Hallo,

    Ich empfehle dir zu erlauben dass man PHP code in dein template einbaut, hab ich nach vielem Hickhack so gemacht und hat sich bewährt; musst du aber wissen, wie auch immer. Das mit dem [if] würd ich mit preg_replace und dem /e modifier (funktion aufrufen) lösen. Bsp:

    PHP-Code:
    $StringAusTemplate preg_replace("/\[if ([^\]]+)\](.+)\[\/if\]/isUe""tmpl_parse_if('\\1', '\\2')"$StringAusTemplate);

    tmpl_parse_if($condition$todo)
    {
        
    $condition preg_replace("/\{([^\}]+)\}/""\$\\1"$condition); // {Var} ersetzen
        
    $todo preg_replace("/\[else\]/i""} else {"$todo); // else ersetzen
        
    $evaluate "if(".$condition.") {\n".$todo."\n}";
        eval(
    $evaluate);

    Ist noch nicht perfekt ausgereift, aber vielleicht kommt das prinzip rüber, ansonsten: Fragen!

    Kommentar


    • #3
      PS: Da wo \1 und \2 steht gehört natürlich \\1 und \\2 hin, das macht der parser. Quote mich für richtigen Code

      Kommentar


      • #4
        danke für die schnelle antwort.
        an sich habe ich nichts gegen php-code im template.

        mal sehen wie sich das macht

        mfg Sodan

        Kommentar


        • #5
          Templates sind doch gerade dafür da, dass man KEINEN PHP-Code dort benutzen muss ..... Trennung von Logik und Präsentation ...


          Für das IF-Statement würde ich alle erlaubten Zeichen etc. in eine Regex packen, das ganze per | trennen und dann durch die Matches durchloopen und schauen ob es "syntaxgemäß" ist

          z.B.:

          !|==|<|>| etc. etc.
          Für alle die Fehler suchen, gibts gratis tolle Debuggingmöglichkeiten:
          var_dump(), print_r(), debug_backtrace und echo.
          Außerdem gibt es für unsere Neueinsteiger ein hervorragendes PHP Tutorial zu PHP 4 und PHP 5 (OOP)
          Es heißt $array['index'] und nicht $array[index]! Und nein, das ist nicht egal!
          Dieses Thema lesen, um Ärger im Forum und verzögerte Hilfen zu vermeiden.

          Kommentar


          • #6
            1. muss ich Shurakai da recht geben
            2. hat der Vorschlag von Luke leider nicht funktioniert.

            Kennt jemand von euch einen guten php-regex guide?
            Alle die ich bis jetzt gefunden hab sind schwer verständlich, zudem scheinen sich die Regex-Syntaxen der unterschiedlichen Programmiersprachen auch noch zu unterscheiden :/

            Ich wäre auch für weitere Ideen zum Thema dankbar.

            MfG Sodan

            Kommentar


            • #7
              Hi,

              ja es gibt regex-dialekte, die meistens ihre wurzeln(und auch namensteile) in den tools haben die sie als erstes verwendeten. Ich halte mich seit eh und je an PCRE (perl compatible regular expression). Das bedeutet in php die preg_-familie.

              Generell würde ich an so eine template engine nicht mit puren regex rangehen. Verschachtelte strukturen lassen sich so nicht erfassen. Hier würde ich hingehen und die regex als unterstützendes mittel für einen template-parser nutzen, der ansonsten die im parserbau üblichen methoden benutzt. Hier kann man dann leicht noch an verschiedene backends denken um evtl. caching dazwischen zu schalten und dann verschieden writer um die gecachten daten an unterschiedlichen orten speichern zu können.

              greets
              (((call/cc call/cc) (lambda (x) x)) "Scheme just rocks! and Ruby is magic!")

              Kommentar


              • #8
                Original geschrieben von Sodan
                Kennt jemand von euch einen guten php-regex guide?
                Ich hab grad n tutorial geschrieben... ist noch nicht ganz fertig, aber kannst mir ja mal sagen was du davon hälst (wenn du willst). Für Fragen stehe ich natürlich bereit

                http://www.phpbar.de/w/Regul%C3%A4re_Ausdr%C3%BCcke
                http://www.phpbar.de/w/Regul%C3%A4re...3%BCcke/Teil_1 (Tutorial)

                Kommentar


                • #9
                  > 2. hat der Vorschlag von Luke leider nicht funktioniert.

                  Mit was für nem Code hast du's eigentlich gestestet?

                  Kommentar


                  • #10
                    Also ich habe das in meiner Template Klasse so gelöst:

                    TPL-Tags sehen so aus(Bsp.):
                    [COLOR=crimson]{if "{var}" == "TRUE"}
                    ist wahr!
                    {elseif "{var}" == "FALSE"}
                    ist falsch!
                    {else}
                    keine Angabe
                    {/if}[/COLOR]

                    Dann filtert man mit RegEx preg_match_all() alle if Blöcke raus und geht sie in einer foreach-schleife durch.
                    Die if's und elseif's etc. ersetzt du durch gängigen PHP-Code und schickst ihn an eval() ummantelt mit OutPut Control.
                    Per ob_get_contents() oder wie das heisst, kannst du dann den fertigen Code der Kontrollstruktur zum Ersetzen des If-Blocks nutzen.

                    Funktioniert bei mir durchaus gut

                    Kommentar


                    • #11
                      hab auch an der template klasse "mitgeschrieben" (und danach stark erweitert...) - inzwischen wäre es für mein projekt auch sinnvoll wenn es sowas wie if gäbe - allerdings bin ich ganz stark gegen php-code im template und auch gegen irgendwelche eval konstrukte - angesichts der tatsache das ich die template klasse gerne noch auch parsing umstellen möchte fände ich es gut wenn die lösung keine regulären ausdrücke benutz da das eine template klasse stark verlangsamt - für die vorgehensweise:

                      - "[if " suchen
                      - inhalt danach extrahieren
                      - zweite varible extrahieren
                      - suchen nach boolschen operatoren (filtern z.b. mit switch)
                      - je nach fall einzelne behandlung z.b. mit php
                      - suchen nach "[/if]" oder "[else]" - weiter mit dem inhalt verfahren
                      Die Regeln | rtfm | register_globals | strings | SQL-Injections | [COLOR=silver][[/COLOR][COLOR=royalblue]–[/COLOR][COLOR=silver]][/COLOR]

                      Kommentar


                      • #12
                        Ich frage mich gerade, wie man soetwas ohne regex machen soll?
                        Geht das überhaupt? Nicht das ich gegen andere Varianten wäre, aber ich kann mir das bloß gerade nicht vorstellen

                        Mich würde des Weiteren interessieren, wie du die Template-Klasse erweitert hast

                        MfG Sodan

                        Kommentar


                        • #13
                          Ich frage mich gerade, wie man soetwas ohne regex machen soll? Geht das überhaupt? Nicht das ich gegen andere Varianten wäre, aber ich kann mir das bloß gerade nicht vorstellen
                          natürlich geht das - du musst die ganze datei "parsen" also von vorne bis hinten durch gehen (Ansätze: substr(), strstr() ) wenn du eine klammer findest suchst du nach der nächsten klammer und extrahierst den teil dazischen - all sowas ist möglich

                          die template klasse hab ich um eine verbesserte marker ersetzung (entfernen von blöcken inclusive inhalt), einen ansatz für default werte ({blubb|default="test"}), und eine verbesserte ersetzung von böcken (inklusive __count__ etc für rekursive blöcke) - allerdings alles mit regulären ausdrücken - was mir erlich gesagt gar nicht gut gefällt - das parsen würde ich so aufbauen das es einfach erweiterbar ist, so das man dann default aber auch strtoupper etc einfach einbauen kann wenn man es braucht - allerdings sollte das ganze dabei möglichst schnell bleiben - smarty ist nähmlich verdamt langsam ....

                          ich werde mich jetzt mal mit dem parsen von templates (und anderem beschäftigen) was ich auch überlege ob man den parse vorgang irgendwie so aufbauen kann das man damit auch z.b. bbcode parsen kann.... nur so ein paar ideen - man könnte eine allgemeine parse klasse schreiben und das fürs template dann noch mehr anpassen - die andere sache ist - ich wollte mir mal das paket pear::cache_lite angucken um evtl ein cache lösung einzubauen - mal sehen

                          mfg tontechniker
                          Die Regeln | rtfm | register_globals | strings | SQL-Injections | [COLOR=silver][[/COLOR][COLOR=royalblue]–[/COLOR][COLOR=silver]][/COLOR]

                          Kommentar


                          • #14
                            Hallo miteinander,

                            ich habe mir auch meine eigene Templateklasse geschrieben, und dass Problem mit IFs auf andere Weise gelöst.

                            Wenn es um einzelne Werte geht, findet die Prüfung im PHP-Script (das das Template aufruft) statt und der Wert wird als Variable ans Template übergeben. Wenn es sich um länge Seitenteile handelt werden diese in einen Block/Schleife gepackt - ebenso wie alternative Seitenteile. In PHP entscheide ich dann, welcher Block angezeigt werden soll. Meine Klasse entfernt zum Schluss alle Vars / Blöcke für die keine Werte übergeben wurden.

                            Beispiel:
                            PHP-Code:
                            <!--Begin alternative1--> hier folgt HTML ... <!--End alternative1-->
                            <!--
                            Begin alternative2--> hier folgt anderes  ... <!--End alternative2-->
                            <!--
                            Begin alternative3--> hier folgt ganz was anderes  ... <!--End alternative3--> 
                            Wenn ich jetzt nur alternative2 registriere - sprich Daten oder ein leeres Array übergebe - werden die beiden anderen Varianten automatisch gelöscht. Damit erübrigt sich eine separate Lösung üfr IFs.

                            Kommentar


                            • #15
                              Ihne euch jetzt den Spaß an einer eigenen Template Engine nehmen zu wollen:

                              http://templatelite.sourceforge.net/


                              Vielleicht könnt ihr zumindest da ein paar Ideen rausholen.

                              Kommentar

                              Lädt...
                              X