Problem: Templatesystem

glowhand

Programmierer
21 April 2006
273
16
Hallo!
Stehe vor einem Problem, bei dem mir hoffentlich jemand helfen kann. Ich möchte eine Template-Klasse entwickeln. Leider erfüllt sie noch nicht meine Anforderungen und ich weiß auch nicht wie ich sie so einfach verbessern könnte.
Bisher macht die Klasse folgendes:
(1) .tpl mit file_get_contents einlesen
(2) Variablen zuweisen (in Array speichern)
(3) Seiten zuweisen (in Array speichern)
(4) eingelesene .tpl nach Platzhaltern durchsuchen und diese mit entsprechender Variable oder andere .tpl ersetzen.
(5) Seite ausgeben

Alles schön und gut, nur angenommen, eine .tpl, die in einer andere .tpl durch einen Platzhalter eingesetzt wurde, beinhaltet auch noch einmal einen Platzhalter für eine zu einlesende .tpl... Dieser wird dann nichtmehr ersetzt.
Lösung des Problems wäre möglicherweise, sofort beim Zuweisen die Seiten zu ersetzen, statt sie in einem Array zu speichern, allerdings könnte ich dann einmal zugewiesene Seiten nicht noch einmal abändern.

Kann mir da jemand eine Idee bieten? Dankeschön schonmal.
 
Du gehst einfach alles durch:

Du fängst beim Main-Template an. Dann ersetzt du z.B. den Platzhalter durch das include-tpl-file. Und das ganze einfach so lange, bis eine replace-Funktion keine Änderung mehr bringt (bzw false).

btw: Wieso ein eigenes Templatesystem ? Smarty z.B. ist einfach und relativ schnell.
 
Johnson schrieb:
Du gehst einfach alles durch:

Du fängst beim Main-Template an. Dann ersetzt du z.B. den Platzhalter durch das include-tpl-file. Und das ganze einfach so lange, bis eine replace-Funktion keine Änderung mehr bringt (bzw false).

btw: Wieso ein eigenes Templatesystem ? Smarty z.B. ist einfach und relativ schnell.

hmm, danke, das werde ich mir nochmal ansehen.
von smarty bin ich nicht so begeistert, denn erstens möchte ich meine scripts möglichst nur mit eigenem code programmieren, zweitens ist smarty sehr vollgepackt mit vielen dingen, die ich zumindest garnicht benötige und drittens ist das ja fast schon wieder pseudo php code in den templates.
 
surferhit.com schrieb:
hmm, danke, das werde ich mir nochmal ansehen.
von smarty bin ich nicht so begeistert, denn erstens möchte ich meine scripts möglichst nur mit eigenem code programmieren, zweitens ist smarty sehr vollgepackt mit vielen dingen, die ich zumindest garnicht benötige und drittens ist das ja fast schon wieder pseudo php code in den templates.

1. und 2. ziehen ja noch (okay, ich habe zumindest bei 1. im Fall Smarty meine Meinung geändert).
Aber zu 3. muss ich sagen:
Wenn du ein Array mit {foreach} ausgibst und da dann gleich die Tabellenstruktur o.ä. zwischen dem Open- und dem Close-Tag hast; ist das bessere Trennung von Layout und Logik als z.B. das Füllen von Tabellen im PHP-Part. Das Layout ergibt so einen zusammenhängenden Sinn.
 
Johnson schrieb:
1. und 2. ziehen ja noch (okay, ich habe zumindest bei 1. im Fall Smarty meine Meinung geändert).
Aber zu 3. muss ich sagen:
Wenn du ein Array mit {foreach} ausgibst und da dann gleich die Tabellenstruktur o.ä. zwischen dem Open- und dem Close-Tag hast; ist das bessere Trennung von Layout und Logik als z.B. das Füllen von Tabellen im PHP-Part. Das Layout ergibt so einen zusammenhängenden Sinn.

werde es mir wohl nochmal ansehen müssen ;)
 
surferhit.com schrieb:
von smarty bin ich nicht so begeistert, denn erstens möchte ich meine scripts möglichst nur mit eigenem code programmieren, zweitens ist smarty sehr vollgepackt mit vielen dingen, die ich zumindest garnicht benötige und drittens ist das ja fast schon wieder pseudo php code in den templates.
Ich stimme sogar allen drei Punkten zu, obwohl Johnson mit dem foreach() nicht so ganz Unrecht hat.

Zum Topic selber verstehe ich aber das Problem noch nicht. Im Prinzip hast du genau sowas ähnliches, was ich auch immer nutze. Und das klappt eigentlich perfekt. Krieg ich nochmal die Frage, dass ich sie auch versteh ? :biggrin:
(bin heut erst um 4 ins Bett und war um 9 schon wieder auf :shifty: )
 
theHacker schrieb:
Ich stimme sogar allen drei Punkten zu, obwohl Johnson mit dem foreach() nicht so ganz Unrecht hat.

Zum Topic selber verstehe ich aber das Problem noch nicht. Im Prinzip hast du genau sowas ähnliches, was ich auch immer nutze. Und das klappt eigentlich perfekt. Krieg ich nochmal die Frage, dass ich sie auch versteh ? :biggrin:
(bin heut erst um 4 ins Bett und war um 9 schon wieder auf :shifty: )

ok... also:
habe eine klasse "template". die function assign schreibt in ein array den namen des platzhalters und dessen zu ersetzenden wert.
genauso wird es seiten gemacht (function assignSite), also templates, die im eigentlichen template statt einem platzhalter eingelesen werden (name des platzhalters, datei.tpl, die eingelesen werden soll).
die function display() hat das dann alles zu ersetzen, in dem es zuerst mit foreach nach platzhaltern für zu einlesende templates sucht (und diese ersetzt), danach für variablen (und diese ersetzt).
das problem ist nun, dass foreach das array mit den angaben zum ersetzen der platzhalter durch templates der reihe nach durchgeht. beispiel:
overall.tpl enthält platzhalter {.SITE_MENU.} für menu.tpl
menu.tpl enthält platzhalter für {.SITE_PARTNERS.} für partners.tpl
zuerst wird overall.tpl eingelesen, muss also nicht mit function assignSite angegeben werden. danach wird im script {.SITE_PARTNERS.} für partners.tpl definiert, also vor {.SITE_MENU.}, danach erst {.SITE_MENU.}.
Nun wird zuerst in der overall.tpl nach {.SITE_PARTNERS.} gesucht -> nicht gefunden. darauf nach {.SITE_MENU.} -> wird gefunden. der array eintrag {.SITE_PARTNERS.} war nun aber schon an der reihe und das script durchsucht deshalb nicht nochmal nach dem platzhalter, der eben erst nach einlesem von menu.tpl existiert.
problem verstanden? ;)
 
Ehrlich gesagt kommt mir dein Problem wie kein Problem vor (siehe mein Post oben; war glaube ich der 1.).

Du liest einfach erstmal die Datei z.B. mittels file_get_contents() in einen String. Dann liest du die zu verarbeitenden Tags aus (preg_match, preg_replace), bis irgendwann preg_match kein Ergebnis mehr liefert.
 
surferhit.com schrieb:
problem verstanden? ;)
Ja.
Deine Klasse ist perfekt, du benutzt sie nur falsch ;)

Immer wenn ein Template keinen Platzhalter mehr enthält, kannst du es parsen. Dieses bereits geparste Template kannst du nun anderen - übergeordneten - Templates als Wert zuweisen.

Im Prinzip musst du dein Beispiel nur in der anderen Richtung durchspielen.

Lösung verstanden ? ;)
 
ja, das hatte ich vergessen zu sagen: es kann doch sein, dass ein benutzer einen latzhalter, dem garkeine variable zugeordnet ist. da kann das ja so oft durchgegangen werden wie mal will, es bleibt immer ein platzhalter, der nicht ersetzt wird.
 
surferhit.com schrieb:
ja, das hatte ich vergessen zu sagen: es kann doch sein, dass ein benutzer einen latzhalter, dem garkeine variable zugeordnet ist. da kann das ja so oft durchgegangen werden wie mal will, es bleibt immer ein platzhalter, der nicht ersetzt wird.
Auch das is dein Problem ;)
Du musst schon jede Variaben, die du im Template hast, auch im Script ersetzen lassen und wenn du nur
PHP:
$tpl->set_var("unused_var","");
machst.

Du könntest natürlich deine Platzhalter im Template speziell markieren, z.B.
HTML:
<tr><td>!!-(platzhaltername)-!!</td></tr>
Mit einem RegExp (nicht getestet)
Code:
/!!-\([^)]*\)-!!/
könntest du ganz am Ende vor dem endgültigen Ausgeben alle nicht-gesetzten Platzhalter rauslöschen.
 
versteh ich nicht...
also, 1. weiß man doch nicht, welche platzhalter im template stehen.
2: preg_replace wird bereits vor dem ausgeben genutzt. aber wenn man die tpl-datei so lange durchgehen möchte bis kein platzhalter mehr drin ist (was ja nicht möglich ist, weil es eben auch ungenutzte platzhalter geben könnte) wäre preg_replace ja wiederum überflüssig.
ich kann ja mal ein kleines beispiel veröffentlichen?
 
surferhit.com schrieb:
ich kann ja mal ein kleines beispiel veröffentlichen?
Ja tu das mal. Am besten die ganze klasse! Template systeme sind ja nicht so komplex. Vielleicht wird dann ersichtlich woran es genau liegt.

surferhit.com schrieb:
2: preg_replace wird bereits vor dem ausgeben genutzt. aber wenn man die tpl-datei so lange durchgehen möchte bis kein platzhalter mehr drin ist (was ja nicht möglich ist, weil es eben auch ungenutzte platzhalter geben könnte) wäre preg_replace ja wiederum überflüssig.
In meiner template klasse hab ich das gelöst indem ich leehre platzhalter einfach mit nix ersetzt habe(also ph entfernen und gut is). Und wenn es keine ph mit oder ohne inhalt mehr zu tauschen gibt is der preg_replace durchlauf beendet.
 
Salve,
glaube ich habe raus voran es hängt. Dir unterläuft da ein kleiner denkfehler was die reihenfolge der veorgänge angeht. Im moment versuchst du mit einem aufruf deiner tpl klasse gleich 3 tpl dateien einzulesen.
PHP:
$tpl = new template('overall.tpl');

$tpl->assign('title','DER ZUGEWIESENE TITEL');
$tpl->assignSite('site_menu_user','menu_user.tpl');
$tpl->assignSite('site_menu','menu.tpl');
$tpl->display();
Was natürlich auch funktionieren könnte, jedoch versuchst du ein tpl file einem platzhalter zuzuordnen der noch gar nicht vorhanden ist. Und deshalb kann er auch nicht ersetzt werden. Eine wesentlich bessere methode wäre die tpl klasse zweimal aufzurufen…
PHP:
$tpl = new template('overall.tpl'); // Haupt tpl
$tlp = new template('menu_user.tpl'); // Inneres tpl

$tpl->assign('title','DER ZUGEWIESENE TITEL');
$tpl->assignSite('site_menu','menu.tpl');
$tpl->assign('site_menu_user',$tlp->display(false));
$tpl->display(true);
Das innen template wird dann quasi in das haupt template eingefügt. Alles was du noch tun musst ist deiner display funktion auch das zuzückgeben beizubringen(also auf wunsch return anstatt print)
PHP:
	/* display template */
	function display($print = false)
	{
	/*  */

		if ($print == true){
			print($this->output);
		} else {
			return $this->output;
		}
	}
MFG