Template System

  • Themenstarter Themenstarter Bgag
  • Beginndatum Beginndatum
B

Bgag

Hallo!
Ich habe schon viel über Template-systeme gelesen und mir smarty angeschaut, aber weitergekommen bin ich nur teilweise. Die meisten Tutorials haben mir nicht geholfen und tutorials.de habe ich schon vollkommen auf den Kopf gestellt. NICHTS!
Ich bräuchte folglich eure Hilfe.

Also ein Template-System ermöglicht die Trennung von Webdesign und Programmcode, damit der Webdesigner un der Programmierer getrennt arbeiten können. Wie funktioniert also das ganze?

Man hat zwei Hauptdateien:
1) Die Template Datei: template.tpl (in meinem Beispiel)
2) Die Datei, die den Programmcode in das Template einfügt: index.php (in meinem Beispiel)

So die Template-Datei enthält nun reinen HTML-CODE, in den, an den Stellen wo später der Programmcode stehen soll, Platzhalter eingesetzt sind. Diese können beliebig aussehen. Z.B.: {Platzhalter} oder [Platzhalter] oder #Platzhalter#
Code:

HTML:
<html> <head> <title>HALLO!</title> </head> <body> Zuletzt geändert am {lastchange}! {content} </body> </html>

Doch was macht nun meine index.php? Als erstes bekommt sie per link den Namen der Datei übermittelt, die anstelle des Platzhalters {content} eingefügt werden soll.
Code:

HTML:
<a href="www.deine-domain.de?content=cont_news.php" class="impressum">News</a>

Hier soll für den Platzhalter {content} also der Inhalt der Datei cont_news.php eingefügt werden. Des weiteren soll der Platzhalter {lastchange} durch die aktuelle Uhrzeit ersetzt werden. Wie sieht nun das Script dazu aus?
PHP-Code:
PHP:
<?php

	/* Deklarieren von Inhalten, die auf PHP basieren und immer für bestimmte Platzhalter eingesetzt werden müssen */ 
	$lastchange = filemtime(basename($_SERVER['PHP_SELF']));
	$last_change = date("d.m.Y H:i", $lastchange);
	$copyright = date("Y");
	$url = $_SERVER['PHP_SELF'];



/* Die Klasse Template*/
class template {

	private $t; 
		
	/* Template anlegen */
	public function __construct($template) {
	$this->t = $template;
	}
	
	/* Den Content laden */
	public function loadcontent($content) {
	ob_start();
	include $content;
	$newcont = ob_get_contents();
	ob_end_clean();
	return $newcont;
	}
	
	/* Den einzelnen Platzhaltern ihre Inhalte zuweisen */ 
	public function setvalue( $name , $inhalt ) {
	$insert .= "{" . $name . "}" . $inhalt . "{/" . $name . "}";
	}
	
	/* Platzhalter im Template finden, ersetzen und letztendlich das ganze ausgeben*/
	public function inserts($insert) {
		$html = file_get_contents( $this->t );
		preg_match_all("|{[^}]+}(.*){/[^}]+}|U", $insert, $extract, PREG_PATTERN_ORDER);
		for	($i=0;$i<count($extract[0]);$i++)	{
			$search = substr($extract[0][$i],0,strpos($extract[0][$i],"}")+1);
			$replace = $extract[1][$i];
			$html = str_replace($search, $replace, $html);
		}
		echo $html;
	}

}


$t = new Template("template.tpl");
$t->loadcontent($_GET['content']);
$t->setvalue( "change" , $last_change );
$t->setvalue( "server" , $url );
$t->setvalue( "copy" , $copyright );
$t->setvalue( "content" , $newcont );
$t->inserts( $insert );

?>

So! Wie einigen gleich auffallen wird, führe ich den Inhalt der per Link übergebenen Datei cont_news.php per include() aus, halte jedoch die Ausgabe mit ob_start() zurück und speicher die Rückgabe stattdessen in einer Variable. Diese Variable enthält nun nur noch Design-Code, denn der Programmcode wurde bereits ausgeführt.

Nun kann man das irgendwie auch mit eval() lösen, wobei aber weitere Probleme auftreten. Und zwar gibt es bei eval() auch eine Fehlermeldung, wenn der von eval() bearbeitete String keinen php-code enthält, was in meinem content nicht automatisch der fall sein muss, denn ich kann an Stelle des Platzhalters {content} sowohl php-code als auch einfachen html-code einfügen wollen. Zudem schafft eval() eine große Sicherheitslücke, da jeglicher Code der mit eval() behandelt wird auch ausgeführt wird. So wirdauch der Code ausgeführt, den ein User in ein Gästebuch schreibt, das dann seine Einträge mit Hilfe einer Template -Engine Kreiert.

Ich will also einfach nur das unveränderliche Design vom variablen Content trennen, um für mich die Sache einfacher und übersichtlicher zu halten.

Nun endlich meine Fragen:
Wo liegt mein Fehler in meinen Überlegungen bzw. in meinen Scripten?
Gibt es Verbesserungsvorschläge?
Eine Möglichkeit den Code zu verkürzen.

Ich entschuldige meine langen Ausführungen, aber ich dachte es wäre wichtig, um euch auf den aktuellen Stand meiner Erkenntnis zu bringen. Ich möchte des weiteren an dem Vorhaben dies selbst umzusetzen (natürlich manchmal mit eurer hilfe ;D ) festhalten und nicht auf Smarty / FastTemplate / EasyTemplate und COKG ausweichen.

Ich bedanke mich für euer Verständnis und eure Geduld!
MfG, Andy
 
Ein mir aufgefallener Fehler ist, dass die $insert-Variable nur innerhalb der Aufrufe der Methoden setvalue() und inserts() existiert.
 
Also wenn du nicht ausweichen willst auf andere Templates, wie wäre es mit meinem Tutorial?
Okay, eventuell ist es noch nicht freigeschaltet, daher mal mein Vorschlag:

Du erstellst eine variables.php, ich benutze immer die Struktur:

root/languages/german/main.php
PHP:
$lang['hallo'] = 'Hallo';
root/templates/standard/index.tpl
PHP:
<?php echo $lang['hallo']; ?>
root/index.php
PHP:
include('languages/german/main.php');
include('templates/standard/index.tpl');

Und schon kannste indem du jedesmal dies hier benutzt <?php echo $lang['hallo']; ?> eine Variabel einsetzen. ;)
Soweit habe ich das verstanden, oder suchst du noch etwas anderes?
 
@Radiate: Ich verstehe, was du meinst, sehe allerdings den Sinn dahinter nicht. Ich wollte mein Design schon complett vom Programmcode trennen. Kannst mir ja mal den Link zu deinem Tutorial geben.

@Gumbo: Soll das heiße, dass ich diese Variable global machen muss? Oder wie muss ich das ändern, damit es stimmt?

Danke für eure schnelle Antwort!
MfG, Andy
 
Also soweit ich das sehe, kann man unmöglich den Code vom Design trennen!
Das ist einfach undenkbar. ;)
Der Grund dürfte klar sein, weil du variabeln einsetzen willst um Daten aus einer Datenbank einzusehen, daher weiß ich gerade nicht ob mein Tutorial über diesen Link angezeigt wird, wenn ja dann ist es hier:

http://www.tutorials.de/forum/tutorials-inbox/276217-trennung-vom-code-und-html-durch-variablen.html

Also meine Variante benötigt keine Template-Engine, lediglich gute übersicht der Verzeichnisse es seidenn du ballerst alles in ein Verzeichnis. ;)

Gruß
 
Nein das heißt es nicht unbedingt. Es reicht sie in der Klasseninstanz global verfügbar zu haben. Eine eigenes Klassenattribut reicht dafür also aus.
 
Also auf das Tutorial darf ich schonmal nicht zugreifen. Da habe ich keine Rechte.
Also soweit ich das sehe, kann man unmöglich den Code vom Design trennen!
Und warum sollte das nicht gehen? Mann erstellt eine reine Html- oder besser noch XHTML-Seite, die das Grundlegende Design beinhaltet. An all jene Stellen, wo nun allerdings php-code eingefügt werden soll, setzt man, wie von mir beschrieben Platzhalter.

Ein anderes Script greift sich diese Html oder XHtml datei und sucht nach Platzhaltern. Wenn sie diese Gefunden hat ersetzt es sie automatisch speichert das ganze in einer Variable und gibt es aus.
Der Grund dürfte klar sein, weil du variabeln einsetzen willst um Daten aus einer Datenbank einzusehen.
Datenbank? Wer? Wie? WO? WAS? Grund? Hab ich doch nichts von hgesagt und selbst wenn dann leuchtet mir dein Grund nicht ein. :confused:

Nein das heißt es nicht unbedingt. Es reicht sie in der Klasseninstanz global verfügbar zu haben. Eine eigenes Klassenattribut reicht dafür also aus.
Also so?
PHP:
<?php
class template {

	private $t;
	private $insert; 
        .......
}
?>

MfG, Andy
 
Zuletzt bearbeitet von einem Moderator:
Öhm, sry. ;)
Datenbank war natürlich ein Weg, im Normalfall nimmt man Variabeln oder Einträge aus einer File namens *.php.
Aber auch hier müssen deine Sogenannten Platzhalter in den Design Code rein, sprich, sie werden ersetzt durch deinen in irgendeiner Datei festgelegten Werte.
So, nun ist hier meine Theory aber richtig, statt solche Platzhalter kannste doch auch dieses hier benutzen, ist halt nur etwas länger als {WERT} , meine -> <?php echo $var['WERT']; ?>.

Verstehst du nun was ich meine?^^
 
Variablen sind auch nichts anderes als Platzhalter für andere Werte, nämlich für die Variablenwerte.
 
Ja das wusste ich, doch um solche Platzhalter zu benutzen benötigt man doch meines Wissens nach eine Engine, also eine Template-Engine, oder nicht?
Und ich habe mir diese Technik von phpBB abgeschaut, die verwenden genau das wie ich es benutze. ;)

Also nicht falsch verstehen, ich benutze deren Technik!
 
Zurück