echo $begrüßung;
Wie soll ein View jetzt aufgebaut sein.
Soll es eine Klasse sein?
Es gibt keine Vorschriften diesbezüglich.
Zum Beispiel bei einem Newsletter-System gäbe es was die Empfänger des Newsletter angeht zwei visuelle Ausgaben.
- Das Formular zum eintragen des Newsletters
- Eine Liste aller Newsletter Empfänger
Des bisherigen Verlaufs entnommen würde ich daraus logischerweise zwei Views machen.
Genau.
Aber soll ich dann jeweils eine Klasse erstellen? Denn laut Listing 3 – Views\Home\Index.aspx, würde die direkte Ausgabe dort stehen.
Sowohl beim ASP.NET-MVC als auch bei dem des Zend Frameworks ist eine View nicht viel mehr als ein Template mit eingebauten Codestücken. Also ähnlich wie klassisches Wald- und Wiesen-PHP: HTML-Code mit <?php ?>-Blöcken dazwischen. Der qualitative Unterschied ist, dass sich in diesen Code-Blöcken nur Darstellungslogik befindet, und das möglichst sparsam.
Nun hat man aber bei einem Projekt, dessen Seiten bis auf den Haupt-Inhalt immer gleich aussehen sollen, wiederkehrende HTML-Teile. Diese einzeln in jede View zu kopieren ist nicht sehr wartungsfreundlich. Bei ASP.NET gibt es als Lösungsmöglichkeit das Konzept der Masterpages. Das ZF bietet dazu Zend_Layout an (in dem drei weitere Design Pattern stecken). Aber - siehe ganz oben - selbstverständlich kannst du die Views auch als Klassen implementieren, wenn dir das besser gefällt.
Wenn ich aber die Daten aus dem Array noch aufarbeiten muss, würde ich eher eine Klasse machen.
Ich blick niht ganz durch. Also das Model würde mir ja höchstens die Daten holen.
Ja. Es kommt darauf an, was du unter Aufarbeitung verstehst. Wenn es eine Datenverarbeitung im Sinne der Geschäftslogik ist, dann ist es Aufgabe des Models dies zu tun. Wenn es dazu zwei Schritte braucht (erst Daten holen und dann bearbeiten) oder noch mehr, dann muss es die eben erledigen. Gegebenenfalls kann auch der Controller zwischen mehreren Model-Schritten vermitteln. Wenn eine Model-übergreifende Verarbeitung notwendig ist (das eine holt die Daten, das andere bearbeitet sie) dann ist es sehr empfehlenswert, das den Controller vermitteln zu lassen, so dass die Models untereinander keine Abhängigkeiten aufbauen müssen, was ihren Wiederverwendungswert schmälerte.
Die Darstellung hingegen obliegt allein der View. Dazu gehören auch Modifikationen die nur zu Darstellungszwecken erforderlich sind. Die Darstellungslogik kann mitunter recht umfangreich werden, zum Beispiel wenn eine Datenstruktur mit mehreren HTML-Elementen zur Anzeige gebracht werden soll. Wenn diese Aufgabe auch noch mehrfach durchzuführen ist, hat man ein Standard-Problem des Programmierens. Und dafür gibt es Standard-Lösungen. Allgemein gesagt: wenn Code zu groß und unübersichtlich wird, strukturiert man ihn. Man erstellt beispielsweise Funktionen (die man auch in eigene Codedateien auslagern kann). Speziell gesagt: wenn die Darstellungslogik zu umfangreich wird (nicht nur dann), kann man sie ebenfalls auslagern. Das ZF bringt bereits einige solcher "ausgelagerten Logiken" in Form der View-Helper mit. Eigene View-Helper lassen sich implementieren und in das ZF einbinden. An der Stelle hast du ein weiteres Beispiel, wie dir ein Framework bei der Arbeit helfen kann. Es hat wieder eins deiner Probleme bereits gelöst oder zeigt zumindest eine Vorgehensweise auf, die man zur Lösung verwenden kann.
Achja. Eine Frage zum FrontController.
Sorgt der auch für den kompletten Seitenaufbau?
Denn der Frontcontroller muss ja irgendwo geladen werden.
Lade ich ihn OBEN in der index.php kann er Weiterleitungen per header() vollziehen, Session besser setzen usw... Aber - er kann den View nicht direkt ausgeben, sondern muss den View einer Variable zuweisen die dann irgendwo im Skript ausgegeben werden muss.
Der FrontController muss eigentlich nicht weiterleiten. Höchstens im Fehlerfall, wenn er keinen passenden ActionController findet. Aber auch da kann er sich im Prinzip auf die Ausgabe eines 404ers beschränken. Weiterleiten wollen aber gegebenenfalls die Controller. Alles kein Problem, denn eine Ausgabe wird ja erst auf Anweisung des Controllers erstellt. Ein Controller kann also beliebig HTTP-Header setzen. Selbst wenn mehrere Controller (oder Actions) nacheinander aufgerufen werden müssen, ist das nicht weiter tragisch, die jeweiligen Ausgaben müssen dann eben gepuffert werden. Man kann sogar soweit gehen, dass die Views nicht sofort mit ihrer Arbeit beginnen, sondern dass sie nur mit den jeweiligen Daten initialisiert und in eine Warteschlange eingereiht werden. Der FrontController arbeitet die dann zu gegebener Zeit ab und stößt den Renderprozess der Views an. In dem Fall müssten die Views dann sinnvollerweise Klassen sein und nicht nur Templates.
An welcher Stelle die Session getartet wird, kommt drauf an. Wird sie stets benötigt, kann das der FrontController als zentrale Instanz tun. Wird sie nur von einem oder verhältnismäßig wenigen Controllern kann man den Start auch in den/die Controller legen. Auch die Antwort auf die Frage "Will oder muss ich den Anwender immer mit (Session-)Cookies belästigen oder nur wenn es nötig ist?" kann zur Entscheidungsfindung beitragen.
Das hieße aber auch wenn ich eine Liste mit Postings wie bei meinem Boardskript erstelle, muss ich die View so einstellen das es die Postings etwa so handhabt:
Müssen muss man nicht. Können kann man aber. Dürfen darf man auch. Andere Wege gehen zum Beispiel. Ein Ansatz ist, sämtliche Ausgaben in einer Variable zu sammeln (oder an ein Array anzuhängen, das spart einige PHP-interne Umkopieraktionen beim Erweitern des Strings). Ein anderer Ansatz ist:
class PostingView extends BasisView {
private $posting;
public function __construct($posting) {
$this->posting = $posting;
}
private function fooHelper($value) {
return doSomethingWithValue($value); // was auch immer, ist nur ein Beispiel, dass man die View mit Ausgabelogik-Helpern anreichern kann.
}
public function render() {
?>
<div class="posting">Es folgt ein Beitrag von <?php echo $this->escape($posting->author) ?>.
<h3><?php echo $this->escape($posting->subject) ?></h3>
<p><?php echo $this->escape($posting->content) ?></p>
</div>
<?php
}
}
Da eine Controller-Action immer nur eine Teilaufgabe erledigen soll, ist es auch gar nicht ihre Aufgabe für das Gesamtlayout zu sorgen. Auch kann der FrontController mehrere Actions zur Ermittlung des Gesamtergebnisses aufrufen. Die jeweiligen Ausgaben zu sammeln und sie in das Gesamt-Layout einzubinden ist dann seine Aufgabe. Oder siehe oben - er sammelt nicht die Ausgaben sondern die Views ein und lasst sie zu gegebener Zeit rendern.
Hier eine Frage am Rande. OffTopic:
So ein Posting welches Name, Bild, Posting selbst, Datum, Uhrzeit, Signatur usw anzeigt, packe ich das in ein <li></li> oder einen Div-Container? Rein semantisch gesehen.
Diese Daten bilden für mich keine Liste, also bekommen sie eine Individualbehandlung. Zumal du sicher nicht alles unter- oder nebeneinander anordnen willst sondern vielleicht Name, Bild, Datum und Uhrzeit links und Posting und Signatur rechts daneben. Schon dieses optische Bild widerspricht meiner Meinung von einer Liste. Das Posting wird aus einem oder mehreren Absätzen bestehen. Eine Signatur ist eigentlich kein Absatz im engeren Sinne. Ein Name, ein Bild und Zeitangaben sind es garantiert nicht. Beim Durchsehen der HTML-Elemente ist mir jetzt keins aufgefallen, das wirklich passend wäre, also bleibt wohl nur das Universal-Element div.
echo "$verabschiedung $name";