[PHP] Einfache Templating-Engine

d4f

Kaffee? Wo?
Hier ein kurzes Script um ein "umgedrehtes require" zu realisieren mit welchem die Ausgabedatei in eine andere reingeladen werden kann:

Code:
<?php
define("PAGE_DEFAULT",'main');

define("BASE_DIR",dirname(__FILE__));

//Find requested page
$frame_page = isset($_GET['page']) ? $_GET['page'] : PAGE_DEFAULT;
$frame_page = str_replace(array("..",".","/","\\"),"",$frame_page);

//Check if page exists
$frame_page = ($frame_page != 'index' && is_readable(BASE_DIR.'/'.$frame_page.'.htm')) ? $frame_page : PAGE_DEFAULT;

//Load page
$frame_dependency = $frame_page.'.htm';
while(!is_int($frame_dependency)) {
	$SHOWDEP = true;
	$frame_dependency_curr = $frame_dependency;
	$frame_dependency = require BASE_DIR.'/'.$frame_dependency_curr;
	ob_start();
	$SHOWDEP = false;
	require BASE_DIR.'/'.$frame_dependency_curr;
	$CONTENT = ob_get_contents();
	ob_end_clean();
}
?>

Einziger Haken: man muss index.php?page=<SEITE> aufrufen und <SEITE> muss im gleichen Ordner liegen sowie die Datei-Endung .htm haben (was aber weiterhin PHP-Code in der Datei erlaubt)
Zumindest erstere Einschraenkung liesse sich mittels htaccess einfach wieder in eine "SEO" URL umbiegen.

Anwendungsbeispiel:

template.htm
Code:
<html>
<body>
[HIER-HEADER-EINFUEGEN] <!-- DAS HIER IST KEIN TEMPLATE-ELEMENT sondern Platzfueller! Das Template benutzt ausschliesslich PHP! -->
<div id="content">
<?php echo $CONTENT; ?>
</div>
</body>
</html>

main.htm
Code:
<?php if($SHOWDEP) return 'template.htm'; ?>
<b>Hallo</b> :D


Im groben fuehrt die index.php die main.htm aus und erfaehrt dass diese eigentlich ein Teil der template.htm sein soll. Der Inhalt der Datei wird somit in der Variable $CONTENT gespeichert und die template.htm ausgefuehrt. Diese gibt den Code dann aus.
Zu beachten ist dass die template.htm in der main.htm deklarierte Variablen, Funktionen und Klassen benutzen kann, somit beispielweise im Header der Benutzername angezeigt werden kann.
template.htm kann natuerlich auch wieder auf andere Dateien verweisen aber ich will das Beispiel nicht verkomplizieren ;)

Feedback erwuenscht.
 
Last edited by a moderator:
Hallo,

der Ansatz gefällt mir gut. Ich benutze für meine Projekte eine ähnliches System. Ein kleiner Hinweiß: Anstelle von <?=$CONTENT;?> besser <?php echo $content; ?> verwenden, weil die "short tags" entfernt werden.
 
Danke fuer den Hinweis, ich habe die Beispiele entsprechend korrigiert.

Noch eine kleine Anmerkung zum Script: ein Opcode-Cacher ist Pflicht wenn es im Produktivbetrieb eingesetzt werden soll da alle Dateien 2x eingelesen und somit ansonsten 2x durch den Interpreter gejagt werden!


Hier eine Version die ohne das 2. Einlesen funktioniert:
PHP:
<?php
define("PAGE_DEFAULT",'main');

define("BASE_DIR",dirname(__FILE__));

//Find requested page
$frame_page = isset($_GET['page']) ? $_GET['page'] : PAGE_DEFAULT;
$frame_page = str_replace(array("..",".","/","\\"),"",$frame_page);

//Check if page exists
$frame_page = ($frame_page != 'index' && is_readable(BASE_DIR.'/'.$frame_page.'.htm')) ? $frame_page : PAGE_DEFAULT;

//Load page
$frame_dependency = $frame_page.'.htm';
while(!is_int($frame_dependency)) {
	ob_start();
	$frame_dependency = require BASE_DIR.'/'.$frame_dependency;
	$CONTENT = ob_get_contents();
	ob_end_clean();
}
echo $CONTENT;
?>

main.html:
Code:
Mein Inhalt
<?php return 'template.htm'; ?>

template.html:
keine Aenderung!

Man beachte dass der Return jetzt am ENDE statt am ANFANG der Datei liegt!
Alternativ kann man das ganze in eine Variable speichern lassen, es gibt mehrere Loesungsmethoden ;)
 
Last edited by a moderator:
Unter allen bekannteren PHP Accelerator habe ich bislang nur mit eAccelerator und xCache gearbeitet, allerdings mit ersterem Probleme gehabt (alte Versionen im Cache, Absturz des FCGI-Prozesses bei Compile-Fehler, ...) waehrend xCache bislang immer stabil lief.

Wem allerdings die Performance einer statischen/pseudodynamischen Webseite am Herzen liegt sollte eher in Richtung XSLT und SSI gehen denn php-basierende Template-Bastler ;)
 
Das ist schon wieder so simple, dass ich mich frage ob ein solches Konstrukt noch den Namen "Templateing-Engine" tragen sollte. ;)

Was mich definitiv stört:
<SEITE> muss im gleichen Ordner liegen sowie die Datei-Endung .htm haben
Ein Aufruf des Template-namen mit '.htm' am Ende zeigt dem Surfer also meinen eigenen PHP-Code? Und damit z.T. die Geschäftslogik?
So was wäre zumindest für mich ein No-GO.

Auch sehe ich hier kein echtes Potenzial für nested-templates.

huschi.
 
Ein Aufruf des Template-namen mit '.htm' am Ende zeigt dem Surfer also meinen eigenen PHP-Code?
Entweder man sperrt Dateien mit der Endung .htm oder man laesst .htm als PHP parsen. Ersteres klingt aber besser ;)
Allerdings kann man indem man alle ".htm" in ".php" umaendert auch Dateien mit der Endung nehmen, ich wollte es nur huebscher trennen.

Allerdings sollte man doch -auch wenn es kein full-fledged MVC ist- doch die Logik und das Template trennen ^^

Auch sehe ich hier kein echtes Potenzial für nested-templates.
Dann musst du immer header und footer includen was aber wiederum bedeutend unflexibler ist. Ich bevorzuge es in die umgedrehte Richtung ^^

Das ist schon wieder so simple, dass ich mich frage ob ein solches Konstrukt noch den Namen "Templateing-Engine" tragen sollte.
Ich mich auch =) Aber in Ermangeln eines besseren Namen.. :P
Man kann auch argumentieren dass das Template-System PHP als Templating-Sprache zulaesst und somit sehr flexibel ist ;)
 
Entweder man sperrt Dateien mit der Endung .htm oder man laesst .htm als PHP parsen.
Ohne groß Diskutieren zu wollen... aber damit wälzt Du die Problematik von Dir (dem Entwickler) auf die Anwender ab.
Dazu kommt, dass damit der Konfigurationsaufwand teilweise höher wird, als der Nutzen.
Einfache abwandlung: .tmpl.php oder tmpl_*.php verwenden. Oder noch einfacher: ein eigenes Verzeichnis für die Templates.

Man kann auch argumentieren dass das Template-System PHP als Templating-Sprache zulaesst und somit sehr flexibel ist ;)
PHP als "Templating-Sprache" zu bezeichnen ist vollkommen korrekt. Aber eine "Engine" ist nochmal was anderes, oder? ;)

huschi.
 
Back
Top