Platzhalter in Template ersetzen
lima-city → Forum → Programmiersprachen → PHP, MySQL & .htaccess
alltag
array
ausgabe
benutzen
code
dank
datei
datum
frage
idee
inhalt
motivation
platzhalter
rubrik
span
stehen
string
text
url
zeile
-
Hallo
ich möchte ein Script bauen mit einem (eigenen) Template-System,
in der Template-Datei (HTML) stehen Platzhalter, die durch Inhalte von Variablen ersetzt werden sollen
hier ein einfaches Beispiel der Template-Datei (HTML-Vorlage):
<div class="artikel"> <h2>{TITEL}</h2> <p>{TEXT}</p> <ul> <li>Rubrik: {RUBRIK}</li> <li>Datum: {DATUM}</li> <li>Autor: {AUTOR}</li> </ul> </div>
dazu stehen jeweils als Variablen (Inhalte) bereit: (Beispiel)
$titel = 'Motivation im Alltag'; $text = 'Chakka - Du kannst es ... man muss nur wirklich Wollen, dann klappt einfach Alles ... '; $rubrik = 'Allgemein'; $datum = '16.11.2012 (09:27)'; $autor = 'Donald Duck';
------
EDIT: das ; (Semikolon) im der Zeile:
hinzugefügt$datum = '16.11.2012 (09:27)';
UND: der Satz in $text soll natürlich heissen: ... Wollen, dann klappt einfach Alles ... aber egal :)
------
wie ersetzte ich jetzt am besten (schnell und Ressourcen schonend)
die Platzhalter durch die Werte der dazu-gehörenden Variablen ?
einfach mit str_replace() ?
// ------------- Template einlesen ---------- $tpl_strimg = file_get_contents($template_file); // ------------- Platzhalter ersetzen ---------- $tpl_strimg = str_replace('{TITEL}', $titel, $tpl_strimg); $tpl_strimg = str_replace('{TEXT}', $text, $tpl_strimg); $tpl_strimg = str_replace('{RUBRIK}', $rubrik, $tpl_strimg); $tpl_strimg = str_replace('{DATUM}', $datum, $tpl_strimg); $tpl_strimg = str_replace('{AUTOR}', $autor, $tpl_strimg); // ------------- HTML Ausgabe ---------- echo $tpl_strimg;
... oder gibt es eine andere, bessere Methode ? ... z.B. ein preg_replace mit Pattern ?
Das ist ein stark vereinfachtes Beispiel, eigentlich sollen mind.10 Platzhalter ersetzt werden
wobei sich das auch ver-vielfachen kann, für z.B. 5 Artikel pro Seite dann eben 5 mal
und dazu kommen "globale" Platzhalter für Header-/ Footer-Bereich und Sidebar, etc.
die auch auf jeder Seite ersetzt werden, (HTML-Head, Logo, Seiten-Titel, Navigation, usw.)
... macht es einen Unterschied, in welchen "Markern" der Platzhalter steht?
also ob {TITEL} oder #TITEL# oder %TITEL% oder :TITEL: oder |TITEL| oder ... ?
... und was ist besser, die komplette HTML-Ausgabe in einen einzigen String zu packen,
oder als "kleinere Teile" ablegen ($htmlhead, $pageheader, $content, $sidebar, $footer)
und dann erst bei Ausgabe mit echo zusammen bauen ? ... oder ist das egal ?
Beitrag zuletzt geändert: 18.11.2012 13:52:42 von oindex -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage
-
Wieso machst du es nicht gleich so:
<div class="artikel"> <h2>$titel</h2> <p>$text</p> <ul> <li>Rubrik: $rubrik</li> <li>Datum: $datum</li> <li>Autor: $autor</li> </ul> </div>
Du definierst zuerst die Variablen und bindest dann einfach das Template in das gleiche Script ein. D. h. oben Variablen definieren, unten Ausgabe.
EDIT: ja habe das echo vergessen. Müsste also so ausschauen: <?php echo $titel; ?> usw...
Beitrag zuletzt geändert: 18.11.2012 18:08:18 von hm4-blog -
hm4-blog schrieb:
Nur so wird es nicht funktionieren. Wenn schon müsstest du es so machen:
Du definierst zuerst die Variablen und bindest dann einfach das Template in das gleiche Script ein. D. h. oben Variablen definieren, unten Ausgabe.<?php // template.php echo(<<< END <div class="artikel"> <h2>$titel</h2> <p>$text</p> <ul> <li>Rubrik: $rubrik</li> <li>Datum: $datum</li> <li>Autor: $autor</li> </ul> </div> END );
Nutzen könntest du es dann so:<?php // Variablen füllen $titel = 'Motivation im Alltag'; $text = 'Chakka - Du kannst es ... man muss nur wirklich Wollen, das klappt einfach Alles ... '; $rubrik = 'Allgemein'; $datum = '16.11.2012 (09:27)'; $autor = 'Donald Duck'; // Template einbinden include('template.php');
Wichtig ist dabei aber zu wissen, dass die Variablen auch HTML enthalten können… wenn hier also Nutzerdaten ausgegeben werden muss noch
benutzt werden.htmlentities()
Beitrag zuletzt geändert: 18.11.2012 12:50:22 von hackyourlife -
@ hm4-blog ... hmmm, aber so einfach geht's dann doch nicht,
zumindest bekomme ich so keine Werte in die Ausgabe,
es werden weiterhin die Variablen-Namen $titel etc. ausgegeben, nicht die Werte dazu
wenn Du mit include() meinst, dan evtl so:
<div class="artikel"> <h2><?= $titel; ?></h2> <p><?= $text; ?></p> <ul> <li>Rubrik: <?= $rubrik; ?></li> <li>Datum: <?= $datum; ?></li> <li>Autor: <?= $autor; ?></li> </ul> </div>
bzw. ohne Short-TAGs
<div class="artikel"> <h2><?php echo $titel; ?></h2> <p><?php echo $text; ?></p> <ul> <li>Rubrik: <?php echo $rubrik; ?></li> <li>Datum: <?php echo $datum; ?></li> <li>Autor: <?php echo $autor; ?></li> </ul> </div>
oder wie kann man es ohne die PHP-TAGs im Template machen,
also direkt mit dem Template wie von hm4-blog vorgeschlagen ?
ahhh .. Danke @hackyourlife ... für Antwort während ich das hier geschrieben habe
Auch ne gute Möglichkeit ... muss die Template-Datei dann als .php vorliegen (nicht .htm oder .tpl) ?
PS: Hinweis: bei meinen Beispiel-Variablen oben fehlt ein
(Semikolon) !!!;
$datum = '16.11.2012 (09:27)';
Oder soll ich doch "besser" mit Platzhalter und str_replace() arbeiten ?
Denn ich will, dass auch Andere das Template einfach ändern können,
die das Script nicht genau kennen bzw. gar kein PHP können ....
Beitrag zuletzt geändert: 18.11.2012 12:43:42 von oindex -
https://github.com/sateffen/Common-PHP-Components/tree/experimental/CPC/Template
Sind noch in der Experimental Phase, ich werd wohl erst in einer oder zwei wochen dazu kommen, Unittests dafür zu schreiben, jedoch wären das Templateansätze die eigentlich funktionieren sollten. Dabei sind dies nur die Evaluationsfunktionen. Dazu würden die Abstract halt noch gelesen werden müssen (liegen entsprechend dem PSR0 Std in den Ordnern)
Das Executiontemplate funktioniert so, dass du die Variablen, die übergeben werden, so wie her benutzen kannst:
<div class="artikel"> <h2><?php echo $titel; ?></h2> <p><?php echo $text; ?></p> <ul> <li>Rubrik: <?php echo $rubrik; ?></li> <li>Datum: <?php echo $datum; ?></li> <li>Autor: <?php echo $autor; ?></li> </ul> </div>
Nur halt in einem seperiertem Scope.
Das Replacement übernimmt das ganze über Replacementpattern. Im stdfall sind dies {{VARNAME}}, welche im Template zu stehen haben:
<div class="artikel"> <h2>{{title}}</h2> <p>{{text}}</p> <ul> <li>Rubrik: {{rubrik}}</li> <li>Datum: {{datum}}</li> <li>Autor: {{autor}}</li> </ul> </div>
Damit kann man die logik komplett aus den Templates halten. Da die Klassen jedoch noch lange nicht fertig sind, komplett ungetestet, und die kommentare auch noch nicht fertig sind, würd ich dir empfehlen vielleicht mal rüber zu schauen, wie es codetechnisch gelöst ist, ob du davon vllt was gebrauchen kannst. Ich für mich kämpfe noch mit der Zeit um alles fertig zu machen
Liebe Grüße -
oindex schrieb:
Wie du die Datei nennst ist völlig egal, da sie durch
ahhh .. Danke @hackyourlife ... für Antwort während ich das hier geschrieben habe
Auch ne gute Möglichkeit ... muss die Template-Datei dann als .php vorliegen (nicht .htm oder .tpl) ?
als PHP ausgewertet wird. Du kannst sie also ohne Probleme auchinclude()
oder sonst irgenwdie nennen, falls dir das besser gefällt..tpl
oindex schrieb:
Dir muss klar sein, dass bei meiner Variante jeder beliebige PHP-Code der im Template enthalten ist ausgeführt werden kann…
Oder soll ich doch "besser" mit Platzhalter und str_replace() arbeiten ?
Denn ich will, dass auch Andere das Template einfach ändern können,
die das Script nicht genau kennen bzw. gar kein PHP können ....
Die 2 Zeilen am Anfang und die 2 Zeilen am Ende kann man kopieren, dazwischen die Variablen benötigen auch keine weiteren PHP-Kenntnissen.
Bei
werden hingegen nur die Platzhalter ersetzt, PHP kann im Template nicht benutzt werden…str_replace()
oindex schrieb:
Das ist völlig egal.
... macht es einen Unterschied, in welchen "Markern" der Platzhalter steht?
also ob {TITEL} oder #TITEL# oder %TITEL% oder :TITEL: oder |TITEL| oder ... ?
So, jetzt hab ich sogar noch mal schnell eine weitere Idee umgesetzt, auf die mich ggamee gebracht hat
template.tpl:<div class="artikel"> <h2>{{titel}}</h2> <p>{{text}}</p> <ul> <li>Rubrik: {{rubrik}}</li> <li>Datum: {{datum}}</li> <li>Autor: {{autor}}</li> </ul> </div>
index.php:<?php $vars = array( 'titel' => 'Motivation im Alltag', 'text' => 'Chakka - Du kannst es ... man muss nur wirklich Wollen, das klappt einfach Alles ...', 'rubrik'=> 'Allgemein', 'datum' => '16.11.2012 (09:27)', 'autor' => 'Donald Duck' ); $tpl = file_get_contents('template.tpl'); echo(preg_replace('|{{(.*?)}}|e', 'isset($vars["\1"])?$vars["\1"]:"\0"', $tpl));
Beitrag zuletzt geändert: 18.11.2012 13:18:34 von hackyourlife -
Danke @ggamee die klasse werd ich mal anschauen / beobachten,
Danke @hackyourlife genau so ein preg_replace habe ich gesucht
aber kannst Du mir sagen, warum Modifikator: e im Pattern ?!?
... ahhh .... ok .... gefunden dazu habe ich:
e (PREG_REPLACE_EVAL)
Wenn dieser Modifikator gesetzt ist, macht preg_replace() in der Ersetzungszeichenkette eine normale Ersetzung von Rückrefenzen, wertet sie als PHP-Code aus und verwendet das Ergebnis um damit die gesuchte Zeichenkette zu ersetzen. Einfache Anführungszeichen, doppelte Anführungszeichen, Backslashes (\) und NULL-Zeichen werden in den ersetzten Rückreferenzen mit einem Backslash maskiert.
für den Fall, dass z.B. $vars['text'] weiteren HTML-Code enthält, und dieser richtig escaped wird ?
... hab ich das "richtig" verstanden ?
würde ich vor dem preg_replace() machen:$vars['text'] = htmlentities($vars['text']);
dann bekäme ich als Ausgabe nicht den interpretierten HTML sondern einen sichtbaren HTML-Code
also anstatt:Chakka <span style="color:red;">Du</span> kannst es ...
dann sowas:Chakka <span style="color:red;">Du</span> kannst es ...
... aber es soll ja in $tpl der "string" für die Ausgabe mit echo / print richtig escaped sein ...
$tpl = "Chakka <span style=\"color:red;\">Du</span> kannst es ...";
(hier mal nur als kleiner Teil,
ist schon klar das $tpl dann den gesamten Code aus template.tpl plus Variablen-Werte enthalten soll.
Würde ich es ohne den Modifikator: e machen würde, wären die
im $tpl String nicht escaped"
... richtig? ( ... ich will ja auch was lernen)
Wäre dazu eine Alternative auch:$vars['text'] = addslashes($vars['text']);
und dann geht's im preg_replace() ohne den Modifikator: e ..... oder hab ich da was falsch verstanen?
-
Du bringst hier einiges durcheinander…
Der Modifier
sagte
, dass der Ersetztext kein normaler Text ist, sondern PHP-Code. Dabei wirdpreg_replac()
durch den Ausdruck in der Klammer und\1
durch den gesamten Ausdruck ersetzt und danach alles als PHP-Code ausgeführt, wobei diese Ersetzungen zuerst mit\0
escaped werden, damit die Ersetzungen als String benutzt und nicht ausgeführt werden.addslashes()
Der zusammengebaute String wird dann jedenfalls so ausgewertet, wie wenn
benutzt werden würde.eval()
Wenn du die Daten in
durch$vars
laufen lassen willst wäre es so wohl am einfachsten:htmlentities()
<?php $vars = array( 'titel' => 'Motivation im Alltag', 'text' => 'Chakka <span style="color:red;">Du</span> kannst es ...', 'rubrik'=> 'Allgemein', 'datum' => '16.11.2012 (09:27)', 'autor' => 'Donald Duck' ); $tpl = file_get_contents('template.tpl'); echo(preg_replace('|{{(.*?)}}|e', 'htmlentities(isset($vars["\1"])?$vars["\1"]:"\0")', $tpl));
Das würde dann den Effekt erzielen:$vars['text'] = 'Chakka <span style="color:red;">Du</span> kannst es ...';
wird in der Ausgabe zuChakka <span style="color:red;">Du</span> kannst es ...
Das würdest du nutzen, wenn nur reiner Text ohne Formatierungen erlaubt ist und der Text vom Benutzer (wie bei einem CMS) eingegeben wird (= Schutz vor XSS).
Wenn nur du Text eingibst der auch noch Formatierungen enthalten darf musst du
weglassen.htmlentities()
oindex schrieb:
Nein, addslashes brauchst du hier nirgendwo,
Wäre dazu eine Alternative auch:$vars['text'] = addslashes($vars['text']);
und dann geht's im preg_replace() ohne den Modifikator: e ..... oder hab ich da was falsch verstanen?
hingegen schon, wenn der Ersetzungstext dynamisch und aus dem Array erstellt werden soll.e
Kurz die Funktionsweise der
-Zeile:preg_replace
1) Muster suchen, die mit
anfangen und{{
enden; den Text dazwischen merken ("gefundenertext").}}
2) Folgenden PHP-Code ausführen:$ersetztext = isset($vars["gefundenertext"]) ? $vars["gefundenertext"] : "{{gefundenertext}}";
Also wenn
gesetzt ist wird dadurch ersetzt, sonst bleibt es so wie es war.$vars["gefundenertext"]
3) Der Treffer wird durch
ersetzt.$ersetztext
und die Strings hier dienen nur als Beispiel!$ersetztext
-
@hackyourlife: Ich hab ne Frage dazu:
Wäre es nicht hierbei sinnvoller str_replace zu benutzen, aufgrund der hohen Suchhäufigkeit von preg_replace (was doch Serverlastiger ist?) oder warum kommt hier ein preg_replace?
Hätte das mit einer for schleife und eine switch anweisung gelöst, indem ich einfach die Variable abfrage und dementsprechend ersetze. -
kill-a-teddy schrieb:
Wenn schon ohne switch und so:
@hackyourlife: Ich hab ne Frage dazu:
Wäre es nicht hierbei sinnvoller str_replace zu benutzen, aufgrund der hohen Suchhäufigkeit von preg_replace (was doch Serverlastiger ist?) oder warum kommt hier ein preg_replace?
Hätte das mit einer for schleife und eine switch anweisung gelöst, indem ich einfach die Variable abfrage und dementsprechend ersetze.<?php $vars = array( 'titel' => 'Motivation im Alltag', 'text' => 'Chakka - Du kannst es ... man muss nur wirklich Wollen, das klappt einfach Alles ...', 'rubrik'=> 'Allgemein', 'datum' => '16.11.2012 (09:27)', 'autor' => 'Donald Duck' ); $tpl = file_get_contents('template.tpl'); foreach($vars as $name => $value) $tpl = str_replace("{{{$name}}}", $value, $tpl); echo($tpl);
Das könnte hier wirklich performanter sein.
Aber ich schrieb doch "mal schnell eine weitere Idee umgesetzt" … dass das die beste Lösung ist hat niemand behauptet -
hackyourlife schrieb:
Aber ich schrieb doch "mal schnell eine weitere Idee umgesetzt" … dass das die beste Lösung ist hat niemand behauptet
Sollte auch keine Kritik werden, bitte nicht falsch auffassen. :) War lediglich eine Interessen's - Frage meinerseits. :P -
Hallo
Danke für die Antworten und Diskussion ...
also ich nehme jetzt mals an, ...
.. dass es mit
performater ist alsstr_replace()
zu verwendenpreg_replace()
... ich habs jetzt so:
foreach($vars as $name => $value) { $upname = strtoupper($name); // ---- Platzhalter im Template $setvalue = stripslashes($value); // ---- Inhalt zum Ersetzen $tpl = str_replace($upname, $setvalue , $tpl); }
anstatt "nur" stripslashes() kann ich ja vor Ausgabe
den Inhalt ($setvalue) noch anders weiter "filtern"
auch mal mit strip_tags() oder htmlentities() o.ä. ...
alos meine Platzhalter sind immer die Array-Keys als Grossbuchstaben
eingefasst in einfach (1x) "geschweiften Klammern" nicht doppelt
... titel ---> {TITEL}
... text ---> {TEXT}
... usw.
Wobei es mit {{ doppelt geschweiften Klammern }} evtl ja doch besser wäre,
damit es eindeutiger als ein Platzhalter zu erkennen ist.
-
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage