Template Engine - Idee
-
Hallo!
Was haltet ihr von folgendem Design:
Es soll eine Template Engine werden, die eher auf statische Seiten ausgelegt ist, denn auf echt dynamische Seiten (wie zB dieses Forum).
Die meisten Seiten die ich entwickle sind nur leicht dynamisch. Es ist zwar zB immer ein anderer User eingeloggt, aber bis auf die paar angepassten Sachen wie Links zum Profil und die Anrede ist die Seite ja immer gleich.
Oder es ist eine Produktdatenbank - die Produkte werden zwar dynamisch geladen, sind aber immer die selben. Einzig die Anzahl der vorhandenen Exemplare ändert sich.
Da ich soetwas öfters entwickle, finde ich es natürlich Verschwendung jedesmal eine identische Seite neu zu genieren... Ganz statisch geht ja auch nicht, weil es 1) dynamische Elemente beinhaltet und 2) alle inhalte 'dynamisch' sind, weil sie sich ja doch ändern können.
Deshalb habe ich mir folgendes Design überlegt:
Es gibt sogenannte Content-Templates - in denen statische Texte aber auch PHP Code vorhanden sein kann. PHP wird nicht über <?php sondern per XML Tag: <dynamic> eingebunden. Hier kann man angeben, ob das Ergebnis des PHP Codes cachbar ist, wenn ja, von welchen Variablen es abhängt.
zB
<dynamic cache="lang">echo load_text($values['lang'], 'GREETING');</dynamic>
dies würde die Funktion load_text aufrufen und den passenden Text für 'GREETING' laden. Hierbei wird der Code für $values['lang'] gecacht. dh, wenn dieser PHP Code wiedereinmal ausgeführt wird, wird zuerst geschaut ob es für dieses 'lang' schon das gecachte ergebnis gibt. wenn ja, dann wird der code nicht ausgeführt.weiters beinhalten diese Content-Templates keinen HTML Code, sondern abstrakte Tags.
zB
<heading>Wichtiger Text</heading>
<par>bla bla bla</par>
<par>bla <keyword>foo</keyword> bla</par>in der ersten Stufe werden diese Content Templates quasi kompiliert und der PHP Code ausgeführt bzw. nicht ausgeführt (man kann ja nicht alles cachen).
In der zweiten Stufe wird die passende Visualisierung ausgeführt.
zB fügt die HTML Visualisierung noch ein Menü auf jeder Seite ein und wandelt die abstrakten Tags in konkrete HTML Tags um.Auch hierbei gilt: das ergebnis wird gecacht und kann genauso PHP Code nach ähnlichen richtlinien wie die Content-Templates enthalten.
Wichtig ist, dass der nicht gecachte PHP Code der Content-Templates direkt in die Visualisierungstemplates einfliesst. So dass nicht jedesmal das gesamte Content-Template transformiert werden muss, sondern nur der dynamische inhalt der PHP Codes.
das ergebnis wird natürlich auch wieder gecacht - so dass man am ende wirklich nur recht wenig PHP Code ausführen muss. Gleichzeitig ist es auch sehr leicht andere Visualisierung wie zB ein anderes HTML Theme oder auch PDF, XML, Flash output zu erzeugen.
Die Nachteile:
lange kompilierzeiten: von einem Content-Template zur Ausgabe an den Browser geht recht viel Zeit verloren, man muss also ähnlich wie bei ASP3 jede seite einzeln aufrufen... denn vorkompilieren geht nicht (bzw. man könnte ein script schreiben das anhand von daten die man händisch eingeben muss, einen teil der templates kompiliert) - desto länger das system aber läuft, desto bessere und mehr cache treffer gibt es.viel Speicherplatz: da alles sehr viel gecacht wird, hat man viele dateien.
als Vorteile sehe ich uA die erweiterbarkeit.
Dieses system kann man recht einfach um neue visualisierungen erweitern und das füttern der visualisierungstemplates ist nicht so mühsam wie zB mit smarty und anderen template engines. Denn der content ist vorhanden und bestimmt im prinzip selber seine form (durch die abstrakten tags)weiters ist eine indizierung für eine suche recht einfach - weil jedes content template mittels <keyword>foo</keyword> sich selber keywords geben kann.
was haltet ihr von diesem Design? Oder von der Idee allgemein?
gibt es verbesserungsvorschläge oder kritik?
-
Das Interface Deines Templatesystems finde ich gelinde gesagt etwas unpraktisch, die Idee mehrstufiger Template-Caches ist aber prinzipiell nicht schlecht.
Im Prinzip beschreibst Du da ja ein zwei-Stufensystem, nämlich einen Cache für die wirklich statischen Content-Elemente,bzw. für all die Content-Elemente wo alle möglichen Resultate schon bekannt sind, in dem dann die dynamischen Elemente als 2nd-stage-Cache eingebunden werden. Die Idee ist weder schlecht noch besonders neu, in Deiner Realisierung hast Du jedoch IMHO zum einen das Problem, daß Du Aussehen und Geschäftslogik noch zu sehr vermengst, und zum anderen das Problem, schlecht aufzulösender Abhängigkeiten (wie von Dir prinzipiell ja schon angesprochen).
Ich würde für sowas über zwei Dinge nochmal nachdenken:
- Ich würde versuchen ein Repository über alle dynamischen Inhalte inklusive ihrer Abhängigkeit zu generieren. Du kannst dann nämlich vollautomatisch Dein Template-Verzeichnis (oder welchen Lagerort Du auch immer wählst) durchgehen und die Daten weitestgehend vorkompilieren, und somit für jedes Template, welches andere Templates einbindet, komplette Abhängigkeitsinformationssätze verwalten. Das wäre dann sozusagen der 1st-Level-Cache, auf welchem der im zweiten Teil beschriebene 2nd-Level-Cache aufsetzt.
- Ich würde sehen, daß ich den PHP-Code aus den Templates rausziehe und eher mit Listener-Klassen arbeite. Ein Listener könnte dann komplett selbst verwalten, von welchen Informationstypen seine Caching-Fähigkeiten abhängen, und oft sogar schon alle möglichen Belegungen angeben. Wenn Du diese Struktur mit einer vernünftigen Abhängigkeitshierarchie verknüpfst, dann kann ein solcher Listener sein komplettes Caching selbst verwalten. Dann müßtest Du nämlich in Deinen Templates nur noch sagen, daß irgendwo das Dynamische Element X eingebunden werden soll, und in Abhängigkeit dessen geht der Listener an die Arbeit, schaut nach, ob zum aktuellen Applikationszustand schon ein gecachetes (gibts dafür eigentlich ein passendes Deutsches Wort?) Objekt im Reppository ist, und liefert dieses aus, existiert noch keines, so wird eines generiert, und das ganze abgelegt. Ausserdem kann ein solcher Listener alle abhängigen Dynamischen Elemente angeben, und somit selbst die Cache-Verwaltung anderer Listener benutzen.
Daraus ergibt sich dann im 1st-Level-Cache z.B. eine Menge von Grobtemplates für alle Sprachen, inklusive alle Länderabhängigen Optischen Komponenten, wo dann nur noch die dynamischen Komponenten aus dem 2nd-Level-Cache eingebunden werden müssen, wobei intern quais rekursiv gecachete dynamische Komponenten aus dem 2nd-Level-Cache benutzt werden. Mit der Zeit tariert sich das ganze dann so aus, daß sich die Template-Sätze im 1st-Level-Cache immer stärker vermehren, und die Anzahl der Elemente im 2nd-Level-Cache immer kleiner wird. Zusätzlich bietet dieser Ansatz noch den Vorteil, daß ein großer Anteil der 1st-Level-Cache-Elemente vorkompiliert werden kann, ohne das groß Handarbeit von Nöten wäre.
Gruß Jens
-
Sa(n)dman schrieb:
Die Idee ist weder schlecht noch besonders neu
Kennst du eine PHP Engine die das so macht? Ich habe noch keine gefunden
Ich würde versuchen ein Repository über alle dynamischen Inhalte inklusive ihrer Abhängigkeit zu generieren.
Allerdings habe ich zB ein Menü wenn ich nach HTML ausgebe - aber bei PDF hätte ich ein Inhaltsverzeichnis...
Deshalb denke ich, dass die Templates sich untereinander nicht wirklich kennen müssen - da das ja die Visualisierung übernehmen sollte.
Ich würde sehen, daß ich den PHP-Code aus den Templates rausziehe und eher mit Listener-Klassen arbeite.
Was genau verstehst du darunter?
zB eine Komponente UserOnline welche von Komponente X abhängt und sich selbst als '<foo>Member Online: <c>$member</c></foo>' ausgibt?Sowas klingt interessant...
Allerdings müsste man dann für jeden Code so eine Komponente schreiben...
allerdings wäre das auf Tags bezogen recht interessant. Man könnte jeden Tag als Komponente sehen und jeder Tag transformiert sich dann je Visualisierung in den passenden ausgabe code...Daraus ergibt sich dann im 1st-Level-Cache z.B. eine Menge von Grobtemplates für alle Sprachen, inklusive alle Länderabhängigen Optischen Komponenten, wo dann nur noch die dynamischen Komponenten aus dem 2nd-Level-Cache eingebunden werden müssen, wobei intern quais rekursiv gecachete dynamische Komponenten aus dem 2nd-Level-Cache benutzt werden.
Yeah!
Das was du gesagt hast klingt super. Hast du so ein System schonmal selber geschrieben?
-
Shade Of Mine schrieb:
Sa(n)dman schrieb:
Die Idee ist weder schlecht noch besonders neu
Kennst du eine PHP Engine die das so macht? Ich habe noch keine gefunden
Ich hab mal gelesen, das Smarty Template das können müsste.
http://smarty.php.net/
-
2oopuls schrieb:
Ich hab mal gelesen, das Smarty Template das können müsste.
http://smarty.php.net/inwiefern kann smarty das?
ich verwende smarty eigentlich schon länger, aber das ist mir noch nie aufgefallen. abgesehen davon, dass ich mit der fütterung der smarty templates (also content in die templates zu bringen) nicht ganz glücklich bin
-
Ich hab smarty noch nie verwendet. Ich dachte nur das es eine Cache-Funktion
haben müsste, so wie du sie beschrieben hast. Mir ist smarty nur mal so über
den Weg geflogen.
-
Das Problem was Du hast ist mir bestens bekannt!
Ich habe auch schon einige Stunden damit verbracht, eine sinnvolle Lösung zu finden. Bei mir ist das Problem ähnlich. Die große Schwierigkeit die ich dabei sehe ist eher die Ausführungsgeschwindigkeit. Handelt es sich nur wenige dynamische Werte, dann kann man durchaus mit Hilfe von Smarty ein recht performantes Caching System entwickeln.
Kann sich aber bei jedem Besucher sehr viel ändern, z. B. mehrere Sprachen/unterschiedliche Navigation/versch. Blöcke, dann habe ich leider keine saubere _und_ schnelle Lösung gefunden.
Das mit den verschiedenen Caches ist mir auch als erstes in den Sinn gekommen. Allerdings musste ich sehr schnell feststellen, dass dieses bei vielen Abhängigkeiten in einer wilden Inkluderei endet. Am Ende ist es vielleicht sogar langsamer, als eine kleine schnelle Template Engine.
Greets
PS: Willst Du evt. ein bischen mehr zu Deinem Problem erzählen? Vielleicht finden wir ja doch noch eine geniale Möglichkeit.
-
Shade Of Mine schrieb:
Deshalb denke ich, dass die Templates sich untereinander nicht wirklich kennen müssen - da das ja die Visualisierung übernehmen sollte.
Doch, zumindestens die Template-Bereiche, die von einem Template eingebunden werden, müssen dem übergeordneten Template bekannt sein. Ansonsten kannst Du nicht bestimmen, von welchen Informationen das übergeordnete Template abhängt und somit nicht vernünftig cachen.
Shade Of Mine schrieb:
Was genau verstehst du darunter?
zB eine Komponente UserOnline welche von Komponente X abhängt und sich selbst als '<foo>Member Online: <c>$member</c></foo>' ausgibt?Sowas klingt interessant...
Allerdings müsste man dann für jeden Code so eine Komponente schreiben...
allerdings wäre das auf Tags bezogen recht interessant. Man könnte jeden Tag als Komponente sehen und jeder Tag transformiert sich dann je Visualisierung in den passenden ausgabe code...Im wesentlichen ging es genau in die Richtung. Listener war da aber vielleicht das falsche Wort, "Content-Container" oder sowas wäre da vielleicht passender gewesen.
Shade Of Mine schrieb:
Yeah!
Das was du gesagt hast klingt super. Hast du so ein System schonmal selber geschrieben?
Vollständig nicht, ich war allerdings mal in einem Projekt involviert, wo wir sowas ausgiebigst diskutiert, und im Ansatz auch implementiert haben. Das Problem bei dem Projekt war allerdings, daß da ein paar Technik-Freaks zusammengetroffen sind, die alles besonders gut machen wollten, und darüber die Realisierbarkeit im verfügbaren Zeitrahmen vergessen haben. Wir haben da das ganze Spiel noch ein bißchen weiter gesponnen, und auf das ganze oben drauf noch einen Etag-Cache und eine komplette HTTP/1.1-Cache-Header-Verwaltung setzen wollen. (+ die ganzen anderen Gimmicks, auf die man in den anhängenden Bereichen so kommen konnte.) Letztendlich ist das Projekt daran gestorben.
Gruß Jens
[EDIT] Denkfehler meinerseits korrigiert[/EDIT]