Ankündigung

Einklappen
Keine Ankündigung bisher.

HMVC-Umsetzung mit dem APF

Einklappen

Neue Werbung 2019

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

  • HMVC-Umsetzung mit dem APF

    Dieser Thread wurde aus http://www.php.de/software-design/61...p-gesucht.html herausgelöst.

    Zitat von jw-lighting Beitrag anzeigen
    In dem ich $Pagecontroller->execute() aufrufe würde (nach meinem Verständnis) der View für die Seite instanziert, und mit Informationen gefüttert. Dieser nimmt sich dann das Rahmentemplate vor und läuft es von Anfang an durch.
    +
    Zitat von jw-lighting Beitrag anzeigen
    Ich habe etwas Angst, das ich den Eindruck erwecke ich will meine Idee um jeden Preis verteidigen. Darum geht es mir nicht, sondern um einen guten Ansatz.
    Ohne arrogant wirken zu wollen: ist das wirklich deine Idee? Das APF implementiert exakt diesen Ansatz um Module auch auf DOM-Baum-Ebene mit einer generischen Page-Controller-Verwaltung drumherum zu ermöglichen - und das nicht seit gestern.

    Hast du dir die Implementierung des Ansatzes dort mal angesehen? Im Detail hatte ich unter Plugin System - Forum: phpforum.de konkret über Plugin-Mechanismen gesprochen, die auf Basis einer (H)MVC aufgebaut sind. Ich denke, der Thread sollte dir nochmal ausführliche Informationen zum APF-Konzept geben.

    Zitat von jw-lighting Beitrag anzeigen
    Ich hatte angedacht, über eine Singeltoninstanz des Pagecontrollers immer eben diesen zu nutzen um das Modul aufzurufen.
    Egal wie tief ich schachtle, ist also nicht der jeweilige Controller sondern immer der Pagecontroller für den Aufruf eines anderen Moduls zuständig.
    Das ist - wie im verlinkten Thread und auch hier schon erwähnt - wichtig um einen generischen Ansatz wirklich implementieren zu können. Die Module/Plugins müssen dabei nach dem Composite-Pattern aufgebaut sein, damit der Page-Controller die Sprache des Moduls/Plugins auch versteht.

    Zitat von jw-lighting Beitrag anzeigen
    Ein View der auf ein Modul stößt muss sich um die Einbindung des Moduls kümmern um es einzusetzen, und ruft loadModule() des Pagecontrollers auf, der das Ergebnis des Modulviews zurückgibt.
    Das ist IMHO Blödsinn und wiederspricht sich mit dem letzten Satz. Ein Modul sollte vom Page-Controller verwaltet werden und nicht umgekehrt bzw. vom View. Ein View sollte nicht zu viele Aufgaben haben, denn er repräsentiert nur. Die Tatsache im Blick, dass das MVC-Pattern ein Pattern der Präsentations-Schicht ist, unterstreicht diese Aussage nochmals.

    Zitat von jw-lighting Beitrag anzeigen
    Da sich das aber immer auf direktem Wege zum Pagecontroller abspielt, wird nicht durchgereicht, nur weitergereicht.
    Im Gegenzug spart man sich das doppelte Parsen des Templates.
    Warum müssen Templates denn überhaupt doppelt geparst werden? Das APF beweist doch, dass es nicht notwendig ist - provokativ formuliert.

    Zitat von jw-lighting Beitrag anzeigen
    Darüber habe ich noch nicht nachgedacht.
    Kann die Bedingung vom View gelöst werden, ist das kein Problem.
    Hängt die Bedingung vom Modul selbst ab, wäre es am einfachsten einen leeren String zurückzugeben, wenn das Modul nicht veingebunden werden soll. Ist allerdings etwas unsauber.
    Das ist auch unsauber und sollte durch die Möglichkeiten des Moduls - nicht seines Views bzw. seiner Views - gelöst werden. Das APF hält hierzu die Möglichkeit bereit in einem Modul Entscheidungen über den Aufbau in Taglibs und Controllern treffen zu können. Hast du in einem "Menü-Modul" zwei Zustände kannst du entweder per Controller entscheiden, welcher Zustand angezeigt wird oder die Entscheidung fällt zuvor eine Front-Controller-Action und du greifst in der Taglib auf diese Informationen zu (View-Model) und bindest dasjenige Template ein, das für den Anwendungsfall relevant ist (siehe Spezielle TagLibs :: Adventure PHP Framework (APF)).
    Viele Grüße,
    Dr.E.

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    1. Think about software design [B]before[/B] you start to write code!
    2. Discuss and review it together with [B]experts[/B]!
    3. Choose [B]good[/B] tools (-> [URL="http://adventure-php-framework.org/Seite/088-Why-APF"]Adventure PHP Framework (APF)[/URL][URL="http://adventure-php-framework.org"][/URL])!
    4. Write [I][B]clean and reusable[/B][/I] software only!
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  • #2
    Zitat von dr.e. Beitrag anzeigen
    Ohne arrogant wirken zu wollen: ist das wirklich deine Idee? Das APF implementiert exakt diesen Ansatz um Module auch auf DOM-Baum-Ebene mit einer generischen Page-Controller-Verwaltung drumherum zu ermöglichen - und das nicht seit gestern.
    Ich habe mir in den letzten Tagen immer mal wieder Seiten aus der Doku zum APF angeguckt - dennoch könnte ich damit jetzt keine Website aufbauen.
    Sicherlich bin ich dadurch inspiriert worden. Was konkret in meinem Kopf als Idee entstanden ist, ist die loadModule() Methode des PageControllers mit der ich das Laden eines Moduls was im Template eingebunden ist an dem PageController überlasse. das war der Knoten der platzen musste.
    Wenn du es genau so machst, ist das für mich ein Zeichen das die Idee nicht alzu falsch gewesen sein kann..

    Zitat von dr.e. Beitrag anzeigen
    Hast du dir die Implementierung des Ansatzes dort mal angesehen? Im Detail hatte ich unter Plugin System - Forum: phpforum.de konkret über Plugin-Mechanismen gesprochen, die auf Basis einer (H)MVC aufgebaut sind. Ich denke, der Thread sollte dir nochmal ausführliche Informationen zum APF-Konzept geben.
    Du hattest dort ja schon hinverlinkt. Ganz geblickt und komplett durchgelesen habe ich es noch nicht. Vermutlich muss ich es mir mal ausdrucken und dann mit Marker/Bleistift dem Verständnis auf die Sprünge helfen...

    Zitat von dr.e. Beitrag anzeigen
    Das ist - wie im verlinkten Thread und auch hier schon erwähnt - wichtig um einen generischen Ansatz wirklich implementieren zu können. Die Module/Plugins müssen dabei nach dem Composite-Pattern aufgebaut sein, damit der Page-Controller die Sprache des Moduls/Plugins auch versteht.
    Die Kommunikation des Moduls mit dem PageController übernimmt doch eigentlich der Controller des Moduls (das müsste dann der DocumentController sein, richtig?). Würde da nicht ein einfaches Interface ausreichen?

    Zitat von dr.e. Beitrag anzeigen
    Das ist IMHO Blödsinn und wiederspricht sich mit dem letzten Satz. Ein Modul sollte vom Page-Controller verwaltet werden und nicht umgekehrt bzw. vom View. Ein View sollte nicht zu viele Aufgaben haben, denn er repräsentiert nur. Die Tatsache im Blick, dass das MVC-Pattern ein Pattern der Präsentations-Schicht ist, unterstreicht diese Aussage nochmals.
    Ich formuliere meinen Satz mal um:
    Ein View der auf ein Modul stößt muss es irgendwie einsetzen, und ruft loadModule() des Pagecontrollers auf, der sich um die Instanzierung des Moduls kümmert und das Ergebnis des Modulviews zurückgibt.

    So ist es gemeint. War schlecht formuliert.

    Zitat von dr.e. Beitrag anzeigen
    Warum müssen Templates denn überhaupt doppelt geparst werden? Das APF beweist doch, dass es nicht notwendig ist - provokativ formuliert.
    Wenn man von dem Ansatz, die Einbindung eines Moduls vom View entdecken und vom PageController ausführen zu lassen absieht, müsste zunächst der PageController das Template parsen, um Module ausfindig zu machen und zu instanzieren.
    Dann müsste der View das Template parsen, um es mit Inhalten zu füllen.
    Der PageController müsste die Ersetzung für die Modultags dann bereit stellen.

    EDIT:
    Zitat von nikosch Beitrag anzeigen
    Das bedeutet dann aber, dass das Template ohne Parameter von außen auskommt. Da Templates aber i.A. {-> ?} parameterisiert sind, muss das ja irgendwo passieren, z.B. beim Einbinden des Moduls.
    Welches Template meinst du?
    Das Template des Moduls bekommt seine Parameter vom Modell des Moduls bzw. evtl. benötigte Seiteninfomationen vom Pagecontroller.
    Das Rahmentemplate bekommt seine Informationen vom Pagecontroller.
    Das Modul ist also doch vollkommen unabhängig vom Rahmentemplate.

    Ich verstehe immer noch nicht genau was du meinst. Ist der Ansatz denn klar?

    Kommentar


    • #3
      Hallo jw-lighting,

      Ich habe mir in den letzten Tagen immer mal wieder Seiten aus der Doku zum APF angeguckt - dennoch könnte ich damit jetzt keine Website aufbauen.
      Hast du dir mal Download, Installation und erste Schritte angesehen? Der hier durkutierte Aufbau bzw. das Konzept hört sich viel schlimmer an, als es tatsächlich ist.
      Nehmen wir an, du baust eine Webseite mit einem Header über 100%, darunter ein Menü auf der linken Seite über 25% und dort wiederum daneben ein Inhaltsbereich über 75% auf, so reicht bereits folgendes Basis-Template:

      Code:
      <html>
         <head>
            ...(1)...
         </head>
         <body>
            <div id="wrapper">
               <div id="head">
                  ...
               </div>
               <div id="main">
                  <div id="menu">
                     ...(2)...
                  </div>
                  <div id="content">
                     ...(3)...
                  </div>
               </div>
               <div id="footer">
                  ...
               </div>
            </div>
         </body>
      </html>
      Die relevanten Stellen, an denen vermutlich dynamischer Inhalt stehen wird habe ich nummeriert. Nun gibt es zwei Spielweisen, wie dynamischer Inhalt eingenaut werden kann: via Taglib oder Controller. Im Beispiel würde ich vorschlagen, den Inhalt des Headers per Document-Controller zu befüllen und die Inhalte des Menüs und des Inhalts-Bereich per eigenem Template einzubinden. Das geht so:

      <@controller namespace="" file="main_controller" class="main_controller" @>
      <html>
      <head>
      <title><htmllaceholder name="title" /></title>
      </head>
      <body>
      <div id="wrapper">
      <div id="head">
      ...
      </div>
      <div id="main">
      <div id="menu">
      <core:importdesign
      namespace=""
      template="menu"
      />
      </div>
      <div id="content">
      <core:importdesign
      namespace=""
      template="content"
      />
      </div>
      </div>
      <div id="footer">
      ...
      </div>
      </div>
      </body>
      </html>
      Im Controller des Haupt-Templates kann ich nun den Titel der Seite füllen und in den Templates menu.html und content.html die dynamischen Inhalte definieren. Der Controller kann dabei folgenden Inhalt haben:

      PHP-Code:
      class main_controller extends base_controller {
         public function 
      transformContent() {
            
      $title = ...
            
      $this->setPlaceHolder('title',$title);
         }

      Die genannten Templates können wie folgt aussehen:

      menu.html
      Code:
      <ul>
         <li><a href="./?Seite=1">Seite 1</a></li>
         <li><a href="./?Seite=2">Seite 2</a></li>
         <li><a href="./?Seite=3">Seite 3</a></li>
      </ul>
      content.html
      Code:
      <@controller namespace="" file="content_controller" class="content_controller" @>
      Im Template content.html habe ich bewusst nur einen Controller spezifiziert, denn dieser ist dafür zuständig den Inhalt aus einer definierten Quelle an Hand des URL-Parameters "Seite" zu auszulesen und in den View einzusetzen. Das kann wie folgt passieren:

      PHP-Code:
      class content_controller extends base_controller {
         public function 
      transformContent() {
            
      $id RequestHandler::getValue('Seite',1);
            
      $content = ...;
            
      $this->setContent($content);
         }

      Rufen wir nun eine index.php auf, die die Zeilen

      PHP-Code:
      include('./apps/core/pagecontroller/pagecontroller.php');
      $page = new Page();
      $page->loadDesign('...','main');
      echo 
      $page->transform(); 
      werden wir das gewünschte Ergebnis erhalten - eine kleine aber feine Webseite. Sicher gehört hier noch ein bischen Styling dazu aber das HTML-Gerüst steht.

      Kümmern wir uns nun noch um den dynamischen Inhalt. Da hier üblicherweise Datenbanken im Spiel sind, lässt sich das obige Beispiel sehr einfach erweitern:

      main_controller.php
      PHP-Code:
      class main_controller extends base_controller {
         public function 
      transformContent() {
            
      $cM = &$this->__getServiceObject('core::database','ConnectionManager');
            
      $conn $cM->getConnection('Content-Database');
            
      $id RequestHandler::getValue('Seite',1);
            
      $result $conn->executeTextStatement('SELECT title FROM site_content WHERE id = \''.$id.'\'');
            
      $data $conn->fetchData($result);
            
      $this->setPlaceHolder('title',$date['title']);
         }

      content_controller.php
      PHP-Code:
      class content_controller extends base_controller {
         public function 
      transformContent() {
            
      $cM = &$this->__getServiceObject('core::database','ConnectionManager');
            
      $conn $cM->getConnection('Content-Database');
            
      $id RequestHandler::getValue('Seite',1);
            
      $result $conn->executeTextStatement('SELECT content FROM site_content WHERE id = \''.$id.'\'');
            
      $data $conn->fetchData($result);
            
      $this->setContent($data['content']);
         }

      Du wirst nun feststellen, dass es performance-technisch etwas ungünstig ist, die Inhalte zweimal zu laden - korrekt! Das kann auch mit einer Abfrage erledigt werden in dem man den Inhalt bereits in der index.php oder in einer Front-Controller-Action läd, ein (View-)Model für die Seite füllt und dieses dann einfach in den beiden Controllern zur Ausgabe nutzt. Grundsätzlich ändert das nichts an der Tatsache, dass das erstellen von Webseiten recht einfach mit dem APF ist.
      Möchtest du noch ein Modul an einer bestimmten Stelle einbinden, reicht das Platzieren eines <core:importdesign />-Tags an der entsprechenden Stelle.

      Wenn du es genau so machst, ist das für mich ein Zeichen das die Idee nicht alzu falsch gewesen sein kann..
      Falsch ist es keinesfalls nur eben nicht neu.

      Du hattest dort ja schon hinverlinkt. Ganz geblickt und komplett durchgelesen habe ich es noch nicht. Vermutlich muss ich es mir mal ausdrucken und dann mit Marker/Bleistift dem Verständnis auf die Sprünge helfen...
      Das ist zugegeben schon alles sehr theoretisch und man muss das auch nicht bis ins Detail verstanden haben. Sofern du es verstehen möchtest, solltest du es wieder und wieder lesen, mal eine Webseite mit dem APF bauen und an Hand dessen versuchen nachzuvollziehen, wie die Komponenten ineinander greifen.

      Die Kommunikation des Moduls mit dem PageController übernimmt doch eigentlich der Controller des Moduls (das müsste dann der DocumentController sein, richtig?). Würde da nicht ein einfaches Interface ausreichen?
      Es findet keine Kommunikation eines Moduls mit dem Page-Controller statt. Das darf schon alleine deshalb nicht sein, weil der Page-Controller alle Elemente des Baumes gleich behandeln können muss. Ist das nicht der Fall, lässt sich nicht so einfach ein Composite-Baum aufbauen und verwalten.
      Für die Kommunikation in einem Modul können unterschiedliche Elemente zuständig sein, zumeist sind es aber Document-Controller und Front-Controller-Actions. Aus diesem Grund implementieren die einzelnen Dokument-Baum-Knoten ein Interface das der Page-Controller kennt und in seinem Lifecycle nutzt, nur ist das zunächst alles, es gibt keine Rück-Kommunikation von Modul zu Page-Controller.

      Ein View der auf ein Modul stößt muss es irgendwie einsetzen, und ruft loadModule() des Pagecontrollers auf, der sich um die Instanzierung des Moduls kümmert und das Ergebnis des Modulviews zurückgibt.
      Der View soll nicht für die Steuerung eines Moduls zustöndig sein. Meiner Meinung nach muss das der Page-Controller erledigen, denn nur er kann ein gemeinsames und generisches Handling zur Verfügung stellen. Alle anderen Komponenten sind konkret - klar, sonst würde ein Gästebuch auch keine Einträge anzeigen, sondern irgend etwas generisches tun. Richtig ist, dass sich der Page-Controller um die Verwaltung und den Lifecycle eines Moduls kümmert. Beim APF ist das der DOM-Baum mit lauter kleinen MVC-Elementen.

      Wenn man von dem Ansatz, die Einbindung eines Moduls vom View entdecken und vom PageController ausführen zu lassen absieht, müsste zunächst der PageController das Template parsen, um Module ausfindig zu machen und zu instanzieren.
      Das muss er auch tun - tut der APF-Page-Controller - weil das die zentrale Stelle für soetwas ist. Man kann das Parsen sehr generisch in Quellcode formulieren und es gibt meiner Ansicht nach keinen Grund es nicht generisch zu tun. Das ist eine Sache, mit der man sich in einem Modul nicht mehr rumärgern möchte, denn ein Modul erfüllt einen konkreten Zweck. Weiterhin ist der Vorteil, dass die Steuerung des Lifecycle wirklich vollständig in der Hand des Page-Controllers liegt.
      Im APF ist dieser Mechanismus noch etwas subtiler implementiert. Hier übernehmen die Dokument-Knoten eine zusätzliche Verantwortung beim Aufbau des Baumes und geben dem Entwickler so die Möglichkeit, den Aufbau in unterschiedlichen Abschnitten des Lifecycles zu beeinflussen. Das ermöglicht es beispielsweise an deinem definierten Knoten an Hand eines URL-Parameters zu entscheiden, wie das Template des nächsten Sub-Knotens heißt und damit ein Modul A oder Modul B eingebunden wird.

      Dann müsste der View das Template parsen, um es mit Inhalten zu füllen. Der PageController müsste die Ersetzung für die Modultags dann bereit stellen.
      Wie oben beschrieben sollte das Parsen generisch implementiert sein, der Page-Controller übernimmt - und das ist richtig erkannt - dann das Zusammensetzen des Ergebnisses bei der Transformation.

      Allerdings hatte ich schon mal im phpforum gesagt: entweder ist alles ein Modul oder nichts. Du musst dich IMHO noch ein bischen vom klassischen Begriff eines Moduls lösen, denn im Rahmen eines Page-Controllers und des HMVC-Pattern gewinnt der Begriff "Modul" eine neue Tragweite. Hier ist ein Modul schon ein Dokument innerhalb eines HMVC-Baumes und nicht etwas eher klassisches. Umgekehrt kannst du dann eben auch ein klassisches Modul über ein Dokument im Baum in eine Applikation einhängen.

      Ich hoffe das hilft dir etwas weiter. Wenn du Fragen zum APF hast, sag einfach Bescheid, so kompliziert ist Webseiten bauen nun wirklich nicht.
      Viele Grüße,
      Dr.E.

      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      1. Think about software design [B]before[/B] you start to write code!
      2. Discuss and review it together with [B]experts[/B]!
      3. Choose [B]good[/B] tools (-> [URL="http://adventure-php-framework.org/Seite/088-Why-APF"]Adventure PHP Framework (APF)[/URL][URL="http://adventure-php-framework.org"][/URL])!
      4. Write [I][B]clean and reusable[/B][/I] software only!
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

      Kommentar


      • #4
        Vielen Dank erstmal!!
        Ich habe mir das Demopack mal runtergeladen und ein wenig im Code gestöbert. Kompliment!

        Der Wald lichtet sich so langsam, und wahrscheinlich werde ich mein nächstes Projekt dann auch mit dem APF bauen.

        Normalerweise bin ich der Meinung erst selbst zu coden, bevor ich etwas fremdes verwende. Allerdings steht hier im Vordergrund es vernünftig zu machen und da gibt es dem APF wohl nichts mehr hinzuzufügen, zumal die Zeit drängt.
        Einen eigenen Ansatz probiere ich dann später.


        Ich habe glaube ich einen kleinen Denkfehler durch den wir aneinander vorbei reden:
        Werden Modell, View und Controller alle durch eigene Klassen repräsentiert?
        Davon bin ich bisher eigentlich ausgegangen.
        Mir scheint aber, dass der View das Template selbst ist - also durch keine Klasse/Objekt repräsentiert wird - und dann vom PageController geparst wird.
        Das macht eine loadModule()-Methode dann in dem Sinne überflüssig.
        Richtig so?

        So weit erstmal von mir, muss los.
        Ich melde mich nochmal und gehe dann im Detail auf deinen Post ein.

        Kommentar


        • #5
          Zitat von dr.e. Beitrag anzeigen
          Du wirst nun feststellen, dass es performance-technisch etwas ungünstig ist, die Inhalte zweimal zu laden - korrekt! Das kann auch mit einer Abfrage erledigt werden in dem man den Inhalt bereits in der index.php oder in einer Front-Controller-Action läd, ein (View-)Model für die Seite füllt und dieses dann einfach in den beiden Controllern zur Ausgabe nutzt.
          Meinst du z.B. über Placeholder?
          Ich habe den Seitenbaum und die Navigation/en generell in der Datenbank. Da bietet sich doch dann z.B. auch ein Modell in Form eines Page-Models an, oder?

          Zitat von dr.e. Beitrag anzeigen
          Grundsätzlich ändert das nichts an der Tatsache, dass das erstellen von Webseiten recht einfach mit dem APF ist.
          Für eine einfache Website sicherlich, mittlerweile zweifel ich da keines Wegs mehr.
          Wie es jetzt mit eigenen Anwendungen/Programmen/Modulen läuft wenn es etwas komplexer wird, kann ich so nicht sagen. Da müsste man sich halt rein arbeiten. Aber es scheint ja ein gutes Konzept zu sein, von daher wird es auch nicht so kompliziert sein. Ich vertrau mal darauf

          Zitat von dr.e. Beitrag anzeigen
          Falsch ist es keinesfalls nur eben nicht neu.
          Den Anspruch wollte ich auch keineswegs stellen

          Zitat von dr.e. Beitrag anzeigen
          Es findet keine Kommunikation eines Moduls mit dem Page-Controller statt. Das darf schon alleine deshalb nicht sein, weil der Page-Controller alle Elemente des Baumes gleich behandeln können muss. Ist das nicht der Fall, lässt sich nicht so einfach ein Composite-Baum aufbauen und verwalten.
          Für die Kommunikation in einem Modul können unterschiedliche Elemente zuständig sein, zumeist sind es aber Document-Controller und Front-Controller-Actions. Aus diesem Grund implementieren die einzelnen Dokument-Baum-Knoten ein Interface das der Page-Controller kennt und in seinem Lifecycle nutzt, nur ist das zunächst alles, es gibt keine Rück-Kommunikation von Modul zu Page-Controller.
          Wo bekommt das Modul (kein Modell, also eine gesamte MVC-Node-Einheit) dann seine Daten? Wird es vorher "befüllt" und muss damit auskommen, oder werden die Daten an anderer Stelle auf Abfrage zur Verfügung gestellt.
          Ich meine mit Daten jetzt nicht den Inhalt des Modells, sondern z.B. Informationen zur aktuellen Seite oder von anderen Knoten.
          (Wenn ein Modul seine Darstellung z.B. dem vorhanden sein oder nicht vorhanden sein anderer Module innerhalb der Seite abhängig macht)

          Zitat von dr.e. Beitrag anzeigen
          Der View soll nicht für die Steuerung eines Moduls zuständig sein. Meiner Meinung nach muss das der Page-Controller erledigen, denn nur er kann ein gemeinsames und generisches Handling zur Verfügung stellen.
          Was verstehst du hier unter Steuerung? Wenn er den kompletten Life- und Workcycle eines Moduls eben dem PageController überlässt und nur sagt "Das soll hier hin, mach mir mal" ist das für mich keine Steuerung.

          Zitat von dr.e. Beitrag anzeigen
          Wenn man von dem Ansatz, die Einbindung eines Moduls vom View entdecken und vom PageController ausführen zu lassen absieht, müsste zunächst der PageController das Template parsen, um Module ausfindig zu machen und zu instanzieren.
          Das muss er auch tun - tut der APF-Page-Controller - weil das die zentrale Stelle für soetwas ist. Man kann das Parsen sehr generisch in Quellcode formulieren und es gibt meiner Ansicht nach keinen Grund es nicht generisch zu tun.
          Hier stellt sich jetzt für mich gerade wieder die Frage: Ist der View ein Objekt, was sich um das parsen des Templates kümmert?
          Oder macht das der PageController und der View ist das Template selbst.

          Zitat von dr.e. Beitrag anzeigen
          Das ist eine Sache, mit der man sich in einem Modul nicht mehr rumärgern möchte, denn ein Modul erfüllt einen konkreten Zweck. Weiterhin ist der Vorteil, dass die Steuerung des Lifecycle wirklich vollständig in der Hand des Page-Controllers liegt.
          Du meinst damit, das der Baum aus den einzelnen MVC Knoten bzw. Modulen zuvor vom PageController aufgebaut wird und die Module sich nur noch um ihre Transformierung kümmern müssen, oder?

          Zitat von dr.e. Beitrag anzeigen
          Im APF ist dieser Mechanismus noch etwas subtiler implementiert. Hier übernehmen die Dokument-Knoten eine zusätzliche Verantwortung beim Aufbau des Baumes und geben dem Entwickler so die Möglichkeit, den Aufbau in unterschiedlichen Abschnitten des Lifecycles zu beeinflussen. Das ermöglicht es beispielsweise an deinem definierten Knoten an Hand eines URL-Parameters zu entscheiden, wie das Template des nächsten Sub-Knotens heißt und damit ein Modul A oder Modul B eingebunden wird.
          Mir stellt sich nun die Frage, wie "ich als PageController" Submodule erkennen soll - also Module die im Template eines Moduls eingebunden werden - ohne das Template des Moduls zu kennen.
          Meinst du eben das mit "Verantwortung der Dokument-Controller beim Aufbau des Baumes"?
          Also kümmern sich die Dokument-Controller quasi genau darum, zu erkennen welche Subknoten gebraucht werden (und können auch darüber entscheiden) aber eben nicht um mehr.
          (Und geben diese Infos an den PageController weiter)

          Zitat von dr.e. Beitrag anzeigen
          Wie oben beschrieben sollte das Parsen generisch implementiert sein, der Page-Controller übernimmt - und das ist richtig erkannt - dann das Zusammensetzen des Ergebnisses bei der Transformation.
          Spricht dafür, das ich oben richtig liege.

          Zitat von dr.e. Beitrag anzeigen
          Allerdings hatte ich schon mal im phpforum gesagt: entweder ist alles ein Modul oder nichts. Du musst dich IMHO noch ein bischen vom klassischen Begriff eines Moduls lösen, denn im Rahmen eines Page-Controllers und des HMVC-Pattern gewinnt der Begriff "Modul" eine neue Tragweite. Hier ist ein Modul schon ein Dokument innerhalb eines HMVC-Baumes und nicht etwas eher klassisches. Umgekehrt kannst du dann eben auch ein klassisches Modul über ein Dokument im Baum in eine Applikation einhängen.
          Lass uns doch einfach von einem MVC-Knoten sprechen. Dann ist auch die Verwirrung Modul/Modell nicht mehr so groß.

          Zitat von dr.e. Beitrag anzeigen
          Ich hoffe das hilft dir etwas weiter.
          Aber hallo! Ich weiß gar nicht wie ich dir für deinen Aufwand danken soll. Du bringst mich hier echt voran.
          Ich bezweifel das mein Code deinen Anforderungen genügt. Wenn du allerdings bereit wärst, dir mal ein NestedSets-Paket von mir anzugucken.., vielleicht wäre das was für die Tools im APF.
          Etwas bin ich dir schuldig...

          Zitat von dr.e. Beitrag anzeigen
          Wenn du Fragen zum APF hast, sag einfach Bescheid...
          Ich würde mich sonst auch im APF-Forum melden - was ist dir lieber?
          Irgendwann bestimmt

          Zitat von dr.e. Beitrag anzeigen
          ...so kompliziert ist Webseiten bauen nun wirklich nicht.
          Ja!

          Kommentar


          • #6
            Hallo jw-lighting,

            nun schaffe ich es endlich dir zu schreiben.

            Meinst du z.B. über Placeholder?
            Ich habe den Seitenbaum und die Navigation/en generell in der Datenbank. Da bietet sich doch dann z.B. auch ein Modell in Form eines Page-Models an, oder?
            Korrekt. Du kannst in einem Controller ganz einfach Inhalte per Platzhalter im Template anzeigen. Da du die Inhalte ohnehin in der Datenbank hast, bietet sich ein Page-Model an, das in einer Front-Controller-Action gefüllt wird. Das geht dann im Prinzip so:

            index.php
            PHP-Code:
            $fC = &Singleton::getInstance('Frontcontroller');
            $fC->setContext('...');
            $fC->registerAction('sites::mybiz::setmodel','setModel');
            $fC->start('sites::my::pres::templates','root_template'); 
            SetModelAction.php
            PHP-Code:
            class SetModelAction extends AbstractFrontcontrollerAction {
               public function 
            run(){
                  
            $model = &Singleton::getInstance('ViewModel');
                  ...
                  
            $model->setContent(...);
                  
            $model->setPageId(...);
               }

            content_controller.php
            PHP-Code:
            class content_controller extends base_controller {
               public function 
            transformContent() {
                  
            $model = &Singleton::getInstance('ViewModel');
                  
            $this->setContent($model->getContent());
                  
            // Alternative:
                  
            $this->setPlaceHolder('content',$model->getContent());
               }

            Wie es jetzt mit eigenen Anwendungen/Programmen/Modulen läuft wenn es etwas komplexer wird, kann ich so nicht sagen. Da müsste man sich halt rein arbeiten. Aber es scheint ja ein gutes Konzept zu sein, von daher wird es auch nicht so kompliziert sein. Ich vertrau mal darauf
            Komplexer Anwendungen haben immer mehr Anspruch an den Entwickler - soviel ist klar. Aber das liegt meiner Ansicht nach nicht am Tool, sondern an den gestiegenen Anforderungen und den komplexeren Zusammenhängen. Das APF tut immer nur das, was du ihm sagst.

            Wo bekommt das Modul (kein Modell, also eine gesamte MVC-Node-Einheit) dann seine Daten? Wird es vorher "befüllt" und muss damit auskommen, oder werden die Daten an anderer Stelle auf Abfrage zur Verfügung gestellt. Ich meine mit Daten jetzt nicht den Inhalt des Modells, sondern z.B. Informationen zur aktuellen Seite oder von anderen Knoten.
            (Wenn ein Modul seine Darstellung z.B. dem vorhanden sein oder nicht vorhanden sein anderer Module innerhalb der Seite abhängig macht)
            Das wird über die "Umgebung", in dem sich ein Knoten befindet geregelt. Will heißen: der Page-Controller erzeugt den Knoten mit denjenigen Informationen, die er wissen muss um in seinem Umfeld aufgehoben zu sein (Vater-Beziehung) und die er benötigt um sich zu initialisieren (Context, Sprache, Tag-Attribute, ...). Innerhalb eines Knotens der Ebene 2 kannst du beispielsweise immer auf den Knoten der Ebene 1 (=Vater) zugreifen und von dort im Baum navigieren.
            Oft ist das aber nicht notwendig, denn ein Modul benötigt auf einfachere Weise für dieses selbst zentrale Informationen. Hierzu bietet sich immer ein Model an, das innerhalb des Moduls beispielsweise als Singleton genutzt wird.
            Sofern du Abhängigkeiten zwischen Knoten hast, kannst du die Informationen des Baumes selbst und dessen Knoten nutzen. Im Formular injiziert beispielsweise ein Datei-Upload-Feld automatisch das enctype-Attribut in das Formular (=Vater des Upload-Feldes), weil es seinen Vater direkt kennt. Wenn du in einem Controller abhängig vom eingebundenen Kind-View verschiedene Dinge tun möchtest, kannst du im Controller die Kinder des aktuellen Knotens abfragen und beispielsweise an Hand der Attribute beurteilen, was zu tun ist.

            Was verstehst du hier unter Steuerung? Wenn er den kompletten Life- und Workcycle eines Moduls eben dem PageController überlässt und nur sagt "Das soll hier hin, mach mir mal" ist das für mich keine Steuerung.
            Steuerung wurde hier immer wieder damit in Verbindung gebracht, dass der View dafür zuständig ist zu entscheiden, ob ein Sub-View eingebunden werden soll oder nicht. Das gilt es zu vermeiden und an den Page-Controller zu delegieren. Beim APF passiert das beispielsweise über den <core:importdesign />-Tag, der die Funktion hierfür kapselt und der Page-Controller nutzt diese Tag-Implementierung um den Teil des Baumes zu steuern.

            Hier stellt sich jetzt für mich gerade wieder die Frage: Ist der View ein Objekt, was sich um das parsen des Templates kümmert?
            Oder macht das der PageController und der View ist das Template selbst.
            Der Page-Controller kümmerst sich um das Parsen und im APF ist oft View = Template(-Datei). Manchmal ist ein View aber auch ein Control/Tag, das seinen Inhalt aus einer Datenbank o.ä. generiert.

            Du meinst damit, das der Baum aus den einzelnen MVC Knoten bzw. Modulen zuvor vom PageController aufgebaut wird und die Module sich nur noch um ihre Transformierung kümmern müssen, oder?
            Genau. Nur so erreichst du eine saubere Trennung der einzelnen Module und ihrer Zuständigkeiten.

            Mir stellt sich nun die Frage, wie "ich als PageController" Submodule erkennen soll - also Module die im Template eines Moduls eingebunden werden - ohne das Template des Moduls zu kennen.
            Meinst du eben das mit "Verantwortung der Dokument-Controller beim Aufbau des Baumes"?
            Das passiert quasi automatisch über die Signatur eines Tags. Diese haben ein gemeinsames Interface mit dem der Page-Controller interagiert. Beim <core:importdesign />-Tag ist das die onAfterAppend() in der ein Sub-View eingebunden wird. Diese Methode haben auch alle anderen. Deshalb entscheidet einzig uns allein die Tag-Implementierung über den internen Zustand. Da ich einen solchen Tag zu den View-Komponenten zähle passiert das zwar im View (das mag nun als Wiederspruch zu oben aussehen, ist es aber nicht) aber durch die Steuerung des Page-Controller, der dann den Knoten entsprechend in den Baum platziert.

            Also kümmern sich die Dokument-Controller quasi genau darum, zu erkennen welche Subknoten gebraucht werden (und können auch darüber entscheiden) aber eben nicht um mehr.
            (Und geben diese Infos an den PageController weiter)
            Nein, das tut einzig und alleine der Page-Controller zusammen mit den Tags. Die Document-Controller sind nur Möglichkeiten, die Transformation eines Knotens zu "unterstützen".

            Lass uns doch einfach von einem MVC-Knoten sprechen. Dann ist auch die Verwirrung Modul/Modell nicht mehr so groß.
            Gerne.

            Ich bezweifel das mein Code deinen Anforderungen genügt. Wenn du allerdings bereit wärst, dir mal ein NestedSets-Paket von mir anzugucken.., vielleicht wäre das was für die Tools im APF.
            Etwas bin ich dir schuldig...
            Seh' das nicht so eng, sondern nutze die Diskussion über deinen Code als Chance. So schlecht wird er nach der Diskussion hier nicht sein. Und: schuldig bist nur mir nichts, ich finde es aber trotzdem schön, dass du dich für das APF engagieren möchtest.

            Ich würde mich sonst auch im APF-Forum melden - was ist dir lieber?
            Irgendwann bestimmt
            Das ist ganz gleich. Vielleicht sollten wir aber hier einen anderen Thread nutzen, der ist schon wirklich sehr lang.
            Viele Grüße,
            Dr.E.

            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            1. Think about software design [B]before[/B] you start to write code!
            2. Discuss and review it together with [B]experts[/B]!
            3. Choose [B]good[/B] tools (-> [URL="http://adventure-php-framework.org/Seite/088-Why-APF"]Adventure PHP Framework (APF)[/URL][URL="http://adventure-php-framework.org"][/URL])!
            4. Write [I][B]clean and reusable[/B][/I] software only!
            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

            Kommentar


            • #7
              Zitat von dr.e. Beitrag anzeigen
              nun schaffe ich es endlich dir zu schreiben.
              Vielen Dank für die Meldung zwischendurch

              Korrekt. Du kannst in einem Controller ganz einfach Inhalte per Platzhalter im Template anzeigen. Da du die Inhalte ohnehin in der Datenbank hast, bietet sich ein Page-Model an, das in einer Front-Controller-Action gefüllt wird. Das geht dann im Prinzip so:
              Die Datenbank dient nur der Validierung des Seitenparameters (?page=xyz) und des Aufbaus der Navigation daraus. Die (statischen) Inhalte liegen in Templates.
              Für verschachtelte Navigationen ist dann eben das NestedSets-Paket gedacht, dem man dann die Verwaltung der NestedSets-Baum spezifischen Daten (LFT und RGT Werte) überlässt.
              Das wird über die "Umgebung", in dem sich ein Knoten befindet geregelt. Will heißen: der Page-Controller erzeugt den Knoten mit denjenigen Informationen, die er wissen muss um in seinem Umfeld aufgehoben zu sein (Vater-Beziehung) und die er benötigt um sich zu initialisieren (Context, Sprache, Tag-Attribute, ...). [...]
              Gut, das ist jetzt soweit klar. Ich habe jetzt angefangen eine Seite mit dem APF zu erstellen, dazu habe ich noch ein paar Fragen, die ich dann denke ich im APF-Forum stelle. Auf jeden bemerke ich hier gerade learning by doing.

              Steuerung wurde hier immer wieder damit in Verbindung gebracht, dass der View dafür zuständig ist zu entscheiden, ob ein Sub-View eingebunden werden soll oder nicht. Das gilt es zu vermeiden und an den Page-Controller zu delegieren.
              [...]
              Der Page-Controller kümmerst sich um das Parsen und im APF ist oft View = Template(-Datei). [...]
              Genau an dieses deligieren hatte ich auch gedacht. Von entscheiden war gar nicht die Rede. Allerdings hat sich das Problem jetzt eben auch dadurch beseitigt, dass meist View = Template ist, was auch der entscheidende Faktor war weshalb ich MVC teils nicht verstanden habe.

              Das passiert quasi automatisch über die Signatur eines Tags. Diese haben ein gemeinsames Interface mit dem der Page-Controller interagiert. Beim <core:importdesign />-Tag ist das die onAfterAppend() in der ein Sub-View eingebunden wird. Diese Methode haben auch alle anderen.
              Das verstehe ich noch nicht ganz. Was meinst du mit 'Signatur eines Tags'

              Deshalb entscheidet einzig und allein die Tag-Implementierung über den internen Zustand.
              Arg.. Was verstehst du unter 'interner Zustand'

              Nein, das tut einzig und alleine der Page-Controller zusammen mit den Tags. Die Document-Controller sind nur Möglichkeiten, die Transformation eines Knotens zu "unterstützen".
              Gut. Die Dokumentcontroller haben also nur die Aufgabe die internen Abläufe eines Knotens bis hin zur Transformation zu unterstützen.
              Nochmal zur Frage woher der PageController die Unterknoten eines Knotens kennt.
              Wir haben ein Tag, bspw. <blog:display />. Dieses Tag soll also die Inhalte eines Blogs darstellen.
              Für die Darstellung des Blogs wird die Klasse blog_taglib_display ja sicherlich ein eigenes Template benutzen wollen, z.B. ein HTML-Grundgerüst mit den Positionen für die Einträge und ein Formular für die Erstellung von Kommentaren. Das Formular und die Einträge stellen ja Kindknoten des Tags <blog:display /> dar, müssen also in den Doc.-Baum des Pagecontrollers integriert werden.
              Dieser kennt aber bestenfalls die Klasse blog_taglib_display hinter dem Tag, aber ja nicht die darin verwendeten Templates und die in den Templates auftretenden Subknoten. Woher weiß also der Pagecontroller welche Knoten in den Templates des Tags <blog:display /> vorkommen?

              Seh' das nicht so eng, sondern nutze die Diskussion über deinen Code als Chance. So schlecht wird er nach der Diskussion hier nicht sein. Und: schuldig bist nur mir nichts, ich finde es aber trotzdem schön, dass du dich für das APF engagieren möchtest.
              Ich habe vor der Diskussion angefangen, und bin auch noch nicht ganz fertig. Ich schicke dir dann einfach mal einen Link, wenn ich fertig bin. Dann kannst du selbst entscheiden ob du mal reingucken willst.

              Das ist ganz gleich. Vielleicht sollten wir aber hier einen anderen Thread nutzen, der ist schon wirklich sehr lang.
              Ja. Mittlerweile weicht die Diskussion ja auch recht stark vom eigentlichen Threadtitel ab.
              Magst du vielleicht die letzten Posts (z.B. ab #52) in einen neuen Thread 'Fragen zum HMVC-Prinzip (APF)' auslagern. Die Fragen die speziell zum APF auftauchen stelle ich im APF Forum.

              LG

              Kommentar

              Lädt...
              X