Ankündigung

Einklappen
Keine Ankündigung bisher.

MVC und Templates

Einklappen

Neue Werbung 2019

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

  • MVC und Templates

    Hallo leute,

    ich hatte bisher immer vermieden in meinen Projekten eine Template Engine zu Benutzen. Aus vielen Beiträgen aus dem Forum sah ich dass viele es doch einsetzen. Nun dachte ich mir, es kann ja nicht schlecht sein, wenn selbst nikosch auf twig schwört

    Jedoch erscheinen mir einige Dinge etwas unklar in verbindung von (H)MVC und Templates.

    Ich habe mir 3 Templates engines angeschaut, Smarty,Twig,Mustache.

    Alle haben eine Gemeinsamkeit in der doku:

    PHP-Code:
    //Smarty
    $smarty = new Smarty();
    $smarty->assign('foo','bar');
    $smarty->display('foobar.tpl');

    //twig
    $twig = new Twig_Environment($loader);
    $twig->render('foobar.html',array('foo'=>'bar'));

    //mustache
    $mustache = new Mustache_Engine();
    $mustage->render('foobar.mustache',array('foo'=>'bar')); 
    soweit so gut.

    Soweit ich es verstanden habe, sieht das MVC konzept vor dass Controller Daten aus dem Model liest, diese an das View übergibt und das View macht dann irgendwas damit, zb rendern.

    Also wäre es doch die Aufgabe des Views ein Renderer zu instanzieren und die erhaltenen Daten vom Controller an den Renderer zu übergeben.

    Soweit auch alles kein Problem. Der Controller bzw Action, bestimmt welches View/Model verwendet werden soll , tauscht daten zwischen Model und View aus und View tauscht daten mit renderer aus und der Renderer zeigt diese an.

    Nun gibt es aber besonderheiten in den Template engines, sowas wie Block inheritance oder Partials.
    d.h. also dass der Controller keine Kontrolle mehr über das Template hat. Das Template kann von sich aus bestimmen was noch zusätzlich angezeigt werden soll.

    Also qausi das was ich vorher mit "Subviews" im Controller erledigt habe, übernimmt das Template. Nun ist die Frage wie man sowas hand haben sollte.

    So wie ich es sehe, dient es dazu, eine komplette ansicht dann zu cachen(header,content,footer).
    Der Richtige weg wäre also ein einziges View Objekt im Front Controller zu initialisieren und dieses View Objekt mit daten aus anderen Controllern zu füttern und in nach verarbeitung der Action das View rendern.

    Das Problem ist, dass ich dann vom Controller aus nicht wirklich steuern könnte welche blocks gerade angezeigt werden sollten bzw ausgeblendet werden sollen. Auch müsste ich jedes mal das View mit weiteren daten füttern wenn der Designer mehr dinge agezeigt haben will.

    Vielleicht kann mir ja hier jemand ein denkanstoß geben wie man am besten MVC mit Template Engine kombinieren kann. Vielleicht kann ja jemand aus seinen erfahrungen berichten.

    Ich hatte es bisher immer so gemacht, dass ich im Front Controller ein template View erzeugt habe(header,footer,content) und statt partials, habe ich einfach ein Layout view erzeugt, das Layout konnte im Controller verändert werden. Angenommen für die Startseite brauchte ich einspalten layout, nach dem einloggen zweispalten Layout, bei errorpages wieder einspalten layout.

    Wenn ich ein Ajax Controller aufgerufen habe, habe ich das template View deaktiviert damit beim Response header und footer nicht mitgesendet werden. bei JSON response habe ich dann ohne Layout gearbeitet.

    Ich konnte halt alles direkt über Actions steuern.

    Hoffe jemand hier kann mir ein paar nette links dazu posten

    Viele Grüße,

    BlackScorp
    apt-get install npm -> npm install -g bower -> bower install <package> YOLO [URL]https://www.paypal.me/BlackScorp[/URL] | Mein Youtube PHP Kanal: [url]https://www.youtube.com/c/VitalijMik[/url]

  • #2
    Zitat von BlackScorp Beitrag anzeigen
    Nun gibt es aber besonderheiten in den Template engines, sowas wie Block inheritance oder Partials.
    d.h. also dass der Controller keine Kontrolle mehr über das Template hat. Das Template kann von sich aus bestimmen was noch zusätzlich angezeigt werden soll.
    Soll der Controller ja auch nich, ist nicht seine Aufgabe. Der Controller holt Daten aus dem Model und gibt sie an die View weiter. Welche Daten das sind, soll ihn garnicht interessieren, er muss nur wissen, wie er an sie rankommt.

    Zitat von BlackScorp Beitrag anzeigen
    Das Problem ist, dass ich dann vom Controller aus nicht wirklich steuern könnte welche blocks gerade angezeigt werden sollten bzw ausgeblendet werden sollen. Auch müsste ich jedes mal das View mit weiteren daten füttern wenn der Designer mehr dinge agezeigt haben will.
    Der Controller sollte sowieso garnicht filtern, wenn Designer und Coder tatsächlich unterschiedliche Instanzen sind. Die View entscheidet, was der Benutzer gerade zu sehen bekommt.

    Der Controller ist nur ein Mittelsmann zwischen View und Model, der weiß, wie man mit dem Model spricht und wie die Daten an die View kommen.
    [URL="http://goo.gl/6Biyf"]Lerne Grundlagen[/URL] | [URL="http://sscce.org/"]Schreibe gute Beispiele[/URL] | [URL="http://goo.gl/f2jR7"]PDO > mysqli > mysql[/URL] | [URL="http://goo.gl/jvfSZ"]Versuch nicht, das Rad neu zu erfinden[/URL] | [URL="http://goo.gl/T2PU5"]Warum $foo[bar] böse ist[/URL] | [URL="http://goo.gl/rrfzO"]SQL Injections[/URL] | [URL="http://goo.gl/Q81WJ"]Hashes sind keine Verschlüsselungen![/URL] | [URL="http://goo.gl/2x0e2"]Dein E-Mail Regex ist falsch[/URL]

    Kommentar


    • #3
      Die View entscheidet, was der Benutzer gerade zu sehen bekommt.

      Der Controller ist nur ein Mittelsmann zwischen View und Model, der weiß, wie man mit dem Model spricht und wie die Daten an die View kommen.
      seh ich nicht so.

      Die View ist ja nur die Darstellung. Warum sollte sie wissen was sie darzustellen hat ?

      Der Controller kontrolliert, deswegen heißt er ja auch so.

      Er weiß welche Daten vom Model angefordert werden
      und auf welcher "Seite" welche View geladen wird und welche
      Subviews dort dargstellt werden.

      Wär ja auch gaga: eine View die möglicherweise gar nicht erst geladen wird
      soll entscheiden was der Benutzer zu sehen kriegt ??

      Der Controller sollte sowieso garnicht filtern, wenn Designer und Coder tatsächlich unterschiedliche Instanzen sind.
      Wieso ? Der Designer entscheidet dann auch ob eine "Login"-Box überhaupt angezeigt wird ??
      Eine if-else-Abfrage nimmt, ordentlich geschrieben eine Menge Platz weg. Platzsparend geht es mit einem ternären Operator.

      Kommentar


      • #4
        naja die idee ist, dem designer zu sagen in der Doku stehen dir verfügbaren Variablen und welchen Typ die haben, string,array er kann dann diese variablen im Template platzieren.

        Nun kommt aber eben die Login Box. eigentlich ist es aus meiner sicht ein Subview, aber aus der sicht der Template engine ist es ein Block bzw partial

        aus meiner sicht aus, müsste ich also erstmal die login box rendern und das resultat(HTML Code) and das layout view übergeben.

        aber ich bin mir dann nicht sicher was der renderer dann cached und ob es sich genauso verhalten würde wenn ich im template ein inlcude mache
        apt-get install npm -> npm install -g bower -> bower install <package> YOLO [URL]https://www.paypal.me/BlackScorp[/URL] | Mein Youtube PHP Kanal: [url]https://www.youtube.com/c/VitalijMik[/url]

        Kommentar


        • #5
          die idee ist, dem designer zu sagen in der Doku stehen dir verfügbaren Variablen und welchen Typ die haben, string,array er kann dann diese variablen im Template platzieren.
          ja, klar

          Nun kommt aber eben die Login Box. eigentlich ist es aus meiner sicht ein Subview, aber aus der sicht der Template engine ist es ein Block bzw partial
          Block/Partial/Subview meint doch alles das Gleiche.

          Du gibst dem Designer doch ein array damit er darüber ggf. iterieren kann (foreach oder Ähnliches).

          Bei der Loginbox kommt dann eben noch ein if dazu.

          Wenn eingeloggt-> logout usw. anzeigen, wenn nicht->login.

          Der Designer brauch also nur diese if-Abfrage ins Template schreiben
          und dann je nach Ergebnis html einzubauen und per CSS zu stylen.

          Oder Du gibst ihm gleich den html-Code vor mit ids, damit er stylen kann.

          Zum Caching:
          hab da noch nie Probleme gehabt, da ich den Zustand "eingeloggt" in der Session
          speichre und je nach Login-Zustand die richtige Seite ausgeliefert wird.
          Würd ich einfach mal ausprobieren.
          Eine if-else-Abfrage nimmt, ordentlich geschrieben eine Menge Platz weg. Platzsparend geht es mit einem ternären Operator.

          Kommentar


          • #6
            also sollte ich bei solchen späßen wie login einfach eine eigenschaft is_loggedin oder so auf true bzw false setzen, und der designer bestimmt dann in seinem partial/block/subview ob und was für ein html code angezeigt werden soll.

            also gibt es im grunde nur ein einziges view im front controller..
            apt-get install npm -> npm install -g bower -> bower install <package> YOLO [URL]https://www.paypal.me/BlackScorp[/URL] | Mein Youtube PHP Kanal: [url]https://www.youtube.com/c/VitalijMik[/url]

            Kommentar


            • #7
              Zitat von Koala Beitrag anzeigen
              Bei der Loginbox kommt dann eben noch ein if dazu.

              Wenn eingeloggt-> logout usw. anzeigen, wenn nicht->login.

              Der Designer brauch also nur diese if-Abfrage ins Template schreiben
              und dann je nach Ergebnis html einzubauen und per CSS zu stylen.
              Davon halte ich nichts. Der Controller bzw. eine dafür zuständiger Service sollte entscheiden, wie die Login-Box aussieht. Sprich, ob ein Formular zum Anmelden oder der bereits angemeldete Zustand ausgegeben werden soll. Für den Designer stellt sich nur die Frage, an welcher Stelle die Login-Box platziert werden soll. Für den Designer ergeben sich auch keine Nachteile, denn die jeweiligen Zustände der Login-Box können in separaten Template-Dateien angepasst werden.


              @ BlackScorp

              Vom Controller aus musst du nicht unbedingt steuern können, welche Blocks an welcher Stelle angezeigt werden. Es ist ausreichend, wenn ein Template angegeben wird. Dieses wiederum inkludiert ein Layout (mit bspw. Header und Footer) und definiert die Blocks.

              Sofern der Designer in Puncto Daten nicht eingeschränkt werden soll, kann auch überlegt werden, einen modifizierten Service Locator im Template bereitzustellen. Gerade bei Navigationen stelle ich gerne einen NavigationService zur Verfügung. Die Übergabe der konkreten Navigationen in den Controllern führt meiner Meinung nach zu mehr Redundanzen.

              Kommentar


              • #8
                also gibt es im grunde nur ein einziges view im front controller..
                ja, nur eine einzige Ansicht.

                Könntest natürlich der View einen Parameter mitgeben,
                der angibt welches Template bzw. Style geladen werden soll
                (kennst "Styleswitcher" ?).

                So stell ich mir das jedenfalls bei MVC vor.

                Bei HMVC hast ja dann ineinander verschachtelte MVC-Komponenten,
                aber dazu kann Dir Doc mehr sagen.
                Eine if-else-Abfrage nimmt, ordentlich geschrieben eine Menge Platz weg. Platzsparend geht es mit einem ternären Operator.

                Kommentar


                • #9
                  Vorweg:

                  Zitat von Koala Beitrag anzeigen
                  Der Controller kontrolliert, deswegen heißt er ja auch so.
                  Engl. to control heißt steuern, nicht kontrollieren! Und ja, das ist ein Unterschied!

                  ----

                  Weiterhin: Der Controller soll gerade eben nicht entscheiden, wie die Loginbox aussieht - Aussehen ist View-Sache. Der Controller sagt nur: "Du bist nicht eingeloggt, ich leite dich auf login.php weiter". Der dafür zuständige Controller sagt dann "Du bist nicht eingeloggt, also zeig ich dir [login.tpl] mit den Daten [loggedIn = false]". Wie das Formular dann aussieht, ist dem Controller in dem Moment pieps.

                  Wenn er dann das Formular erhält mit den Logindaten, validiert er diese. Wenn der Designer vergisst, alle nötigen Formulardaten einzubauen, gehts halt einfach schief.
                  [URL="http://goo.gl/6Biyf"]Lerne Grundlagen[/URL] | [URL="http://sscce.org/"]Schreibe gute Beispiele[/URL] | [URL="http://goo.gl/f2jR7"]PDO > mysqli > mysql[/URL] | [URL="http://goo.gl/jvfSZ"]Versuch nicht, das Rad neu zu erfinden[/URL] | [URL="http://goo.gl/T2PU5"]Warum $foo[bar] böse ist[/URL] | [URL="http://goo.gl/rrfzO"]SQL Injections[/URL] | [URL="http://goo.gl/Q81WJ"]Hashes sind keine Verschlüsselungen![/URL] | [URL="http://goo.gl/2x0e2"]Dein E-Mail Regex ist falsch[/URL]

                  Kommentar


                  • #10
                    Davon halte ich nichts. Der Controller bzw. eine dafür zuständiger Service sollte entscheiden, wie die Login-Box aussieht. Sprich, ob ein Formular zum Anmelden oder der bereits angemeldete Zustand ausgegeben werden soll. Für den Designer stellt sich nur die Frage, an welcher Stelle die Login-Box platziert werden soll. Für den Designer ergeben sich auch keine Nachteile, denn die jeweiligen Zustände der Login-Box können in separaten Template-Dateien angepasst werden.
                    ?? wir sind uns doch einig. Der Controller übergibt der View den Parameter "loggedin".
                    Und je nachdem wird dann die ein oder andere Box angezeigt.
                    Eine if-else-Abfrage nimmt, ordentlich geschrieben eine Menge Platz weg. Platzsparend geht es mit einem ternären Operator.

                    Kommentar


                    • #11
                      Engl. to control heißt steuern, nicht kontrollieren! Und ja, das ist ein Unterschied!
                      wo du Recht hast, hast Du Recht.

                      Trotzdem steuert bei Dir die View was sie darstellen will.

                      Du packst mehr als reine Designlogik in die View.

                      Oder seh ich das falsch ?

                      Die View entscheidet, was der Benutzer gerade zu sehen bekommt.
                      Der dafür zuständige Controller sagt dann "Du bist nicht eingeloggt, also zeig ich ihm [loginView]".
                      sind für mich Widersprüche.

                      Aber vermutlich meinen wir dasselbe.
                      Eine if-else-Abfrage nimmt, ordentlich geschrieben eine Menge Platz weg. Platzsparend geht es mit einem ternären Operator.

                      Kommentar


                      • #12
                        Zitat von ApoY2k Beitrag anzeigen
                        Weiterhin: Der Controller soll gerade eben nicht entscheiden, wie die Loginbox aussieht - [...] Der dafür zuständige Controller sagt dann "Du bist nicht eingeloggt, also zeig ich dir [login.tpl] mit den Daten [loggedIn = false]".
                        Das klingt ganz nach einer Entscheidung des Controllers. Entscheide dich für eine Variante

                        Kommentar


                        • #13
                          Zitat von Koala Beitrag anzeigen
                          Bei HMVC hast ja dann ineinander verschachtelte MVC-Komponenten,
                          desswegen bin ich zz etwas verwirrt, vorher habe ich dann einfach in einer action ein "subrequest" ausgeführt, das Reponse davon war entweder html code oder json die antworten der subrequests haben dann mein View im Initial request erweitert und zum schluss wurde das gesamt view gerendert.

                          so hatte ich zb die möglichkeit ein subcontroller forms mit login action erzeugen, im view sagte ich einfach

                          <?= $login_form ?> mein subrequest bestimmte dann selber ob da jetzt ein formular angezeigt wird oder nichts. so stand zb in einem 2 spalten layout folgendes drin
                          <?= $login_form ?>
                          <?= $profile_navigation ?>

                          der subcontroller der profile navigation hat dann auch die navigation automatisch aktiviert.

                          wenn ich das mit templates mache, müsste ich das view immer mehr erweitern so dass es dann plötzlich 1000e variablen hat und anhand der variablen werden bestimmte blöcke angezeigt mit bestimmten variablen usw

                          bei einem einzigen view muss man alles komplett umdenken
                          apt-get install npm -> npm install -g bower -> bower install <package> YOLO [URL]https://www.paypal.me/BlackScorp[/URL] | Mein Youtube PHP Kanal: [url]https://www.youtube.com/c/VitalijMik[/url]

                          Kommentar


                          • #14
                            Zitat von Trainmaster Beitrag anzeigen
                            Das klingt ganz nach einer Entscheidung des Controllers. Entscheide dich für eine Variante
                            Na der Controller entscheidet, "User nicht eingeloggt -> Umleitung auf /login". Er entscheidet aber nicht "User nicht eingeloggt -> Loginseite anzeigen".

                            Der Controller für "/login" entscheidet auch nicht, wie die Loginseite angezeigt wird, sondern nur, was für Daten er an sie weitergibt.
                            [URL="http://goo.gl/6Biyf"]Lerne Grundlagen[/URL] | [URL="http://sscce.org/"]Schreibe gute Beispiele[/URL] | [URL="http://goo.gl/f2jR7"]PDO > mysqli > mysql[/URL] | [URL="http://goo.gl/jvfSZ"]Versuch nicht, das Rad neu zu erfinden[/URL] | [URL="http://goo.gl/T2PU5"]Warum $foo[bar] böse ist[/URL] | [URL="http://goo.gl/rrfzO"]SQL Injections[/URL] | [URL="http://goo.gl/Q81WJ"]Hashes sind keine Verschlüsselungen![/URL] | [URL="http://goo.gl/2x0e2"]Dein E-Mail Regex ist falsch[/URL]

                            Kommentar


                            • #15
                              Na der Controller entscheidet, "User nicht eingeloggt -> Umleitung auf /login". Er entscheidet aber nicht "User nicht eingeloggt -> Loginseite anzeigen".
                              also bitte ... "umgeleitet" wird gar nichts, oder machst Du da wirklich einen "header Location" ?

                              Er entscheidet aber nicht "User nicht eingeloggt -> Loginseite anzeigen"
                              doch !
                              Wieso denn nicht ?

                              Jedenfalls entscheidet die View weder das eine noch das andere: die View ist strunzdumm,
                              von dem bißchen Designlogik abgesehn.
                              Eine if-else-Abfrage nimmt, ordentlich geschrieben eine Menge Platz weg. Platzsparend geht es mit einem ternären Operator.

                              Kommentar

                              Lädt...
                              X