Portal > Foren > PHP > PHP-Programmierung > [Design] CMS-System: Seitenstruktur
Antwort
 
Themen-Optionen
Alt 18.06.2007, 10:32 Nach oben    #1
Martin Eisengardt
 
Registriert seit: 30.03.2006
Ort: Pfinztal
Beiträge: 355
Standard [Design] CMS-System: Seitenstruktur

Hallo zusammen.


Ich habe nach Jahren der PHP-Abstinenz (nunja, war wohl eher nur ein ganzes Jahr) mal gedacht, ich versuche mich an einem Projekt. Hauptsächlich aufgrund der Tatsache, dass ich akut eine Webseite brauche. Da ich gleichzeitig auch mit all den neuen Modeerscheinungen Schritt halten will (Web 2.0, Ajax, bla blub) will ich von der Pike auf anfangen.

Also habe ich mir das Zend Framework geholt und habe losgelegt.

Hintergrund: Es geht mir aktuell um ein Application-Framework inklusive CMS, was ich aufsetzend auf das Zend Framework entwickeln will. Das Framework basiert auf View-Komponenten (hat erst einmal nichts mit den Zend Views zu tun). Beispiel für ein einfaches Login-Fenster:

PHP-Code:
$userLine = new Container();
$userLine->add(new Label("Benutzername:"));
$userLine->add(new InputField(), "inputBenutzername");
$rootComponent->add($userLine);
$rootComponent->add(new LineFeed());
$pwdLine = new Container();
$pwdLine->add(new Label("Passwort:"));
$pwdLine->add(new InputPasswordField(), "inputPassword");
$rootComponent->add($pwdLine);
$rootComponent->add(new LineFeed());
$rootComponent->add(new Button("Login"$meineLoginAction)); 
Man betrachtet eine Webseite also grundsätzlich nicht mehr als eine Webseite, sondern als eine View. Diese View besteht aus diversen Komponenten, die in der Lage sind, validen HTML-Code zu erzeugen. Es gibt eine Art Initialzustand der View, der immer sozusagen angezeigt wird, sobald ein unbekannter User die Webseite neu betritt oder wenn die View nicht in der Lage ist, eine alte Session aufzunehmen, weil beispielsweise der Login abgelaufen ist, die Seite aber einen Login erfordert.
Sobald der User diese Webseite erhalten hat, folgen alle weiteren Änderungen per DHTML. Klickt man beispielsweise auf einen Button, wird eine Aktion per WebRequest veranlasst, was zur Folge haben kann, dass eine neue Komponente eingefügt wird. Beispiel für $meineLoginAction:
PHP-Code:
function onKlick()
{
    [...]
    
// Annahme: Wir holen uns den Root-Container in $root
    
$username $root->getComponent('inputBenutzername')->getValue();
    
$password $root->getComponent('inputPassword')->getValue();
    [...]
    
// Validierung ist gelaufen
    
$root->removeAllChildren();
    
$root->add(new Label("Hallo Admin!"));

Nun der Ablauf des ganzen, wie ich ihn mir vorstelle. Sobald der Benutzer im Browser auf den Button "Login" klickt, werden per WebRequest die beiden Eingabefelder übertragen und der Aufruf des Buttons. Dadurch landet er im onKlick(). Diese Methode beeinflusst die View. Sie löscht zunächst alle vorherigen Elemente (Also das Login-Gedöhns, Eingabefelder usw.) und fügt ein allessagendes "Hallo, Admin!" hinzu. Als Antwort erhält das JavaScript aus dem WebRequest nun die Anweisung, die ganzen anderen Komponenten schlichtweg zu löschen und den neuen Text einzufügen.
Schließt man den Browser und öffnet man ihn wieder, findet das Framework die bereits existierende View mit gültigem Login. Es wird bei unserer View ein Resume aufgerufen, wobei die View dann entscheiden kann, ob sie die Benutzeranmeldung akzeptiert oder von vorne anfängt.
Frage: Ist das obige Konzept OK? Ist es verständlich für einen Neuling? Gibt es aus eurer Erfahrung mit DHTML- und Ajax- Anwendungen Anforderungen, die man vielleicht nicht abdecken kann?
Im Hinterkopf behalten sollte man, dass ich ganz weit später plane, dort so etwas wie Testklassen zu bauen. Also beispielsweise Klassen, die das Verhalten eines Users (die erzeugten Events) im Browser und im PHP abgreifen und aufzeichnen, um daraus beispielsweise automatisierte Tests zu erstellen.
Auch im Hinterkopf behalten: Ich rede nur von der Oberfläche des ganzen. Die Views beinhalten nicht zwangsläufig Anwendungslogik. Das würde man in separaten Klassen unterbringen. Die Anwendungsdaten sind nach Mimik des Zend-Frameworks eh in separaten Klassen gekapselt. Daraus ergibt sich auch die Frage: Wohin mit der Anwendungslogik? Das ist relativ simpel: Die Anwendungslogik basiert auf einem generischen Set aus solchen Aktionen, wie beispielsweise $meineLoginAction. Die ursprüngliche View-Klasse dient zum einen der Darstellung der Anwendung, als auch als Mediator, um zwischen der Darstellung und der Anwendung zu vermitteln.

Da ich für das ganze eine Art CMS bauen will ergibt sich ein kleines Problem bei dem ganzen. Ich betrachte die Webseiten fortan ja nicht mehr als Webseiten, wie beispielsweise Typo3, sondern als eine Seite, die sich interaktiv verändert. Wie strukturiere ich hier den Inhalt? Wie sieht ein CMS für so etwas aus? Von Grund auf werden heutige CMS in folgende Teile untergliedert: Navigation, Layout, Inhalt. Das friemeln die dann zusammen. Das klappt so ja nicht mehr, denn ich habe prinzipiell weder eine Navigation, noch "Seiten", für die man ein Layout definieren würde. Ich habe stattdessen zunächst eine oder mehrere Views, die man sich aus verschiedensten Komponenten zusammenklicken kann. Man plaziere Labels usw. Dort einbauen könnte man interaktive Komponenten, wie beispielsweise einen Login-Bereich. Als nächstes habe ich Aktionen, die Inhalte verändern. Wie wird aus sowas ein Schuh? Spinnen wir mal rum: Wie würde man eine vollständig auf DHTML-basierende "Web-Anwendung" inhaltlich pflegen wollen und damit in einem CMS-System darstellen wollen?
__________________
Open Sourcing the Online Gaming Universe
PHP/SQL/Java/C++/Assembler.
Seit Jahren Mitglied und Entwickler in einem der wohl größten Java-Projekte der Welt: http://weblogs.java.net/blog/hansmul...e_desktop.html
mepeisen ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 18.06.2007, 11:44 Nach oben    #2
Bastian Fenske
 
Registriert seit: 04.01.2006
Ort: Kassel
Beiträge: 826
Standard

Hi "mepeisen".

Hast du dir mal PRADO angeschaut? Ist auch ein event-basiertes Framework und bietet bestimmt einiges zum Abschauen.

Ein Paar Anmerkungen zu deinen Beispiel-Codes:

Zitat:
Zitat von mepeisen Beitrag anzeigen
PHP-Code:
$userLine = new Container();
$userLine->add(new Label("Benutzername:"));
$userLine->add(new InputField(), "inputBenutzername");
$rootComponent->add($userLine);
$rootComponent->add(new LineFeed());
$pwdLine = new Container();
$pwdLine->add(new Label("Passwort:"));
$pwdLine->add(new InputPasswordField(), "inputPassword");
$rootComponent->add($pwdLine);
$rootComponent->add(new LineFeed());
$rootComponent->add(new Button("Login"$meineLoginAction)); 
Ich würde hier eher mit konkreteren Widgets arbeiten. Was, wenn du einem Container hier noch ein InputField beigibst? Auf welches Feld bezieht sich dann das Label?

Eher so:
PHP-Code:
$View = new View;

$LoginForm = new Form;

$UserNameField = new InputField('username');
$UserNameField->addLabel(new Label('Benutzername:'));

$LoginForm->add($UserNameField);

$SubmitButton = new SubmitButton('Login');
$SubmitButton->registerAction('User''login');

$LoginForm->add($SubmitButton);

$View->add($LoginForm); 
Damit hast du auch die Felder gruppiert und weißt, welche Werte der Funktion übergeben werden müssen, die du an den Button geknüpft hast.

Zitat:
PHP-Code:
function onKlick()
{
    [...]
    
// Annahme: Wir holen uns den Root-Container in $root
    
$username $root->getComponent('inputBenutzername')->getValue();
    
$password $root->getComponent('inputPassword')->getValue();
    [...]
    
// Validierung ist gelaufen
    
$root->removeAllChildren();
    
$root->add(new Label("Hallo Admin!"));

Hier dann eben entsprechend:
PHP-Code:
<?php

class Module_User_Actions
{
    public function 
login(View $ViewRequest $Request)
    {
        
$User User::get($Request->username);
        if (
is_null($User) || $User->password !== $Request->password) {

            
// waere die Frage, wie das genau paltzieren
            
$View->add(new ErrorMssage('passt net'));

        } else {

            
$User->login();
            
$View->
        
}
    }
}
Wäre hier die Frage, ob man nicht die komplette View, sondern eben nur eine Komponente übergibt. Hier sind dann auch alle Elemente bekannt und Konflikte lassen sich ausschließen. ViewComponents müssten dann noch eine Schnittstelle nach außen haben, so z.B. Einhängepunkte für Observer. Hier kann sich z.B. die Komponente "MainMenu" einhängen, die dann bei Änderungen informiert wird und sich selbst aktualisiert.

Zitat:
Frage: Ist das obige Konzept OK? Ist es verständlich für einen Neuling?
Ich denke nicht, dass ein Neuling (also ein do-it-yourself PHP-Tibbeler), der gerade mal gelernt hat, was ein "Affenformular" ist so leicht in diese Konzepte reinkommt. Aber … muss ja auch nicht sein, oder?

Zitat:
Gibt es aus eurer Erfahrung mit DHTML- und Ajax- Anwendungen Anforderungen, die man vielleicht nicht abdecken kann?
Ein Punkt ist der, dass du, um eine View zu "rekonstruieren" immer POST-Requests absetzen musst. Wenn du eh JavaScript (Ajax) voraussetzt ist das Wurscht. Andernfalls kannst du eben z.B. nicht mit Links arbeiten, da der Status der View so eben nicht mit-übermittelt werden kann. Das ist zwar natürlich nichts neues, nur, wenn du mit so einem Konzept arbeitest, dann ist natürlich zu erwarten, dass, wenn der Benutzer links ins Suchfeld "Brotbacken" eingibt und rechts dann einen Link klickt, um die Wie-wird-das-Wetter-heute-in-Berlin-Box auszuklappen, die Benutzereingabe nicht verschwindet.

Ein weiterer Punkt, der zu durchdenken ist, sind mehrere Instanzen in mehreren Browserfenstern, sowie die Navigationsmöglichkeiten im Browser (Back-Button), Bookmarks etc. (letztlich eh Ajax-Typische Probleme, nur bei einem CMS natürlich nochmal besonders wichtig).

Ein weiterer Punkt sind hier auch Redirects. Nach jeder erfolgreichen Verarbeitung eines POST-Request machst du ja normalerweise einen Redirect (Location-Header), um ein nochmaliges Verarbeiten durch einen Refresh zu verhindern. Was passiert hier bei einem Refresh?

Zitat:
Auch im Hinterkopf behalten: Ich rede nur von der Oberfläche des ganzen. Die Views beinhalten nicht zwangsläufig Anwendungslogik. Das würde man in separaten Klassen unterbringen. Die Anwendungsdaten sind nach Mimik des Zend-Frameworks eh in separaten Klassen gekapselt. Daraus ergibt sich auch die Frage: Wohin mit der Anwendungslogik? Das ist relativ simpel: Die Anwendungslogik basiert auf einem generischen Set aus solchen Aktionen, wie beispielsweise $meineLoginAction. Die ursprüngliche View-Klasse dient zum einen der Darstellung der Anwendung, als auch als Mediator, um zwischen der Darstellung und der Anwendung zu vermitteln.
Ich vermute, hier brauchst du dann je Modul/Komponente eine eigene Schnittstelle, die die Views den Controllern anbieten, wie z.B. "insertErrorMessage()" oder "closeBox()", "refreshMenu()" etc.

Zitat:
Da ich für das ganze eine Art CMS bauen will ergibt sich ein kleines Problem bei dem ganzen. Ich betrachte die Webseiten fortan ja nicht mehr als Webseiten, wie beispielsweise Typo3, sondern als eine Seite, die sich interaktiv verändert. Wie strukturiere ich hier den Inhalt? Wie sieht ein CMS für so etwas aus? Von Grund auf werden heutige CMS in folgende Teile untergliedert: Navigation, Layout, Inhalt. Das friemeln die dann zusammen. Das klappt so ja nicht mehr, denn ich habe prinzipiell weder eine Navigation, noch "Seiten", für die man ein Layout definieren würde. Ich habe stattdessen zunächst eine oder mehrere Views, die man sich aus verschiedensten Komponenten zusammenklicken kann. Man plaziere Labels usw. Dort einbauen könnte man interaktive Komponenten, wie beispielsweise einen Login-Bereich. Als nächstes habe ich Aktionen, die Inhalte verändern. Wie wird aus sowas ein Schuh? Spinnen wir mal rum: Wie würde man eine vollständig auf DHTML-basierende "Web-Anwendung" inhaltlich pflegen wollen und damit in einem CMS-System darstellen wollen?
Die Frage ist ja, was du für einen Vorteil davon hast, es genau so zu machen. Macht irgendwie wenig Sinn, sich einen Entwurf auszudenken und dann rumzubasteln bis er vielleicht doch irgendwann zum Problem passt, oder? Nicht, dass ich den Ansatz uninteressant finde - für mich hab ich ihn jedoch als für mein CMS als untauglich erstmal beiseite gelegt, auch wenn ich an Teilen arbeite (PageFlow- und ViewState-Geschichten), die in die Richtung gehen und von denen ich mir sehr viel verspreche, wenn sie denn mal stehen.

Ähnlich deine Herangehensweise: Du brauchst akut eine Website und machst dich an ein anfängerfreundliches Web-Application-Ajax-Framework-CMS-Gebilde und fragst, wo die Grenzen sind (Welche Anforderungen lassen sich damit nicht umsetzen?).

Meine Erfahrung ist, dass du schneller vorankommst, wenn du erstmal für deine ganz konkreten und "kleinen" Anforderungen dein System baust, dich z.B. festlegst, ob Framework oder CMS, dir anschaust, wie die Seiten im CMS denn dargestellt werden müssen etc. Schwer vostellbar, dass du so ein System am Reißbrett entwerfen kannst ohne es an konkreten Anwendungen wachsen zu lassen (und dann natürlich auch immer mal wieder in Teilen oder komplett umbauen zu müssen, klar).

Ich entwickle seit über einem Jahr täglich an einem CMS (mit MVC-Framework-Charakter) und bin damit seit kurzem in Produktion. Es gibt einige wichtige Entwurfsentscheidungen, die ich jetzt anders treffen würde, als ich sie am Anfang getroffen habe und ich arbeite parallel (in meiner Freizeit) an neuen Strukturen für ein umfangreiches Refactoring. Das ganze nervt mich manchmal ganz schön, weil ich ja weiß, wie es besser sein könnte (oder: glaube, es zu wissen), aber nicht die Zeit habe, im laufenden Betrieb alles umzubauen (anstatt dessen schreib ich ellenlange Forenbeiträge *g). Aber: Ich musste den Weg so gehen, da ich ohne die konkreten und kleineren Anforderungen nichts zustande gebracht hätte und da ich am Anfang noch nicht die Komplexität so durchschauen konnte, wie ich das jetzt tue, nachdem ich eben monatelang täglich mitten drin bin in der Materie und die Vor- und Nachteile, sowie Grenzen der einzelnen Entscheidungen erst jetzt richtig abschätzen kann. Mag sein, dass einem da andere Vorgehensmethoden helfen, hier schon im Vorfeld mehr zu durchblicken - ich denke aber, dass das eher ein Problem ist, das in der Natur der Sache liegt und die Entwicklungen in Richtung agiler Software-Entwicklungen deuten ja genau darauf hin.

Soweit mal mein Senf.
Basti
Basti ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 18.06.2007, 13:21 Nach oben    #3
Martin Eisengardt
 
Registriert seit: 30.03.2006
Ort: Pfinztal
Beiträge: 355
Standard

Zitat:
Zitat von Basti Beitrag anzeigen
Ich würde hier eher mit konkreteren Widgets arbeiten. Was, wenn du einem Container hier noch ein InputField beigibst? Auf welches Feld bezieht sich dann das Label?
Das sollte der Einfachheit dienen und derzeit kenne ich noch nicht viel mehr außer Label Die Widgets kommen, sobald ich mir sicher bin, dass das Design OK ist. Dann gibbet auch sowas wie ein Form-Objekt, in dem man Eingabefelder und Aktionen gruppieren kann. Alternativ kann man vielleicht einem Button gezielt beibringen, welche Komponenten für ihn wichtig sind und übertragen werden müssen. Wie auch immer

Zu dem Plazieren von Elementen bin ich mir noch leicht unschlüsslig. In jedem Fall wird es Widgets geben, die sich ein bischen an dem Swing-Gedöhns orientieren, also auch sowas wie Panels mit einem GridbagLayout oder sowas (bin doch irgendwie vorbelastet durch Java *g*). Ansonsten gilt, dass die Standardkomponenten oder ein Container simpel alle Kinder hintereinander einblendet. Dass das vom Layout her schlecht ist, ist klar, aber dafür solls ja auch weiterführende Widgets geben.


Zitat:
Zitat von Basti Beitrag anzeigen
Wäre hier die Frage, ob man nicht die komplette View, sondern eben nur eine Komponente übergibt. Hier sind dann auch alle Elemente bekannt und Konflikte lassen sich ausschließen.
Elemente lassen sich immer eindeutig identifizieren. Ausgehend von einer Komponente kann man für jede eingehängte Kind-Komponente einen eindeutigen Namen vorgeben oder es wird eine eindeutige fortlaufende ID generiert. Ausgehend von einem Root-Objekt werden die Komponenten beispielsweise so identifiziert:
LoginBox_LoginPanel_UserField_UserInputField
(UserField ist das von dir angesprochene Widgets z.B.).
Ich nenne das ganze dann ViewPath und Referenzen sollen sich immer über einen solchen ViewPath abbilden lassen, der ausgehend von einem Root beschriftet ist. Das mit dem Unterstrich als "Trennzeichen" kommt hauptsächlich aus dem Zend Framework, da das dortan einigen Stellen als Mimik so gemacht wird.

Zitat:
Zitat von Basti Beitrag anzeigen
ViewComponents müssten dann noch eine Schnittstelle nach außen haben, so z.B. Einhängepunkte für Observer. Hier kann sich z.B. die Komponente "MainMenu" einhängen, die dann bei Änderungen informiert wird und sich selbst aktualisiert.
Bisher habe ich das so noch nicht bedacht. Aber die Login-abhängigen Menüs sind dafür ein gutes Beispiel. Generell soll sowas aber weniger die ViewComponent machen. Die gibt nur allgemeine Zustandsänderungen vor. Komplexere Widgets (nehmen wir mal ein LoginWidget) könnten freilich Aktionen anbieten, die sich auf einen erfolgreichen Login/ Logout beziehen. Man sollte wohl das, was ich weiter oben plump im Konstruktor eines Buttons als Aktion mitgegeben habe etwas aufboren. Auch um eventuell mehrere Aktionen auszuführen oder von einem Widget mehrere unterschiedliche Aktionen zu triggern.

Zitat:
Zitat von Basti Beitrag anzeigen
Ich denke nicht, dass ein Neuling (also ein do-it-yourself PHP-Tibbeler), der gerade mal gelernt hat, was ein "Affenformular" ist so leicht in diese Konzepte reinkommt. Aber … muss ja auch nicht sein, oder?
Das ist nicht die Zielgruppe

Zitat:
Zitat von Basti Beitrag anzeigen
Ein Punkt ist der, dass du, um eine View zu "rekonstruieren" immer POST-Requests absetzen musst. Wenn du eh JavaScript (Ajax) voraussetzt ist das Wurscht. Andernfalls kannst du eben z.B. nicht mit Links arbeiten, da der Status der View so eben nicht mit-übermittelt werden kann. Das ist zwar natürlich nichts neues, nur, wenn du mit so einem Konzept arbeitest, dann ist natürlich zu erwarten, dass, wenn der Benutzer links ins Suchfeld "Brotbacken" eingibt und rechts dann einen Link klickt, um die Wie-wird-das-Wetter-heute-in-Berlin-Box auszuklappen, die Benutzereingabe nicht verschwindet.
Ersteres (Rekonstruieren) sollte sogar problemlos möglich sein. Das einzige Problem - was man aber immer hat - sind zwischenzeitlich abgelaufene Logins oder auch Änderungen, die ausschließlich im Browser passieren. Das nicht-Verschwinden der Benutzereingaben funktioniert sogar, solange ich keine Komponenten explizit ersetze. Wenn ich sowas doch tue, müssten temporäre Benutzereingaben der Suchbox zwischenzeitlich übertragen werden, sobald die Suchbox durch was anderes ersetzt würde und kommt man zurück, würde man wieder das alte Suchwort sehen. Wenn die Suchbox mit der Wetter-Box nix zu tun hat, brauche ich auch nichts zum Server übertragen.

Zitat:
Zitat von Basti Beitrag anzeigen
Ein weiterer Punkt, der zu durchdenken ist, sind mehrere Instanzen in mehreren Browserfenstern, sowie die Navigationsmöglichkeiten im Browser (Back-Button), Bookmarks etc. (letztlich eh Ajax-Typische Probleme, nur bei einem CMS natürlich nochmal besonders wichtig).
Ich sehe hier von vornherein keine andere Chance, als zusätzliche Back-Buttons und ähnliches einzuarbeiten. Das ist wie du sagst, ein eher grundsätzliches Problem. Mehrere Instanzen sind typischerweise kein Problem, da ich eine View instantiiere und sie dabei eine eindeutige ID von mir verpasst bekommt, die bei jedem Ajax-Aufruf mitgeschickt wird. Problematisch wirds, wenn man eine Seite frisch betritt. Man weiss nciht wirklich, ob der Benutzer nun versucht, die Seite neu aufzubauen (also die alte Instanz weiterführen will) oder ob er eine neue öffnen will.
Das Problem habe ich noch vor mir her geschoben, derzeit bedeutet frisches Betreten der Seite: Mach frische Instanz. Muss man einiges an Hirnschmalz reinstecken

Zitat:
Zitat von Basti Beitrag anzeigen
Ein weiterer Punkt sind hier auch Redirects. Nach jeder erfolgreichen Verarbeitung eines POST-Request machst du ja normalerweise einen Redirect (Location-Header), um ein nochmaliges Verarbeiten durch einen Refresh zu verhindern. Was passiert hier bei einem Refresh?
Normalerweise passiert da nix, da ein Button kein Formular ist bzw. dabei einfach ein für den Browser nichtssagendes Javascript ausgeführt wird (was einen WebRequest macht...). Das mit dem Refresh-Button ist wieder das selbe Problem wie oben mit dem Back-Button. btw.: Kann ich die Navileiste ausblenden ohne ein neues Popup-Fenster zu öffnen?
ber du bringst mich auf eine andere Idee: Redirects von einer View auf eine neue. Wenn beispielsweise ein Request merkt, dass die Benutzeranmeldung abgelaufen ist, sollte er vielleicht bei einer Administrations-Anwendung auf eine völlig neue View wechseln, die nur beinhaltet "Admin böse, nix Anmeldung da." Also auch sowas wie ein Redirect

Zitat:
Zitat von Basti Beitrag anzeigen
Ich vermute, hier brauchst du dann je Modul/Komponente eine eigene Schnittstelle, die die Views den Controllern anbieten, wie z.B. "insertErrorMessage()" oder "closeBox()", "refreshMenu()" etc.
sowas in der Art ja.

Zitat:
Zitat von Basti Beitrag anzeigen
Die Frage ist ja, was du für einen Vorteil davon hast, es genau so zu machen. Macht irgendwie wenig Sinn, sich einen Entwurf auszudenken und dann rumzubasteln bis er vielleicht doch irgendwann zum Problem passt, oder? Nicht, dass ich den Ansatz uninteressant finde - für mich hab ich ihn jedoch als für mein CMS als untauglich erstmal beiseite gelegt, auch wenn ich an Teilen arbeite (PageFlow- und ViewState-Geschichten), die in die Richtung gehen und von denen ich mir sehr viel verspreche, wenn sie denn mal stehen.
Mein Ansatz verfolgt eine striktere Trennung zwischen CMS-Framework und den Basiskomponenten. Es soll (technisch) möglich sein, auch eine Anwendung per CMS zu pflegen, die mit einer klassischen Webseite (Navigation, Login, Inhaltsbereich) nicht so viel gemein hat. Ich will die Navigation und ein Inhaltsbereich als Module ansehen, die prinzipiell voneinander losgelösten Inhalt anbieten. Logischerweise ist das eine Herausforderung.

Zitat:
Zitat von Basti Beitrag anzeigen
Ähnlich deine Herangehensweise: Du brauchst akut eine Website und machst dich an ein anfängerfreundliches Web-Application-Ajax-Framework-CMS-Gebilde und fragst, wo die Grenzen sind (Welche Anforderungen lassen sich damit nicht umsetzen?).
Ich bin nicht unbelastet, was sowas angeht. Und ich werde mich sicher nicht übernehmen. Ich bin jetzt fast ein Jahrzehnt Profi-Entwickler, wenn auch nicht die ganze Zeit mit PHP... Will jetzt keinen virtuellen "Wer-hat-den-längsten"-Vergleich, aber wenn ich eines gelernt habe, dann, einzuschätzen, wo die Grenzen sind und was man schafft. Ich verspreche mir Ideen und Ansätze, mehr erstemal nicht

Zitat:
Zitat von Basti Beitrag anzeigen
Schwer vostellbar, dass du so ein System am Reißbrett entwerfen kannst ohne es an konkreten Anwendungen wachsen zu lassen (und dann natürlich auch immer mal wieder in Teilen oder komplett umbauen zu müssen, klar).
Das Framework inklusive des obigen praktischen Beispiels gibt es bereits und es löft. Auch die Ajax-Schnittstelle für einen Button-Klick gibt es und es löft. Die hunderte Widgets gibt es noch nicht...
__________________
Open Sourcing the Online Gaming Universe
PHP/SQL/Java/C++/Assembler.
Seit Jahren Mitglied und Entwickler in einem der wohl größten Java-Projekte der Welt: http://weblogs.java.net/blog/hansmul...e_desktop.html
mepeisen ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 18.06.2007, 14:47 Nach oben    #4
Bastian Fenske
 
Registriert seit: 04.01.2006
Ort: Kassel
Beiträge: 826
Standard

Hi.

Zitat:
Zitat von mepeisen Beitrag anzeigen
Zitat:
Zitat von Basti Beitrag anzeigen
Wäre hier die Frage, ob man nicht die komplette View, sondern eben nur eine Komponente übergibt. Hier sind dann auch alle Elemente bekannt und Konflikte lassen sich ausschließen.
Elemente lassen sich immer eindeutig identifizieren. Ausgehend von einer Komponente kann man für jede eingehängte Kind-Komponente einen eindeutigen Namen vorgeben oder es wird eine eindeutige fortlaufende ID generiert. Ausgehend von einem Root-Objekt werden die Komponenten beispielsweise so identifiziert:
LoginBox_LoginPanel_UserField_UserInputField
(UserField ist das von dir angesprochene Widgets z.B.).
Ich nenne das ganze dann ViewPath und Referenzen sollen sich immer über einen solchen ViewPath abbilden lassen, der ausgehend von einem Root beschriftet ist.
Was ich meine ist folgendes:
Du hast meinetwegen eine Komponente, die dem Benutzer erlaubt, sich einzuloggen. Die Komponente lässt sich sowohl als Mini-Formular in eine kleine Seitenspalte einbinden, also auch als "großes" Formular in den Bereich des Haupt-Contents der CMS-Seite. Beide Male ist der Pfad zwischen Root und LoginBox unterschiedlich. Für die Komponente selbst muss (sollte) dieser Part unerheblich sein.

Ich benutze z.B. RequestFilter, SessionFilter etc., die den einzelnen Komponenten nur Zugriff auf ihren eigenen Raum geben. Eine Benutzereingabe einer Komponente liegt dann z.B. in $_REQUEST['pagecomponent']['Downloads']['new_file']['title'], lasst sich aber nur via $this->Request->get('new_file.title') ansprechen, da die Komponente nichts davon weiß und wissen soll, dass sie unter der Bezeichnung "Downloads" als Seitenkomponente eingebunden ist und sich natürlich auch auf der anderen Seite keinen eigenen globalen Namen geben darf, um nicht in Konflikt mit anderen Komponenten zu geraten.

Zitat:
Zitat:
Zitat von Basti Beitrag anzeigen
ViewComponents müssten dann noch eine Schnittstelle nach außen haben, so z.B. Einhängepunkte für Observer. Hier kann sich z.B. die Komponente "MainMenu" einhängen, die dann bei Änderungen informiert wird und sich selbst aktualisiert.
Bisher habe ich das so noch nicht bedacht. Aber die Login-abhängigen Menüs sind dafür ein gutes Beispiel. Generell soll sowas aber weniger die ViewComponent machen.
Ja, stimmt. Eigentlich sollten die Komponenten ja den Zustand überwachen, sollte eine Menü-Komponente also den Zustand eines Sitemap-Objektes (oder sonstwas) in der Session überwachen und nicht die View, die eine Seite womöglich darstellt.

Zitat:
Zitat:
Zitat von Basti Beitrag anzeigen
Ich denke nicht, dass ein Neuling (also ein do-it-yourself PHP-Tibbeler), der gerade mal gelernt hat, was ein "Affenformular" ist so leicht in diese Konzepte reinkommt. Aber … muss ja auch nicht sein, oder?
Das ist nicht die Zielgruppe
Hat mich auch schon gewundert…

Zitat:
Zitat:
Zitat von Basti Beitrag anzeigen
Ein Punkt ist der, dass du, um eine View zu "rekonstruieren" immer POST-Requests absetzen musst. Wenn du eh JavaScript (Ajax) voraussetzt ist das Wurscht. Andernfalls kannst du eben z.B. nicht mit Links arbeiten, da der Status der View so eben nicht mit-übermittelt werden kann. Das ist zwar natürlich nichts neues, nur, wenn du mit so einem Konzept arbeitest, dann ist natürlich zu erwarten, dass, wenn der Benutzer links ins Suchfeld "Brotbacken" eingibt und rechts dann einen Link klickt, um die Wie-wird-das-Wetter-heute-in-Berlin-Box auszuklappen, die Benutzereingabe nicht verschwindet.
Ersteres (Rekonstruieren) sollte sogar problemlos möglich sein. Das einzige Problem - was man aber immer hat - sind zwischenzeitlich abgelaufene Logins oder auch Änderungen, die ausschließlich im Browser passieren. Das nicht-Verschwinden der Benutzereingaben funktioniert sogar, solange ich keine Komponenten explizit ersetze. Wenn ich sowas doch tue, müssten temporäre Benutzereingaben der Suchbox zwischenzeitlich übertragen werden, sobald die Suchbox durch was anderes ersetzt würde und kommt man zurück, würde man wieder das alte Suchwort sehen. Wenn die Suchbox mit der Wetter-Box nix zu tun hat, brauche ich auch nichts zum Server übertragen.
Das funktioniert halt nur in einer "Ajax-only"-Lösung oder eben mit JavaScript (POST-Request per Link oder Werte über den angesprochenen Pfad in Cookies legen).

Basti
Basti ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 20.06.2007, 17:17 Nach oben    #5
Martin Eisengardt
 
Registriert seit: 30.03.2006
Ort: Pfinztal
Beiträge: 355
Standard

sodele. Ich habe nun das gesamte Message-System noch einmal leicht überarbeitet.

Es gibt da seit Anfang an einen ViewState, der den Status der Web-Anwendung beinhaltet und bezeichnenderweise in der Session beheimatet ist.

Dieser Status beinhaltet
a) den kompletten Baum aus den View-Komponenten
b) einen zentralen Listener, der als Controller fungiert und ausgehend von Ereignissen reagiert, um die Anwendung und die View zu steuern
c) einen Datenbaum, der das Model beinhaltet. Das beinhaltet in erster Linie das Modell, das zur Lebenszeit der Anwendung aufgebaut wird.
d) über die Zend_Registry einen (statischen) Konfigurationsbereich für die aktuelle View und darüber die Verknüpfung zu Datenbank-Objekten, die für Laufzeitunabhängige/ Sessionunabhängige Datenspeicherung und Zugriffe auf eine Datenbank benötigt werden.

a), c) und d) generieren nun Events, die aus einem Event-Bezeichner (zur Unterscheidung mehrerer Events), einer optionalen Datenvariable und einer Quelle bestehen.
Die Events können auch aus dem Client stammen (Mausklick auf einen Button). Die Änderung, die ich vorgenommen hab ist, dass die View-Komponenten selbst Events ihrer Kinder abfangen können, wenn sie das wollen.

Diese Events werden nun an einen Controller weitergereicht, der dann hoffentlich etwas sinnvolles damit anstellt.

Wie sähe das ganze nun effektiv beim angesprochenen Login-Beispiel aus? Gegeben ist eine Oberfläche, in der man über eine standardmäßig vorgegebene Leiste einen kurzen Login ermöglicht. Mit kleinen Eingabefeldern und ähnlichem. Dazu kommt jedoch ein ausführlicher Login mit zusätzlichen Feldern (zum Beispiel "Stay Connected Checkbox" und so Zeugs).

Sobald der Kerle auf "Login" klickt, werden in einem Rutsch mehrere Ereignisse per Ajax-Gedöhns an das PHP kommuniziert. Das sind die Ereignisse "Änderung Inhalt an Eingabefeld Benutzerdaten; Änderung Inhalt an Eingabefeld Passwort, [...] Klick auf Button Login". Diese Ereignisse werden abgearbeitet und der Klick aufs Login ist interessant.

Folgende Beispiele lassen sich allesamt umsetzen.

Variante 1:
-> Ein Listener (also ein Controller) greift dieses Ereignis ab und vollzieht den Login. Gleichzeitig sorgt er dafür, dass die zweite Login-Komponente benachrichtigt wird und sich ihre Darstellung verändert. Dazu muss er logischerweise die Login- Komponenten kennen.

Variante 2:
-> Die Eingabefelder werden in einer "unsichtbaren" LoginComponent gruppiert. Diese LoginComponent ist eine UI-Komponente, die also in der UI "sitzt". Sie greift den Button-Klick ab und wandelt ihn um in ein allgemeines "LoginEvent". Der Listener (Controller) reagiert seinerseits nur auf dieses "LoginEvent" und macht dann das richtige. Er interessiert sich nicht unbedingt dafür, aus welcher Komponente dieses LoginEvent generiert wurde. Da ich sowieso zwischen Events, die vom Client dürfen können und welchen, die systemintern weitergereicht werden dürfen, unterscheide, kann man das nicht umgehen.

Variante 3:
-> Der Button-Klick bewirkt, von der UI-Komponente veranlasst, eine Veränderung einer Variablen im Model. Durch diese Veränderung wird wieder ein Ereignis generiert, was ein Controller abfängt und nun veranlasst, einen Login zu probieren. Das Ergebnis des Logins bewirkt wieder eine Veränderung einer Variablen im Model, wodurch wiederum alle verfügbaren Login-Komponenten, die auf dieses Ereignis warten, wissen, dass ein Login erfolgt ist und sie sich verändern müssen.
__________________
Open Sourcing the Online Gaming Universe
PHP/SQL/Java/C++/Assembler.
Seit Jahren Mitglied und Entwickler in einem der wohl größten Java-Projekte der Welt: http://weblogs.java.net/blog/hansmul...e_desktop.html
mepeisen ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 20.06.2007, 21:52 Nach oben    #6
Bastian Fenske
 
Registriert seit: 04.01.2006
Ort: Kassel
Beiträge: 826
Standard

…schon wieder ich … aber scheint wohl sonst hier keinen interessieren, oder?

Von Variante 3 würde ich abraten. Sicher keine gute Idee, wenn die View Benutzereingaben in die Model-Schicht kopiert und dann irgendwelche Controller informiert, die den Mist dann da wieder raussammeln müssen!

Meinem Gefühl nach bräuchten beide Komponenten zwei Controller oder es handelt sich um zwei unterschiedlich konfigurierte Instanzen einer Komponente. Diese bekommt die Benutzereingaben und probiert den LogIn. Bei einem Erfolg ist das recht einfach (denke ich Der Status des Benutzers in der Session ändert sich und die übrigen Komponenten, für die das relevant ist (Steuerungselemente, personalisierte E. etc.) haben sich zuvor eh entweder für ein Event onLogin oder bei einem Container in der Session angemeldet, der eben den Benutzer hält.

Wenn der Login jedoch fehlschlägt muss eine höhere Instanz entscheiden, was zu tun ist. In der Regel wieder hier ja erstmal die ausführliche Login-Box, versehen mit der Fehlermeldung in den Hauptbereich der Site geladen, womit natürlich alle "Quicklogins" verschwinden.

ich würde hier einfach mal alle möglichen Pageflow-Fälle sammeln und analysieren. Bei Websites ist es ja z.B. so, dass es praktisch immer einen Haupt-Content gibt und alles andere ist Beiwerk, dass sich entweder auf den Hauptinhalt bezieht oder diesen auch verändern kann (oder auch garnichts damit zu hat). In dem Fall braucht es womöglich keine aufwändige Kommunikation unter den einzelnen Komponenten, sondern eine … wie sagt man … konzentrische, sternförmige, zentralisierter Austausch würde reichen.

Nett ist natürlich immer, diese PageFlow-Geschichten komplett von außen her steuerbar/konfigurierbar zu machen.

Basti
Basti ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 21.06.2007, 06:56 Nach oben    #7
Martin Eisengardt
 
Registriert seit: 30.03.2006
Ort: Pfinztal
Beiträge: 355
Standard

Zitat:
Zitat von Basti Beitrag anzeigen
…schon wieder ich … aber scheint wohl sonst hier keinen interessieren, oder?
Wenigstens einen

Zitat:
Zitat von Basti Beitrag anzeigen
Meinem Gefühl nach bräuchten beide Komponenten zwei Controller oder es handelt sich um zwei unterschiedlich konfigurierte Instanzen einer Komponente.
oder halt einen Controller, der schlichtweg beide kennt und beide gleich behandelt, was in manchen Fällen sicherlich nicht so geschickt gelöst werden könnte

Zitat:
Zitat von Basti Beitrag anzeigen
Wenn der Login jedoch fehlschlägt muss eine höhere Instanz entscheiden, was zu tun ist. In der Regel wieder hier ja erstmal die ausführliche Login-Box, versehen mit der Fehlermeldung in den Hauptbereich der Site geladen, womit natürlich alle "Quicklogins" verschwinden.
Im Zweifelsfalle macht dies der Controller, der den fehlgeschlagenen Login verursachte bzw. er veranlasst sowas.

Zitat:
Zitat von Basti Beitrag anzeigen
ich würde hier einfach mal alle möglichen Pageflow-Fälle sammeln und analysieren. Bei Websites ist es ja z.B. so, dass es praktisch immer einen Haupt-Content gibt und alles andere ist Beiwerk, dass sich entweder auf den Hauptinhalt bezieht oder diesen auch verändern kann (oder auch garnichts damit zu hat). In dem Fall braucht es womöglich keine aufwändige Kommunikation unter den einzelnen Komponenten, sondern eine … wie sagt man … konzentrische, sternförmige, zentralisierter Austausch würde reichen.
Aber nette Idee, ich werde mir das denn mal anschauen. Allzu grün sollte die Wiese nicht sein, auf der man bastelt, also wäre der Zeitpunkt gut, sich mal die Webseite, die ich im Sinn habe, anzuschauen und die dortigen PageFlows. Ansonsten kenne ich ein ähnliches System bereits aus einem Java-Framework und so schlecht ist das nitt.

Zitat:
Zitat von Basti Beitrag anzeigen
Nett ist natürlich immer, diese PageFlow-Geschichten komplett von außen her steuerbar/konfigurierbar zu machen.
Was bedeutet bei dir "von außen"?
__________________
Open Sourcing the Online Gaming Universe
PHP/SQL/Java/C++/Assembler.
Seit Jahren Mitglied und Entwickler in einem der wohl größten Java-Projekte der Welt: http://weblogs.java.net/blog/hansmul...e_desktop.html
mepeisen ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 21.06.2007, 16:41 Nach oben    #8
Bastian Fenske
 
Registriert seit: 04.01.2006
Ort: Kassel
Beiträge: 826
Standard

Zitat:
Zitat von mepeisen Beitrag anzeigen
Zitat:
Zitat von Basti Beitrag anzeigen
Nett ist natürlich immer, diese PageFlow-Geschichten komplett von außen her steuerbar/konfigurierbar zu machen.
Was bedeutet bei dir "von außen"?
Damit meine ich, dass diese Infos eben in einer (oder mehreren) Separaten Dateien oder in der Datenbank abgelegt sind und eben nicht fest in den Controllern einprogrammiert sind. Der Controller sagt dann nur: "Login fehlgeschlagen" und ein ApplicationController erfährt dann aus diesen PageFlow-Definitionen (verwende ich den Begriff page flow hier eigentlich richtig, oder hat sich bei mir da was falsch eingeschlichen?), was als nächstes zu tun ist (Mini-Login-Box abschalten, große Login-Box ins Haupt-Panel laden).

Ich hab hier[1] vor einem Jahr mal einen Ansatz von mir veröffentlicht, wie man sowas ev. auch in PHP definieren könnte.

[1] http://www.phpfriend.de/forum/viewtopic.php?t=59036

Bin davon aber mittlerweile der Ansicht, man müsste da schon einen eigenen Parser schreiben, da es sonst zu viele Fehlerquellen gibt, die man nicht ausschließen kann. Aber ... das führt jetzt wohl auch ein wenig weg vom eigentlichen Thema.

Basti
Basti ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 22.06.2007, 09:50 Nach oben    #9
Martin Eisengardt
 
Registriert seit: 30.03.2006
Ort: Pfinztal
Beiträge: 355
Standard

Zitat:
Zitat von Basti Beitrag anzeigen
(verwende ich den Begriff page flow hier eigentlich richtig, oder hat sich bei mir da was falsch eingeschlichen?)
Doch, passt schon. Wobei es in einer reinen Ajax-Lösung etwas fragwürdig ist, ein PageFlow zu haben. Aber das ist Haarspalterei

Den Ansatz schaue ich mir mal an.
__________________
Open Sourcing the Online Gaming Universe
PHP/SQL/Java/C++/Assembler.
Seit Jahren Mitglied und Entwickler in einem der wohl größten Java-Projekte der Welt: http://weblogs.java.net/blog/hansmul...e_desktop.html
mepeisen ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 24.06.2007, 22:28 Nach oben    #10
Martin Eisengardt
 
Registriert seit: 30.03.2006
Ort: Pfinztal
Beiträge: 355
Standard

Sodele. Meine aktuellen Experimente haben in folgender Seite gefruchtet:
http://www.pentagaia.de/alpha2/

Man betrete die Seite (mit aktiviertem JavaScript und erlaube auch die Cookies...) und klicke auf den Bupperl. Dann wundere man sich.

Unten drunter gibt es Informationen und eine Sicht, wie denn die Klassen für dieses Beispiel ausschauen. Im Moment ist es logischerweise noch sehr sehr simpel, das Beispiel, aber viel mehr soll ein "Hello World!" ja nicht sein oder?

P.S.: Der Microsoft mag meinen zeichensatz nicht oder das Eclipse oder was weiß ich. Mir egal, es ist schon spät, ich muss früh raus, wenn ihr also im IE komische Kästerl statt Ä,Ö,Ü seht, nehmt den Firefox.

Getestet mit IE 7 (Windows, Wine) und Firefox 2.0-30 (SuSe, Windows). Und mein Konqueror mags scheinbar nitt, was mir im Moment aber herzlich egal ist.

Update: Ben, dass es bei dir nitt will, liegt genauso wie bei mir wohl daran, dass die View kaputt geht. Sprich, der Server findet die Komponente nimmer. Keine Ahnung, wieso, aber ich hab bei mir lokal php 5.2.3 installiert und aufm Server ist die 5.2.2 unter Linux. Hmmm. ich wollt ja eigentlich ins Bett *g*
__________________
Open Sourcing the Online Gaming Universe
PHP/SQL/Java/C++/Assembler.
Seit Jahren Mitglied und Entwickler in einem der wohl größten Java-Projekte der Welt: http://weblogs.java.net/blog/hansmul...e_desktop.html

Geändert von mepeisen (24.06.2007 um 23:10 Uhr).
mepeisen ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 24.06.2007, 22:51 Nach oben    #11
Ben
Benjamin Klaile
 
Benutzerbild von Ben
 
Registriert seit: 02.12.2004
Ort: Remagen
Beiträge: 4.480
Standard

Bei mir passiert nix, wenn ich auf den "Hallo"-Button klick ...
Ben ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 24.06.2007, 22:52 Nach oben    #12
Erfahrener Benutzer
 
Benutzerbild von Bleistift
 
Registriert seit: 31.12.2006
Ort: Zürich
Beiträge: 298
Standard

Bei mir wird im Hintergrund ein Request gestartet, der folgende Antwort bekommt:
Code:
<br />
<b>Warning</b>:  Invalid argument supplied for foreach() in <b>/services/web/apache2/htdocs/alpha2/application
/lib/PTBDynamicView.php</b> on line <b>119</b><br />
{"Code":1,"Response":[]}
__________________
. <-- This is Punkt. Copy Punkt into your signature to help him on his way to world domination.
Bleistift ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 24.06.2007, 23:03 Nach oben    #13
Martin Eisengardt
 
Registriert seit: 30.03.2006
Ort: Pfinztal
Beiträge: 355
Standard

O_o Was habt ihr für Browser? Javascript is aktiviert?

Isch gucke. Naja. Wie gesagt, ist es erst auf wenigen Plattformen getestet....



@Bleistift: Dein Reqest ist wohl nicht valide. Möglich, dass das Json-Script, was ich im Internet gefunden habe, nicht so sauber überall läuft. Fehlerbehandlung ist (noch) Mangelware an dieser Stelle *g*.

Ich würde gerne wissen, welcher Browser, damit ich mal gucken kann, wieso das nicht klappt. Ich logge ja fleisig mit und gucke mal, was du da losgeschickt hast.... Ich müsst euch zwei nur auseinander halten können. Egal, morgen ist noche in Tag, gut nacht.

P.S.: Der Text von die Button, sollt sich beim ersten Klick verändern, Ben.
__________________
Open Sourcing the Online Gaming Universe
PHP/SQL/Java/C++/Assembler.
Seit Jahren Mitglied und Entwickler in einem der wohl größten Java-Projekte der Welt: http://weblogs.java.net/blog/hansmul...e_desktop.html
mepeisen ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 24.06.2007, 23:19 Nach oben    #14
Bastian Fenske
 
Registriert seit: 04.01.2006
Ort: Kassel
Beiträge: 826
Standard

Bei mir tut das auch nicht (hier gerade FF 2.0.0.4 aus OS X) - probier das morgen im Büro mal auf meinem Debian.

Macht es nicht mehr Sinn, die Controller entweder z.B. hier an den Button zu kleben (Observer-Pattern) bzw. dem Button verschiedene Events zu verpassen, an die du verschiedene Controller-Methoden oder -Objekte registrieren kannst?

Wie ist das mit bei Model-Updates? Muss da bei jeder Änderung jeder gerade eingebaute Controller benachrichtigt werden? Wie setzt du das um?

Basti