![]() Das große Missverständnis. Oder: Warum Template Engines nicht glücklich machen.![]() Seit Jahren geistern in der PHP-Community verschiedenste sog. "Template Engines" herum. Diese zeichnen sich meist dadurch aus, dass sie eine mehr oder weniger komplexe Template-Syntax etablieren und dem Anwender versprechen, damit könnte er seine PHP-Projekte ganz toll übersichtlich machen. Und - kaum zu glauben - die meisten fallen auf diese Behauptung auch noch herein. Weshalb diese Behauptung falsch ist und wie es überhaupt zu diesem Missverständnis kommen konnte, erkläre ich im Folgenden. Ich versuche dabei nachzuvollziehen, wie sich dieses Missverständnis überhaupt in den Köpfen festsetzen konnte aus der Sicht einer naiven Herangehensweise an ein neues Projekt. Wie alles beginntJeder, der erste Programmiererfahrungen im Webbereich mit PHP sammelt, wird erstmal eine Datei erstellen, und dort den gesammten Quellcode mit PHP und HTML reinschreiben. Das Ergebnis kann sich schnell sehen lassen: Mit nur wenigen Zeilen hat man schon seine erste Website erstellt. Mit der Zeit wird man anspruchsvoller und baut noch ein paar mehr Sachen in die Seite, die Datei wächst und der Funktionsumfang nimmt zu. Man verarbeitet Benutzereingaben, führt Berechnungen durch, lädt Daten aus externen Quellen nach und gibt das irgendwann formatiert als HTML aus. Wenn man dann alle Funktionen eingebaut hat, die man gerne hätte, kommt gleich das nächste: Jetzt soll alles schön werden! Ein klares Design, hübsche Farben und ein paar Bilder zur Auflockerung sollen in die Seite.Und schon steht man vor einem Problem: Die Datei ist so lang geworden, dass man vor lauter "if" und "echo" gar nicht mehr so genau erkennen kann, wie der letztendliche Quelltext der HTML-Seite aussehen wird. Das muss doch anders gehen! Die Geburt des TemplatesWenn man sich dann genug geärgert hat über seinen eigenen Spaghetti-Code, macht man den nächsten konsequent naiven Schritt: Wäre es nicht schön, den gesamten HTML-Quellcode wieder aus der Seite herauslösen zu können und nur ganz wenig Elemente zu haben, die diesen HTML-Code stören? Wäre es nicht toll, wenn man die Seite völlig unabhängig gestalten kann und mit ganz einfach strukturierten Platzhaltern dann die Texte dynamisch einfügt, die man gerne hätte? Und weil man ja konsequent ist, macht man das. Der Einfachheit halber schreibt man HTML-Dateien mit Platzhaltern, die in geschweiften Klammen stehen, weil die sich mit preg_replace so schön einfach ersetzen lassen. Das Ganze packt man dann auch gleich in eine Klasse: Man sagt der Klasse, welche HTML-Datei sie laden soll und welche Platzhalter in dieser Datei durch welchen Text ersetzt werden sollen. Schon hat man seine eigene "Template Engine" erfunden. Ach halt, die TabelleSoweit so gut. Wir haben jetzt also eine PHP-Datei, die Benutzereingaben verarbeitet und Berechnungen durchführt, und dann bestimmte Texte den Platzhaltern zuweist, damit sie in die HTML-Seite eingebunden werden können. Doch schon ergibt sich das nächste Problem: Auf der Seite soll doch eine Tabelle stehen, und diese Tabelle hat ja nun ganz viele Zeilen, die sich immer wieder wiederholen. Wie soll man nun in diese HTML-Datei mit Platzhaltern eine Tabelle unterbringen? Soll man die Tabelle schon im PHP-Skript aufbereiten und dann dem Platzhalter {TABLE} zuweisen, den man in der Datei platziert hat? Doch halt! Dann müsste man ja doch wieder HTML-Code (<tr>!) im PHP-Skript benutzen. Eine extra Template-Datei für die Tabellenzeile? Die könnte man dann ganz oft laden und mit neuen Texten füllen, so dass man die Tabelle zeilenweise aufbauen kann. Aber irgendwie wäre das doch ineffizient und außerdem hat man dann auf Dauer ganz viele kleine Dateien rumliegen. Nein, am besten machen wir Markierungen in die Template-Dateien, die anzeigen, dass dieser Teil von {START} bis {END} beliebig oft wiederholt werden kann. ...und auch noch die PreisangabenToll. Das läuft ja wie am Schnürchen. Die Tabelle wird ausgegeben. Aber ganz super wäre noch, wenn die Preisangaben in der Tabelle unterschiedlich gefärbt wären: Einnahmen grün und Ausgaben rot, das würde die Übersichtlichkeit schon ziemlich erhöhen. Also schreiben wir einfach im PHP: Wenn Betrag kleiner null, dann mach ein CSS-Style namens "rot" um den Betrag und ansonsten ein Style namens "gruen". - Ach nein, wir wollten im PHP ja keinen HTML-Code mehr reinschreiben. Aber die Lösung ist ja naheliegend: Wir machen ins Template einfach eine Unterscheidung rein. Wenn die Bedingung erfüllt ist, dann wird alles von dem {IF} bis zum {ELSE} benutzt, und ansonsten alles vom {ELSE} bis zum {ENDIF} Saubere Arbeit!Klasse! Alles funktioniert. Das Problem ist nur: Unsere Templates enthalten jetzt nicht mehr einfache Platzhalter, sondern wir haben auch noch gleich eine Art von Schleifenmechanismus und eine Art von bedingter Ausführung eingeführt. Irgendwie ist das gar nicht mehr so richtig übersichtlich. Und irgendwie ist das immer noch nicht so richtig flexibel, weil eine Seitennavigation mit Unterordnern kriegen wir mit unserem Template-System noch gar nicht dargestellt. Oder man stelle sich nur diesen einfachen Fall vor: Je nach Sprache des Benutzers (übermittelt vom Browser) soll das Format des Datums mal in der Form "January, 1st 1983" und mal als "01. Jan. 1983" dargestellt werden. Selbst diese einfache logische Aufgabe stellt uns schon wieder vor komplexe Probleme. Jetzt kann man hergehen und auch das alles noch in seine Template-Sprache einbauen. Die Templates werden immer komplexer (und langsamer), aber wir haben ja ein Ziel: Mehr Üebrsichtlichkeit durch Trennung von PHP und HTML. Und dass kein PHP in den Templates steht - das kann ja wohl keiner bestreiten! Über den TellerrandGott sei Dank arbeiten wir ja nicht für Luft und Liebe, sondern für einen Chef. Der sagt uns nun, dass die Ausgabe der HTML-Seite nicht mehr reicht, sondern zusätzlich müssen die Daten auch als grafisches Diagramm abgerufen werden können. Irgendwie ist das ein Problem, denn unser PHP-Skript ist darauf doch gar nicht ausgelegt: Wie packen wir denn diese Tabelle jetzt in ein PNG? Unsere Templates helfen da definitiv nicht mehr weiter. Also wird ein komplett neues PHP-Skript begonnen, in dem nochmal alle Benutzereingaben entgegengenommen werden und nochmal Datenbankabfragen gemacht werden, um die selben Daten jetzt als PNG auszugeben. Irgendwie mischen wir da jetzt zwar PHP mit Grafikfunktionen der GD-Bibliothek, aber das ist ja eigentlich kein Problem, sowas KANN man gar nicht übersichtlich machen! Ist das jetzt unsere strukturierte Programmierung? Soll es tatsächlich so sein, dass man Codeteile kopieren muss, um sie noch einmal an anderer Stelle zu verwenden? Und was haben wir mit unserer Template-Engine jetzt eigentlich gewonnen? Ganz andersMan hätte natürlich auch von Anfang an auf den Quatsch mit der eigenen Template-Syntax verzichten können. Schließlich ist die PHP-Syntax <?= $platzhalter ?> auch recht übersichtlich. Hätten wir einfach das HTML in eine extra Datei ausgelagert, die wir mit "include" einbinden und in der diese PHP-Platzhalter stehen, das hätte wahrscheinlich genauso gut funktioniert. Und unser Kopf wäre frei gewesen, mal etwas mehr über das nachzudenken, was wir eigentlich tun. Dann wären wir vielleicht spätestens bei der Frage nach dem Diagramm auch darauf gekommen, dass wir es eigentlich mit drei Komponenten zu tun haben: (1) Wir müssen die Benutzereingaben auswerten, (2) wir müssen die Daten irgendwoher bekommen und (3) wir müssen das am Schluss irgendwie ausgeben. Egal, ob wir eine Tabelle oder ein Diagramm ausgeben: Die Auswertung der Benutzereingaben und die Daten sind ja eigentlich immer diesselben. Nur die Darstellung unterscheidet sich. Gottlob standen schlaue Köpfe bereits in den 1970ern vor sehr ähnlichen Problemen und haben dieses Problem mitsamt seiner Lösung formalisiert. Es ist heute allgemein als MVC-Pattern bekannt, das in verschiedenen Ausprägungen für verschiedene Anwendungsgebiete (Web, lokale Applikation, etc.) und Abstraktionsebenen existiert. Eine "Controller"-Komponente erledigt die Auswertung von Eingaben und das Besorgen der Daten für uns. Diese Daten werden in einem "Model" bereitgestellt, das wir immer wieder über eine wohldefinierte Schnittstelle auslesen können (im einfachsten Fall z.B. ein Array). Als letztes sorgt eine "View"-Komponente für die Darstellung, die völlig frei ist von der Datenbesorgung und -aufbereitung. Der View ist aber nicht frei von Programmcode, ganz im Gegenteil: Er entscheidet nämlich selbst, wie die Daten dargestellt werden sollen: Als Tabelle, rot oder grün, oder als Diagramm. Ganz nach Anforderung. | |
![]() |
![]() Links zum Thema (ohne Gewähr u. Haftung):
|
