Templates
Jürgen
- programmiertechnik
0 Gerhard Knabe0 Jürgen0 Gerhard Knabe0 Jürgen
0 Gerhard Knabe0 Jürgen0 Gerhard Knabe0 Jürgen
0 Udo
Hallo,
ich versuche gerade, mir ein eigenes Templatesystem zu stricken. Nichts Aufregendes, es ist für eine Website, die aus maximal fünf Seiten besteht. Ich möchte auf kein bestehendes System zurückgreifen, weil ich es als eine Herausforderung begreife, es selbst zu programmieren. Das Ziel des Templatesystems ist die Trennung von Programmcode und Ausgabe und zentrale Speicherung immer gleicher Ausgaben.
Ich habe bisher folgendes realisiert: ein zentrales Template, das HTML-Gerippe und allgemeines Layout beinhaltet. Ich nenne es mal im Beispiel allgemein.tpl. Das Template sieht, hier vereinfacht, so aus:
<html>
<head>
<title>##titel##</title>
</head>
<body>
[eine Linkleiste, fest eingebaut]
<h1>##titel##</h1>
##content##
</body>
</html>
Ich habe im Beispiel das Layout weggelassen, damit es nicht zu unübersichtlich wird. ##...## sind die Bereiche, die ersetzt werden. Das geschieht, indem per URL ein PHP-Skript aufgerufen wird, das sich die allgemein.tpl schnappt, die zu ersetzenden Bereiche austauscht und anschließend die fertige Seite ausgibt. Für die zu ersetzenden Bereiche habe ich weitere Templates angefertigt. Wird beispielsweise eine Datei links.php aufgerufen, gibt es noch ein Template links.tpl. Das könnte so aussehen:
Link 1<br />
Link 2<br />
Dieser Inhalt wird an der Stelle ##content## eingefügt.
Soweit funktioniert das ganz gut. Nun gibt es aber einige Situationen, für die ich nicht weiß, ob meine Herangehensweise sinnvoll ist.
1. Resourcen, die unterschiedliche Ausgaben, basierend auf verschiedenen Templates, erzeugen. Als fiktives Beispiel ein Gästebuch, das einmal eine Eingabemaske ausgibt, im zweiten Fall die Einträge, letztens vielleicht den Adminbereich. Ich habe das bisher so gelöst, drei Templates zu erstellen (gb_0, gb_1, gb_2) und anhand des Querys das richtige Template einzubinden. Ein Aufruf gb.php?seite=1 würde dann die Einträge zeigen.
Dazu ist meine Frage, ob ich auf dem richtigen Weg mit dieser Lösung (drei Templates) bin.
2. Das Gästebuchbeispiel eignet sich auch gut zur Veranschaulichung eines weiteren Problems. Angenommen, auf der Gästebuchseite soll außer der in allgemein.tpl fixierten Linkleiste eine weitere zum Aufruf der drei "Unterseiten" ausgegeben werden, und zwar zwischen [eine Linkleiste, fest eingebaut] und <h1>##titel##</h1>. Das führt zunächst zu einem nicht zu umgehenden Problem, weil das in allgemein.tpl nicht vorgesehen ist. Sicherlich könnte man für diesen Spezialfall per PHP nach [eine Linkleiste, fest eingebaut] die weitere Linkleiste einsetzen, indem man [eine Linkleiste, fest eingebaut] abfragt und dahinter den zusätzlichen Inhalt einsetzt. Das ist aber kein sinnvoller Weg, weil sich [eine Linkleiste, fest eingebaut] ändern kann und das Skript dann angepaßt werden müßte.
Meine Idee, das zu umgehen, ist, den Bereich zwischen <body> und <h1>##titel##</h1> schon selbst als austauschbaren Bereich anzugeben und an dieser Stelle ein weiteres Template einzufügen, etwa so
<body>
##menueleisten##
<h1>##titel##</h1>
Programmiertechnisch ist das kein Problem, aber ich weiß nicht, ob das so sinnvoll ist. In Artikeln zu Templates wird als ein Grund für deren Einsatz die Trennung von Programmierung und Ausgabe genannt, damit unterschiedlich ausgebildete Personen, also Programmierer und Designer, sich nur mit ihrem Gebiet befassen können. Das klingt plausibel, nur kann der Designer bei der Zerstückelung einer Seite in hundert Templates die Seite nicht mehr am Stück bearbeiten, sondern nur noch die einzelnen Templates, die für sich genommen keinen Eindruck vom Gesamtergebnis geben.
3. Noch einmal das Gästebuchbeispiel für das Problem "dynamischer" Templates. Das Template für die Unterseite mit den Gästebuchausgaben könnte so aussehen
##name## schrieb am ##datum##:<br />
##eintrag##
Das Skript gb.php schreibt in einer Schleife die Einträge mit dem Format von diesem Template in die Endfassung der auszugebenden Seite. Das sieht hier noch einfach aus, aber wenn fallweise Unterscheidungen hinzukommen
##name## mit der E-Mail ##mail## schrieb am ##datum##:<br />
##eintrag##
wird es schon komplizierter. Wenn "mit der E-Mail ##mail##" nur bei Vorhandensein einer E-Mail ausgegeben werden soll, muß dieser Bereich auch wieder variabel gehalten werden. Am einfachsten ginge das, wenn das Template so aussieht
##name## ##mail## schrieb am ##datum##:<br />
##eintrag##
und das Skript ##mail## ersetzt mit "mit der E-Mail" und der Adresse. Damit ist aber wieder eine Ausgabe innerhalb der Programmlogik, und der Designer hat beim Bearbeiten das Endergebnis nicht vor Augen. Es ginge sicherlich auch sowas
##name## ##??mail??=mit der E-Mail## ##mail## schrieb am ##datum##:<br />
##eintrag##
was bei Vorhandensein einer E-Mail-Adresse ##??mail??=mit der E-Mail## zu "mit der E-Mail" ersetzt, ansonsten löscht, aber damit hat der Designer bei der Bearbeitung des Templates eine Ansicht des Templates, die sich gehörig vom Endergebnis unterscheidet.
4. Auch ein Problem: Wenn das Template so aussieht
##name## ##??mail??=mit der E-Mail## ##mail## schrieb am ##datum##:<br />
##eintrag##
würde man nur einen Eintrag ausgeben können. Also muß eine Schleife innerhalb eines Skripts Ausgaben übernehmen. Eine Idee wäre in dem Template nur
##gaestebucheintraege##
zu vermerken und für die Schleife ein weiteres Template der Form
##name## ##??mail??=mit der E-Mail## ##mail## schrieb am ##datum##:<br />
##eintrag##
mit dem die Ausgaben zusammengesetzt und am Ende an die Stelle ##gaestebucheintraege## geschrieben werden. Wie auch immer man löst, das Problem ist das gleiche wie oben, die endgültige Seite zerstückelt sich in tausend Fragmente, eine klare Trennung von Logik und Ausgabe ist selbst im Template nicht gegeben - z. B. die bedingte Ausgabe ##??mail??=mit der E-Mail##.
Deshalb weiß ich nicht, ob mein Ansatz zu einem Templatesystem im Kern richtig ist oder ob ich damit in einer Sackgasse lande. Gibt es vielleicht irgendwo im Netz gute Tutorials, die den Aufbau eines Templatesystems von der Pike auf erklären?
Templates ganz ohne "Programmlogik" sind zu unflexibel, um brauchbar zu sein. Notwendig sind z.B. Mechanismen, die auf die Existenz von bestimmten Daten (z.B. einer email Adresse) reagieren oder auch Tabellen aus Arrays erzeugen können, also wie auch immer geartete Bedingungen und Schleifen. Die Frage ist nur, wie weit man dabei geht. Um zu vermeiden, dass letztenendes in einem Template dann doch wieder "programmiert" wird, muss es einen Weg vom Template zurück in Code geben, damit die Funktionalität, die mit einer deklarativen Syntax wie der eines Templates nicht (oder nur schwer) abbilddbar ist trotzdem realisiert werden kann. Ich habe das Problem dadurch gelöst, dass ich in Templates die Verwendung von "Steuerelementen" zulasse, welche durch Code realisiert werden. Deren Ausgabe kann (muss aber nicht) selbst durch ein Template implementiert werden. Dadurch ist auch eine Verschachtelung und sogar Rekursion auf Basis von Templates möglich, ohne dass der Ersteller der Templates Programmierarbeit leisten muss (entsprechende Steuerelemente vorausgesetzt). Gleichzeitig bieten die Steuerelemente in sich abgeschlossene Funktionalität in Form einer verwendbaren Komponente an. Das Aussehen der Steuerlemente kann durch Ändern der von ihnen verwendeten Templates beeinflusst werden, ohne dadurch ihre Funktion zu stören, da diese in Code realisiert ist.
Ich hoffe, Dir einige Anregungegen gegeben zu haben, auch wenn ich nicht konkret auf die von Dir genannten Punkte eingegangen bin.
MfG
GK
Templates ganz ohne "Programmlogik" sind zu unflexibel, um brauchbar zu sein.
Eine Alternative wäre vielleicht ein Template, das rein "statische" Platzhalter enthält, und eine weitere Steuerdatei, die Logik für die Platzhalter enthält.
Notwendig sind z.B. Mechanismen, die auf die Existenz von bestimmten Daten (z.B. einer email Adresse) reagieren oder auch Tabellen aus Arrays erzeugen können, also wie auch immer geartete Bedingungen und Schleifen.
Also bin ich auf dem richtigen Weg? "Statische" Platzhalter, Bedingungen und Schleifen im Template?
Um zu vermeiden, dass letztenendes in einem Template dann doch wieder "programmiert" wird, muss es einen Weg vom Template zurück in Code geben, damit die Funktionalität, die mit einer deklarativen Syntax wie der eines Templates nicht (oder nur schwer) abbilddbar ist trotzdem realisiert werden kann. Ich habe das Problem dadurch gelöst, dass ich in Templates die Verwendung von "Steuerelementen" zulasse, welche durch Code realisiert werden.
Kannst Du das explizieren?
Das Problem ist also, wenn ich das so richtig sehe, der Designer muß Steueranweisungen erlernen und er hat beim Layouten/ Desginen der Seiten die Steueranweisungen ständig vor Augen? Und weiterhin läßt es sich auch nicht vermeiden, eine Seite aus verschiedenen Templates zusammensetzen zu müssen?
Also die "Steueranweisungen" sind bei mir recht einfach gestrickt. Meine Templates sind XML-Dateien. Es existieren Bedingte Anweisung folgender Form
<if condition='...'>
...
<elseif condition='...' />
...
<else />
..
</if>
wobei als Bedingungen im Wesentlichen nur die Prüfung auf Existenz eines Datenelementes möglich ist, also keine Ausdrücke, Funktionsaufrufe oder dergleichen.
"Schleifen" über Felder können wiefolgt realisiert werden:
<foreach path='...'>
...
</foreach>
Innerhalb aller Tags sowie deren Body kann über {Pfad} auf die dem Template zur Formatierung übergebenen Daten zugegriffen werden, wobei {Pfad} einen Navigationspfad innerhalb einer durch die Daten definierten Objekthirarchie darstellt. Ein Ausschnitt aus einem Template für eine Bildergalerie sieht z.B. so aus:
<foreach path='{Imagegroups}'>
<tr>
<td style='background-color:transparent;'><a href='javascript:Application.TriggerEvent('{Path}','Click({.Guid})',null);'>{.Description}</a></td>
</tr>
</foreach>
Die Datenstruktur ist ein Objekt. Dieses hat eine Eigenschaft Imagegroups, auf die im Pfad {Imagegroups} innerhalb des foreach-Tags Bezug genommen wird. Die Eigenschaft Imagegroups enthält ein Feld von Objekten (in diesem Fall vom Typ Imagegroup). Durch das foreach-Konstrukt werden all diese Objekte durchlaufen. Jedes Imagegroup-Objekt verfügt über die Eigenschaft Description, auf die sich der Pfad {.Description} bezieht. Der Punkt am Anfang des Pfades zeigt an, dass die Navigation nicht von der Wurzel aus erfolgen soll, sondern vom derzeit innersten iterierten Element. Geschachtelte foreach-Konstrukte sind ebenfalls möglich. Auf die äußeren Elemente könnte man über den Pfad {Outer} und auf die Elternelemente eines Pfades über {.Parent} sowie auf die Elemente selbst über {this} zugreifen. Eine genaue Darstellung der Funktionsweise würde den Rahmen dieses Postings sprengen. Falls Du aber spezielle Fragen hast, will ich gerne versuchen, diese zu beantworten. Die von mir gewählten Konstrukte sollten zwar ausreichend Flexibilität bieten, um nicht jede Kleinigkeit als Steuerelement realisieren zu müssen, denn dann wären Templates unnötig, aber dennoch so einfach sein, dass für den Designer keine besonderen Programmierkenntnisse erforderlich sind.
Die Anbindung an Steuerlemente sieht bei mir so aus (gleiches Beispiel wie oben):
<control control='Master' Template='{2EE96BCB-E8EC-0BD9-C5CC-AEBFFCF7EEE6}'>
<ActiveNode>{C7617FAA-04CC-75B5-9C07-779008D3A626}</ActiveNode>
<Content type='string'> </Content>
<SidePanel type='string'>
<table style='width:180px;padding:0 0 0 0px;margin:0;background-color:#000018;border-collapse:collapse;'>
<tr>
<th>Bildergalerie</th>
</tr>
<foreach path='{Imagegroups}'>
<tr>
<td style='background-color:transparent;'><a href='javascript:Application.TriggerEvent('{Path}','Click({.Guid})',null);'>{.Description}</a></td>
</tr>
</foreach>
<tr>
<td style='height:100%;background-color:transparent;' />
</tr>
</table>
</SidePanel>
</control>
Hier wird ein Steuerlement vom Typ "Master" erzeugt und den Eigenschaften Template, ActiveNode, Content und SidePanel Werte zugewiesen. Natürlich muss der Designer wissen, wie er mit dem Steuerelement umzugehen hat. Aber das ist nicht wesentlich schwerer als zu verstehen, wie man eine HTML-Tabelle aufbaut. Das "Master" Steuerelement realisiert das Konzept einer Masterseite, also eine zentrale Struktur für alle Seiten einer Webpräsenz. In diesem Fall ist es dreispaltig: Navigationsleiste, Content und eine rechte Spalte (das SidePanel). Die Eigenschaft Template enthält in diesem Fall den Primärschlüssel eines Datensatzes einer DB, die das entsprechende Template enthält. Die Eigenschaft ActiveNode identifiziert den zu aktivierenden Navigationspunkt in der Navi-Leiste. Die Eigenschaften Content und SidePanel enthalten den HTML-Code für die entsprechenden Bereiche des Layouts.
Das Template der Masterseite sieht so aus:
<table style='width:904px;height:100%;margin:0;padding:0;background-color:transparent;border-collapse:collapse;'>
<tr>
<td colspan='3' style='width:904px;height:90px;padding:0;margin:0;background-image:url(images/backgrounds/title.gif);' />
</tr>
<tr>
<td style='width:181px;height:100%;background-color:#000018;padding:0;margin:0;'>
<control Name='Navigation' control='Treeview' style='width:100%;' Root='{F181CD2E-4680-2D18-FAA9-7C915528B71E}'>
<ShowRoot>false</ShowRoot>
<ActiveNode>{ActiveNode}</ActiveNode>
</control>
</td>
<td rowspan='2' style='width:542px;padding:0;margin:0;text-align:center;background-color:#1A1A33;'>
<div style='width:100%;padding:0;margin:0;background-color:transparent;overflow:visible;'>
{Content}
</div>
</td>
<td rowspan='2' style='width:180px;padding:0 0 0 1px;margin:0;text-align:center;background-color:#000018;'>
{SidePanel}
</td>
</tr>
</table>
In diesem Template wird über die Pfade {Content} und {SidePanel} auf die durch das obere Template zugewiesenen Eigenschaften zugegriffen. Die Navigationsleiste wird als Treeview-Steuerelement erstellt. Die Knoten des baumes kommen aus einer Datenbank. Der Primärschlüssen der Wurzel wird durch die Eigenschaft Root festgelegt, der aktive Knoten durch ActiveNode. Alle Seiten werden über diese Konstruktion auf Basis des Master-Templates aufgebaut, so dass ein einheitliches Layout für alle Seiten durch das Mastertemplate gewährleistet ist.
Du wunderst dich möglicherweise wie denn nun ein gültiges HTML-Dokument zustande kommt, also mit html,head und body Tags. Ich betrachte alle Templates als Komponenten, die überall verwendet werden können. Um komplette HTML-Dokuemnte zu erzeugen verwende ich ein anderes Konzept. Grund hierfür ist auch, dass Steuerelemente ggf. Skriptcode und Stylesheets erfordern, die auf geeignete Weise mit in das HTML-Dokument intergriert werden müssen. Prinzipiell spricht aber nichts dagegen, über das Mastertemplate ein komplettes HTML-Dokument zu erstellen. Solltest Du an den weiteren Konzepten ineressiert sein, würde ich allerdings eine weitere Kommunikation per email vorschlagen. Das ist etwas umfangreicher. Auch brauche ich Zeit, um die Darstellung so zu formulieren, dass sie verständlich ist. Ich hab' mir schon für dieses Posting einen abgebrochen, das einigermassen verständlich zu beschreiben, hoffentlich mit ein wenig Erfolg.
MfG
GK
Hallo Gerhard,
ich habe Dein Posting mal eben überflogen. Da das ein recht ausgefeiltes Konzept ist, kann ich nicht ad hoc darauf antworten. Ich werde es mal versuchen nachzuvollziehen, was aber angesichts der Komplexität etwas dauern kann (sofern es mir überhaupt gelingt, die Struktur einigermaßen zu erfassen). Kann also sein, daß ich heute nicht mehr antworte.
Vorab schon mal Danke.
Noch ein Nachtrag zum Thema "Mehrere Templates für eine Seite".
Natürlich ist es möglich, eine Seite mit genau einem Template zu erzeugen. Die Frage ist allerdings, ob das sinnvoll ist, denn Änderungen, die z.B. das Layout der Webpräsenz betreffen müssen dann in allen Templates nachgepflegt werden, wenn Du z.B. eine Kopf- oder Fusszeile einfügen willst, die es vorher nicht gab, oder Du willst von einer vertikalen auf eine horizontale Navigation wechseln. Man kann da zwar einiges mit CSS machen, aber das hat auch seine Grenzen.
Der Einsatz von Templates gibt dir zwar die Möglichkeit, die Seiten in (möglichst logisch strukturierte) Teile zu zerlegen, ein solches Vorgehen wird aber weder erzwungen, noch wird dadurch bestimmt, wie Du eine solche Aufteilung vornimmst.
Ich halte es durchaus für sinnvoll, bei einer Seite die aus Kopfzeile, Navigation und Seiteninhalt besteht diese drei Elemente und ihre Komposition getrennt voneinander gestalten zu können, aber natürlich muss man das nicht so machen.
MfG
GK
Noch ein Nachtrag zum Thema "Mehrere Templates für eine Seite".
Natürlich ist es möglich, eine Seite mit genau einem Template zu erzeugen. Die Frage ist allerdings, ob das sinnvoll ist, denn Änderungen, die z.B. das Layout der Webpräsenz betreffen müssen dann in allen Templates nachgepflegt werden,
Wenn ich Dich richtig verstehe, meinst Du, zu jeder HTML-Seite wird ein identisches Template abgelegt. Habe ich 30 Seiten, sind auch 30 identische Template hinterlegt, die bei einer Änderung am Layout allesamt geändert werden müssen. Na ja, wenn ich das richtig verstanden habe, trennt das zwar Programmlogik von Ausgabe, aber der eigentliche Vorteil von Templates = Schablonen ist damit aufgehoben. Eine Schablone soll ja dazu dienen, mit genau einer Schablone beliebig viele Seiten zu erstellen.
Ich halte es durchaus für sinnvoll, bei einer Seite die aus Kopfzeile, Navigation und Seiteninhalt besteht diese drei Elemente und ihre Komposition getrennt voneinander gestalten zu können, aber natürlich muss man das nicht so machen.
MfG
GK
Oder sogar unter Umständen noch mehr Templates für eine HTML-Seite. Im konkreten Fall, mit dem ich mich beschäftige, habe ich eine Masterschablone, in der es ein horizontales Menü gibt. Danach folgt der Inhalt, ähnlich wie schon in meinen Beispielen. Für zwei Seiten aber wird diese Struktur durchbrochen. Diese Seiten haben "Unterseiten", oder wie man das nennen will. Anhand des Querystrings wird dem Skript mitgeteilt, welche Unterseite angezeigt werden soll. Um die Unterseiten zu erreichen, müssen die Links unterhalb der Hauptnavigation ausgegeben werden (Seite 1, Seite 2 usw.), also zwischen Hauptnavi und eigentlichem Inhalt, was aber so zunächst nicht im Mastertemplate vorgesehen war. Deshalb werde ich jetzt wohl in dem Mastertemplate einen Platzhalter für die Navigation setzen müssen, der mit einem weiteren Template befüllt wird, im Fall der Seiten mit Unterseiten mit noch einem zusätzlichen Template. Ich hoffe, ich habe mich einigermaßen verständlich ausgedrückt.
Nur, wie schon gesagt, kann der Designer dann nur noch mit Fragmenten arbeiten. Einzig denkbar wäre, es wird zuerst eine HTML-Datei erstellt, die erst anschließend in die Einzeltemplates fragmentiert wird, erst hin zum Mastertemplate, das weiter in seine Einzelbestandteile zerlegt wird. Diese Schritte könnte dann der Designer oder auch der Programmierer erledigen.
Na ja, wenn ich das richtig verstanden habe, trennt das zwar
Programmlogik von Ausgabe, aber der eigentliche Vorteil von
Templates Schablonen ist damit aufgehoben. Eine Schablone soll ja
dazu dienen, mit genau einer Schablone beliebig viele Seiten zu
erstellen.
Nicht unbedingt. Wenn ich auf einer Webpräsenz z.B. eine Bildergalerie, einen Newsticker und ein Gästebuch anbiete, so können das durchaus 30 Seiten sein, ggf. sogar viel mehr, wenn die Inhalte z.B. des Newstickers mit angegliedertem Archiv über mehere Seiten verteilt werden, um den Bensucher nicht mit einer Seite und hunderten von Beiträgen zu überschwemmen. Ich nehme mal an, Du willst nicht mit einer einzigen Schablone sowohl Newsticker als auch Gästebuch und Bildergalerie abdecken.
Ich sehe das dann so: Die Masterschablone legt das Layout aller Seiten fest, sozusagen eine Meta-Formatierung. Das Gästebuch, der Newsticker und die Bildergalerie haben dann ihrerseits eigene Schablonen, mit denen sie die von ihnen generierten Daten formatieren. Wenn etwa in einer Bildergalerie mehrere 1000 Bilder verfügbar sind, wird man die wohl kaum alle gleichzeitig anzeigen (ähnlich wie beim Archiv eines Newstickers), nichtmal als Thumbnail. Entweder werden die Bilder kategorisiert oder aber auf mehrere Seiten verteilt (oder beides), dann mit einer "nächste Seite" und "vorherige Seite" Navigation. Für diese Seiten ist natürlich nur eine Schablone notwendig, da alle Daten die gleiche Struktur haben. Die Schablonen beschreiben, wie Daten einer bestimmten Struktur zu formatieren sind. Welche Inhalte die Daten konkret haben (also ob die Eigenschaft Name nun "Wilfried Müller" oder "Rosalinde Schneider" enthält) ist dabei ja nicht relevant, sondern nur wie die Daten strukturiert sind. Die Datenstruktur stellt sozusagen die Schnittstelle einer Schablone dar. Eine Schablone zur Anzeige des Gästebuches benötigt andere Daten, als eine Schablone zur Anzeige einer Bildergalerie, hat also eine andere Schnittstelle.
Für den Designer hat das durchaus Vorteile, da er sich z.B. auf die Gestaltung des Gästebuches konzentieren kann ohne dabei die Navigationsleiste berücksichtigen zu müssen. Bei der Gestaltung der Masterschablone muss er sich Gedanken darüber machen, wie die Elemente (z.B. Kopf, Navigation und Seiteninhalt) zusammen präsentiert werden sollen, ohne die Gestaltungsprobleme dieser Teile bereits vollständig gelöst zu haben. Natürlich bestehen da Abhängigkeiten, wenn z.B. die Bilder der Bildergalerie in einer Breite präsentiert werden soll, für die die Größe des entsprechenden Elements der Masterschablone nicht ausreicht. Das ist aber bei OOP nicht anders. Beim Zusammenführen von unabhängigen Klassen zu einer komplexeren Struktur muss man ja auch die Eigenschaften, Schnittstellen und Verantwortlichkeiten der einzelnen Klassen berücksichtigen. Trotzdem wird versucht, die Abhängigkeiten der Klassen untereinander zu minimieren, damit der Code leichter durchschaubar und wartbar wird (Änderungen haben weniger Seiteneffekte, sind lokal). Warum sollten solche Prinzipien beim Design von Webseiten nicht auch nützlich sein?
Der Grund für den Einsatz von Schablonen ist ja nicht, viele Daten damit zu formatieren, denn das könnte man auch mit Code tun, sondern Code, Daten und Formatierung voneinender zu trennen um Änderungen mit möglichst wenig Aufwand (und ohne Programmierkenntnisse) durchführen zu können. Bei wenigen komplexen Schablonen ist ein solcher Änderungsaufwand aber viel größer als bei einer (sinnvollen!) Unterteilung in mehrere kleinere Schablonen. Natürlich kann man das auch übertreiben. Vor dem falschen Einsatz von Techniken schützt einen aber niemand, da muss man halt nachdenken, was sinnvoll ist. Wenn ich etwa das Gästebuch umgestalten will, dann ist mir eine Schablone, die nur das Gästebuch enthält entschieden lieber als eine, die die ganze HTML-Seite formatiert, inkl. Kopfzeile und Navigation. Diese Elemente machen die Schablone nur unübersichtlich und sind in dem Moment nicht von Interesse. Sinnvoll strukturierte und zusammengesetzte Schablonen konzentrieren die Aufmerksamkeit auf das Wesentliche.
Aber wie ich schon schrieb: Das Konzept erzwingt ein solches Vorgehen nicht, man kann es eben auch anders machen. Ich glaube aber, Schablonen haben mehr Potential als man in dem Fall nutzen würde.
MfG
GK
Hallo,
ich habe mich mißverständlich ausgedrückt. Der Satz "Eine Schablone soll ja dazu dienen, mit genau einer Schablone beliebig viele Seiten zu erstellen." sollte in dem Kontext nicht ausdrücken, daß lediglich eine Schablone angefertigt wird, sondern daß jede Schablone mehrfach verwendbar ist. Das ist der Zweck jeder Schablone. Wenn die Schablone lediglich dazu dienen soll, Logik und Ausgabe zu trennen, finde ich den Begriff nicht passend. Bei Unter- oder Nebenschablonen kann man das auch weniger eng sehen. Wenn es eine Masterschablone gibt, die sich auf (fast) allen Seiten wiederfindet und zusätzliche "Schablonen", die für jede Seite spezifisch angelegt werden, kann man diese Nebenschablonen, die nur ein einziges Mal Verwendung finden, meinetwegen auch als Schablone bezeichnen, auch wenn sie das im eigentlichen Sinn nicht mehr sind.
Im Prinzip habe ich es bisher schon so realisiert, daß es eine Masterschablone gibt und jede Seite eine weitere eigene hat. Das muß nicht so sein, nur bei mir sind bei der betroffenen Site die Seiten alle unterschiedlich, weswegen das nötig war.
Bisher sah ich es erst mal als Problem, wenn sich die Seiten in einzelne Schablonen zersplittern, aber das
Für den Designer hat das durchaus Vorteile, da er sich z.B. auf die Gestaltung des Gästebuches konzentieren kann ohne dabei die Navigationsleiste berücksichtigen zu müssen. Bei der Gestaltung der Masterschablone muss er sich Gedanken darüber machen, wie die Elemente (z.B. Kopf, Navigation und Seiteninhalt) zusammen präsentiert werden sollen, ohne die Gestaltungsprobleme dieser Teile bereits vollständig gelöst zu haben. Natürlich bestehen da Abhängigkeiten, wenn z.B. die Bilder der Bildergalerie in einer Breite präsentiert werden soll, für die die Größe des entsprechenden Elements der Masterschablone nicht ausreicht. Das ist aber bei OOP nicht anders. Beim Zusammenführen von unabhängigen Klassen zu einer komplexeren Struktur muss man ja auch die Eigenschaften, Schnittstellen und Verantwortlichkeiten der einzelnen Klassen berücksichtigen. Trotzdem wird versucht, die Abhängigkeiten der Klassen untereinander zu minimieren, damit der Code leichter durchschaubar und wartbar wird (Änderungen haben weniger Seiteneffekte, sind lokal). Warum sollten solche Prinzipien beim Design von Webseiten nicht auch nützlich sein?
sowie das
Bei wenigen komplexen Schablonen ist ein solcher Änderungsaufwand aber viel größer als bei einer (sinnvollen!) Unterteilung in mehrere kleinere Schablonen. Natürlich kann man das auch übertreiben.
hat mir eine neue Perspektive eröffnet. Aufteilung ist also auch für den Designer gar nicht schlecht.
Der Grund für den Einsatz von Schablonen ist ja nicht, viele Daten damit zu formatieren, denn das könnte man auch mit Code tun, sondern Code, Daten und Formatierung voneinender zu trennen um Änderungen mit möglichst wenig Aufwand (und ohne Programmierkenntnisse) durchführen zu können.
Das klingt mir zu einseitig. Müßte der erste Satz nicht so beginnen "Der Grund für den Einsatz von Schablonen ist ja nicht nur" oder "Der Grund für den Einsatz von Schablonen ist ja nicht primär"?
Wie auch immer, Deine Antwort hat mich schon mal ein ganzes Stück weiter gebracht.
Hallo Jürgen,
ich versuche gerade, mir ein eigenes Templatesystem zu stricken.
da hast du dir ja schon einige Gedanken gemacht, ein Templatesystem ist auf jeden Fall eine sinnvolle Sache.
Aber es geht auch darum wie man das Templatesystem einsetzt.
Zur Zeit beschäftige ich mich auch mit dem Thema und ärgere mich darüber das bei vielen
Programmen versucht wird alles und jedes in Templatedateien konfigurierbar zu machen.
Es wird viel zu wenig auf die Möglichkeiten von CSS gesetzt.
Als Negativbeispiel nenne ich mal XTCommerce, ein Onlinshop mit Templatesystem Smarty,
... über 100 Templatedateien die man anpassen muss
da sitze ich ne Woche dran
im Gegensatz dazu Typo3 da habe ich ein individuelles Layout in ein paar Stunden fertig
... der Vergleich hinkt jetzt etwas da XtCommerce komplexer ist
Zu deinem Beispiel:
<html>
<head>
<title>##titel##</title>
</head><body>
[eine Linkleiste, fest eingebaut]
<h1>##titel##</h1>
##content##
</body>
</html>
(sieht in Typo3 praktisch genauso aus)
das sollte im Prinzip schon ausreichen also ohne Programmlogik im Template. Im Php-programm kann man dann alle Ausgaben
mit Css ID's/Klassen versehen und das Layout komplett über die CSS-Datei gestalten.
Auch Grafiken sollte man mm nicht direkt über das PHP-Programm ausgeben, das kann man auch mit
CSS machen.
Menüs mit ul und li ausgegeben lassen per CSS formatieren ...
ob sie nun horizontal o. vertikal mit Balken oder Hintergrundgrafik sein sollen, lässt sich alles per CSS machen
schau dich mal bei phpclasses.org um. Dort findest du eine Vielzahl von Templateklassen und kannst schauen wie andere Leute das umgesetzt haben.
Gruß Udo
Hallo,
Zu deinem Beispiel:
<html>
<head>
<title>##titel##</title>
</head><body>
[eine Linkleiste, fest eingebaut]
<h1>##titel##</h1>
##content##
</body>
</html>(sieht in Typo3 praktisch genauso aus)
das sollte im Prinzip schon ausreichen also ohne Programmlogik im Template. Im Php-programm kann man dann alle Ausgaben
mit Css ID's/Klassen versehen und das Layout komplett über die CSS-Datei gestalten.
Aber dann ist ja Programmlogik und Ausgabe wieder nicht ordentlich getrennt. Oder versteh ich Dich gerade nicht richtig?
Auch Grafiken sollte man mm nicht direkt über das PHP-Programm ausgeben, das kann man auch mit
CSS machen.Menüs mit ul und li ausgegeben lassen per CSS formatieren ...
ob sie nun horizontal o. vertikal mit Balken oder Hintergrundgrafik sein sollen, lässt sich alles per CSS machen
Das ist schon klar. Daten und Formatierung trenne ich auf die von Dir beschriebene Weise. Weil es nichts zur Sache tut, habe ich das mal in den Beispielen weggelassen.
schau dich mal bei phpclasses.org um. Dort findest du eine Vielzahl von Templateklassen und kannst schauen wie andere Leute das umgesetzt haben.
Gruß Udo
Werde ich tun.
mal ein Beispiel für das Hauptprogramm zu deinem Template:
<?php
class cTemplate {
var $template_string;
function cTemplate($template_file) {
$this->template_string = @file_get_contents($template_file); // Template in einen String einlesen
if ($this->template_string == "") { die("Fehler: Template nicht gefunden"); } // Fehler
}
function assign($marker, $value) { // einer Markierung im Template Daten zuweisen
$this->template_string = str_replace($marker, $value, $this->template_string);
}
function display() { // das Template mit den Inhalten ausgeben
print $this->template_string;
}
}
$html = new cTemplate("template.htm");
$page = $_GET['page'];
switch ($page) {
case 'guestbook_list':
$html->assign("###TITLE###", "Gästebuch");
// Datenbankabfrage usw. und hier evtl. mit Subtemplates für ###CONTENT### arbeiten
$html->assign("###CONTENT###", "");
break;
default:
$html->assign("###TITLE###", "Startseite");
$html->assign("###CONTENT###", "<h3>Hallo Welt,</h3><p>hier kommt Inhalt ...</p>");
}
$html->display();
?>
dann hat man ein Haupttemplate ohne Programmierlogik und kann das Layout sehr schnell für alle Seiten anpassen
Danke. So ähnlich hatte ich das bisher auch gelöst. Zusätzlich hatte ich noch Methoden z. B. für Radio-Felder, die ungefähr so im Template verwiklicht werden
<input type="radio" id=".." name=".." ##option_0## />Option 0
<input type="radio" id=".." name=".." ##option_1## />Option 1
Der Aufruf $template_name->radio("option", 1) führt dann zu
<input type="radio" id=".." name=".." />Option 0
<input type="radio" id=".." name=".." checked="checked" />Option 1
Für Select-Felder habe ich auch eine solche Methode. Wie weit hast Du bzw. werden in Template Engines wie Smarty solche Zusatzfunktionen integriert? Wie gesagt, ich stehe noch am Anfang bei der Template-Technik, will aber schon was halbwegs Vernünftiges aufbauen, das sich wiederverwenden läßt. Es muß zwar erst mal nicht an ausgereifte Engines heranreichen, soll mir aber zukünftig die Arbeit erleichtern, d.h., es muß auf andere Sites, die ich erstelle, übertragbar sein.
Danke. So ähnlich hatte ich das bisher auch gelöst. Zusätzlich hatte ich noch Methoden z. B. für Radio-Felder, die ungefähr so im Template verwiklicht werden
<input type="radio" id=".." name=".." ##option_0## />Option 0
<input type="radio" id=".." name=".." ##option_1## />Option 1Der Aufruf $template_name->radio("option", 1) führt dann zu
<input type="radio" id=".." name=".." />Option 0
<input type="radio" id=".." name=".." checked="checked" />Option 1Für Select-Felder habe ich auch eine solche Methode. Wie weit hast Du bzw. werden in Template Engines wie Smarty solche Zusatzfunktionen integriert? Wie gesagt, ich stehe noch am Anfang bei der Template-Technik, will aber schon was halbwegs Vernünftiges aufbauen, das sich wiederverwenden läßt. Es muß zwar erst mal nicht an ausgereifte Engines heranreichen, soll mir aber zukünftig die Arbeit erleichtern, d.h., es muß auf andere Sites, die ich erstelle, übertragbar sein.
naja, das geht dann schon eher in die Richtung PHP-Framework (MVC).
Wenn man Formulare einbindet hat man meistens noch eine Datenbank
in der die Daten gespeichert werden sollen.
Praktisch läuft es bei individuellen Programmen immer auf folgendes hinaus:
-Listenansicht
-Detailansicht
-Löschen
-Bearbeiten
-Suchen
(kannst ja mal nach MVC u. Framework googeln)
Aber für den Anfang ist wahrscheinlich sinniger sich erstmal nur mit der Template-Engine zu beschäftigen.
zu Frameworks kann ich im Mom. noch nicht viel sagen (bin am testen)
Gruß Udo
Praktisch läuft es bei individuellen Programmen immer auf folgendes hinaus:
-Listenansicht
-Detailansicht
-Löschen
-Bearbeiten
-Suchen
(kannst ja mal nach MVC u. Framework googeln)
Schon richtig, aber was willst Du mir damit sagen?
Aber für den Anfang ist wahrscheinlich sinniger sich erstmal nur mit der Template-Engine zu beschäftigen.
»»
Das gehört für mich dazu, sonst könnte müßte ich wieder Programmlogik und Ausgabe vermischen, entweder im Template selbst oder mittels Zusammenbau der Optionsfelder im Skript selbst.
Hallo Jürgen,
Praktisch läuft es bei individuellen Programmen immer auf folgendes hinaus:
-Listenansicht
-Detailansicht
-Löschen
-Bearbeiten
-Suchen
(kannst ja mal nach MVC u. Framework googeln)Schon richtig, aber was willst Du mir damit sagen?
Zitat Wikipedia:
Demgegenüber steht der ursprüngliche Gedanke der Template Engines: Sie sollen statischen Text und dynamische Inhalte möglichst effizient miteinander verknüpfen. Oft sind Template Engines deshalb gerade in Programmiersprachen anzutreffen, deren Syntax eine solche Mischung nicht direkt unterstützt: (z.B. Java: JSP; VBScript u.a.: ASP)
Für eine echte Trennung der Darstellung von den Datenmodellen und den Logikkomponenten sind Template Engines dagegen ungeeignet und es sind zusätzliche Konzepte wie z.B. MVC notwendig
Zitatende
http://de.wikipedia.org/wiki/Template_Engine
Das gehört für mich dazu, sonst könnte müßte ich wieder Programmlogik und Ausgabe vermischen, entweder im Template selbst oder mittels Zusammenbau der Optionsfelder im Skript selbst.
warum kann man die Optonsfelder nicht im Script zusammenbauen ?
nur das "Programm" weiß doch was da drinstehen muss
Hallo,
Zitat Wikipedia:
Demgegenüber steht der ursprüngliche Gedanke der Template Engines: Sie sollen statischen Text und dynamische Inhalte möglichst effizient miteinander verknüpfen. Oft sind Template Engines deshalb gerade in Programmiersprachen anzutreffen, deren Syntax eine solche Mischung nicht direkt unterstützt: (z.B. Java: JSP; VBScript u.a.: ASP)Für eine echte Trennung der Darstellung von den Datenmodellen und den Logikkomponenten sind Template Engines dagegen ungeeignet und es sind zusätzliche Konzepte wie z.B. MVC notwendig
Zitatendehttp://de.wikipedia.org/wiki/Template_Engine
Ok, das merke ich mittlerweile auch. Demnach kann man diesen Zustand (Trennung von Logik und Ausgabe) nur anpeilen, aber niemals vollständig erreichen.
Verstanden habe ich leider immer noch nicht, was Du mir mit der Auflistung der einzelnen Bestandteile von Programmen (Listenansicht, Detailansicht usw.) sagen willst.
Das gehört für mich dazu, sonst könnte müßte ich wieder Programmlogik und Ausgabe vermischen, entweder im Template selbst oder mittels Zusammenbau der Optionsfelder im Skript selbst.
warum kann man die Optonsfelder nicht im Script zusammenbauen ?
nur das "Programm" weiß doch was da drinstehen muss
»»
Na ja, der Sinn des Templates sollte ja Trennung von Logik und Ausgabe sein. Wenn ich ein Optionspaar männlich/ weiblich habe, das aus einer Datenbank befüllt wird, sind bis auf den Zustand, welches Element aktiviert ist, alle Inhalte statisch. Somit sollten diese statischen Elemente
<input type="radio" name="gender" value="m" ...>männlich
<input type="radio" name="gender" value="f" ...>weiblich
im Template enthalten sein. Die Abfrage, welchen Zustand die Radio-Felder haben, kann man direkt innerhalb des <input>-Tags vornehmen. Das ist nicht sinnvoll. Die <input>-Elemente aus dem Template nehmen ist ebenso sinnlos. Je nachdem, wieviel Content aus dem Template genommen wird, bleibt vom Template nicht viel übrig, womit wir wieder beim Mischmasch aus Logik und Ausgabe sind, diesmal nur an anderer Stelle und auf einer höheren Abstraktionsstufe. Bleibt also nur eine Schnittstelle im Template einzufügen
<input type="radio" name="gender" value="m" ##gender_m##>männlich
<input type="radio" name="gender" value="f" ##gender_f##>weiblich
Das finde ich übersichtlich, es erspart Schreibarbeit unzähliger Vergleiche (statt dessen ein Methodenaufruf $template->radio("gender", "f") ), und der Designer kann seine Vorstellungen innerhalb des Templates verwirklichen.
Wie würdest Du Optionsfelder in Templates verwirklichen?