HTML Template + PHP Script

Sephcom

Mitglied
Ich habe folgendes Problem...
ich habe mir ein HTML-Template zusammengebastelt und möchte nun die PHP-Datei dazu schreiben, die die entsprechenden Teile ersetzt.

D.h.
ein Teil des Templates sieht beispielsweise so aus:
<title>{title]</title>

Jetzt möchte ich, das die PHP Datei die HTML-Datei einliest und {title} ersetzt
in form von

function title($title){
//hier dann die entsprechenden befehle
}

bekomm das aber iwie nicht so ganz hin o.O
 
z.b.:

PHP:
<TITLE><? ECHO ($title);?></TITLE>

Die Datei des Tepmlates muss natürlich die Endung .php haben, sonst wird die nicht geparst!
 
Hast mich wohl Falsch verstanden...

nochmal..

Ich habe eine HTML Datei (das Template!)
Dort ist alles wichtige Vorgegeben und halt PLATZHALTER für entsprechende Dinge, wie beispielsweise dem Titel

also habe ich in der HTML-Datei stehen: <title>{title}</title>

nun möchte ich eine PHP-Datei erzeugen, die {title} mit dem entsprechenden eingegebene Wert ersetzt

function title($title){ //hier der Code }

diese 2. Datei wird dann an jede weitere PHP-Datei gebunden (require_once) damit ich nicht so elendlig lange Codes pro Datei habe!
Sodass also in der 3. Datei nurnoch steht

<?php

title("blubb");

?>
 
Hallo!
Ließ dir doch mal diesen Thread durch. Da findest du Diskussionen zu allen Ansätzen, die so gängig sind, aber auch die entsprechenden Lösungen.
MfG, Andy
 
Hmm alles nicht so ganz das was ich will...
das klappt auch alles nicht so ganz xD

hab mir schon eins angeguckt, da musste ich iwas schreiben von wegen
$layout = set('title','xxx');
output->$layout

oder iwie sowas

aber das ist doch voll dumm, wenn ich das bei jeder Datei schreiben muss
deshalb wollte ich dann eine Funktion schreiben, die das direkt erledigt

function title($text){
$layout = set('title',$text);
}

sodass ich in der Datei nur schreiben muss

require_once 'functions.php';
title('xxx');

aber das klappt auch nicht so wie ich will -.- alles kakce xD
 
Soetwas wie die Methode titel, die du da gebastelt hast ist, entschuldige meine Ausdrucksweise, absolut daneben. Auf diese Weise verbaust du dir selbst die mehrfache verwendung dieser Klasse. Jedes Webprojekt, dass du im Laufe der Jahre machen wirst ist komplett anders und erfordert komplett andere Daten. Willst du für jedes neue Projekt eine neue Methode deiner Klasse beifügen? Greife doch einfach auf die magischen Funktionen von PHP zurück. Mit __set(), __get() und __call läst sich eine sehr sehr einfache und übersichtliche Klasse basteln, mit der du dieses Problem nicht hast.

PHP:
<?php

/***
* Class Template 
*
* Template class allows filling templates with life.
* Sure this class supports also the nesting of
* different templates. So you can manage superior
* designs and webpages.
*  
* @package Template
* @version 0.3
* @author Mauricio Hannika
* @author Andreas Wilhelm <Andreas2209@web.de>
* @copyright Mauricio Hannika, Andreas Wilhelm
**/  
class Template
{
    protected $template;
    protected $vars;

	/**
	* Constructor - Sets the filename of the template
	*
	* @access public
	* @param Str $template
	* @return Boolean
	*/
	public function __construct($template)
    {
		if( !file_exists($template) || !is_readable($template) )
		{
			throw new Exception('Could not load template file.');
        }   
      
		$this->template = $template;
      
		return true;
    }

    /**
	* __get() - Returns the queried value
	* 
	* @access public
	* @param Str $key
	* @return String
	*/
    public function __get($key)
    {
		return isset($this->vars[$key]) ? $this->vars[$key] : '';
    }

    /**
	* __set() - Replaces the placeholders with the intended content
	* 
	* @access public
	* @param Str $key
	* @param Str $value
	* @return String
	*/
    public function __set($key, $value)
    {
        if(isset($this->vars[$key]))
        {
            throw new Exception($key . ' has already been set.');
        }
       
        $this->vars[$key] = $value;
    }

	/**
	* __call() - Parses a file and returns it
	* 
	* @access public
	* @param Str $path
	* @return String
	*/
	public function __call($path='') 
	{	
		if( empty($path) )
		{
			$path = $this->template;
		}
	
		ob_start(); 
		
		if( !@include_once($path) )
		{
			throw new Exception('Failed to parse file.');			
		}
		
		$parsed = ob_get_contents(); 
		ob_end_clean(); 
		
		return $parsed; 
	}
}
?>
Ein Template dazu könnte so aussehen:
HTML:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de" lang="de">

	<head>			
		<title>&middot; <?= $this->title; ?> &middot;</title>

		<meta name="Title" content="<?= $this->title; ?>" />
		<meta name="Author" content="pseudo@mail.de" />
		<meta name="Publisher" content="pseudo.tld" />
		<meta name="Copyright" content="pseudo.tld" />
		<meta name="Revisit" content="After 2 days" />
		<meta name="Keywords" content="pseudo, test, titel, homepage, website" />
		<meta name="Description" content="Besuchen Sie meine Seite! Es k&ouml;nnte sich lohnen." />
		<meta name="Abstract" content="Visit my website. It'll be great." />
		<meta name="Robots" content="INDEX,FOLLOW" />
		<meta name="Language" content="Deutsch" />
		<meta name="Distribution" content="global" />
		<meta http-equiv="content-Type" content="text/html;charset=iso-8859-1" />
		
		<link rel="stylesheet" type="text/css" href="design.css"/>	
	</head>
		
	<body>
		<div id="page">
		
			<h1 id="headline"><?= $this->title; ?></h1>		
			
			<ul id="navigation">
				<?= $this->navigation; ?>
			</ul>
			
			<div id="content">
				<?= $this->content; ?>
			</div>					
			
			<p id="footer">
				powered by <?= $this->title; ?> © <?= $this->date; ?>				
			</p>
		</div>
	</body>
</html>
Die index.php dazu sieht dann so aus:
PHP:
<style type="text/css">
<!--
	.error {
		text-align: center;
		font-weight: bold;
		background: #FFFFCC;
		border: 1px solid #9F0004; }
-->
</style>

<?php
	try
	{
		// load required classes
		require_once('Template.php');
						
		$mysqli = new mysqli('DB_HOST', 'DB_USER', 'DB_PWD', 'DB_NAME');
			
		$tpl = new Template('layout.html');
			
		if( empty($_GET['site']) )
		{
			$content = $tpl->parse('home.html');
		}
			
		elseif( !isset($_GET['site']) || !file_exists($_GET['site']) || !is_readable($_GET['site']) )
		{
			$content = '<p class="error">Die Seite konnte leider nicht gefunden werden.</p>';
		}
			
		else
		{
			$site = $_GET['site'];
			$content = $tpl->parse($site);
		}
		
		
		$sql = "SELECT 
				*
			FROM
				navigation
			ORDER BY
				name";
		
		// send sql-query
		if ( $result = $mysqli->query($sql) ) 
		{        
			// save result into an array
			$navigation = '';
			while( $row = $result->fetch_assoc() ) 
			{
				$navigation .= '<li><a href="index.php?site='.$row['id'].'">'.$row['name'].'</a></li>';
			}
		}
		
		else
		{
			$navigation = '<b>Die Navigation konnte leider nicht geladen werden.</b>';
		}
		
		$tpl->title = $navigation;
		$tpl->navigation = $navigation;
		$tpl->content = $content;
		$tpl->date = date('Y');
			
		echo $tpl->render();
	}
		
	catch(Exception $e)
	{
		echo '<p class="error">'.$e->getMessage().'</p>';
	}
?>
Denke das ist doch sehr übersichtlich und absolut einfach. Die Methoden render und parse brauchst du im übrigen nicht suchen, da die Methode __call() immer dann aufgerufen wird, wenn eine Methode aufgerufen wird, die nicht existent ist. Um das ganze noch abszurunden, kann man noch die hässliche URL via mod-rewrite verstecken.
MfG, Andy

//EDIT: str_replace ist eine sehr schlechte Idee, da das ein echter Performance Fresser werden kann. Habe ich früher auch gemacht, geht auch für sehr sehr kleine Projekte, ist aber nicht sehr empfehlenswert und, wie man sieht, geht es doch auch sehr sehr viel einfacher.
 
Zuletzt bearbeitet von einem Moderator:
Hier noch eine Weitere Variante davon die besten sachen davon könntes du kombienieren um das ganze zu Optimieren.

PHP:
class Template
{
   protected $template;  /* Template Inhalt */ 
   protected $templateDir;    // Der Ordner in dem sich die Template-Dateien befinden.
   
/**
* Klassen aufruf - Lade Template file von $path
*
* @param Str $path
*/
public function __construct($path = '')
{
 if (file_exists($path) == false)
  {
   throw new Exception ('Template File nicht gefunden path: `' . $path . '`');
  }
 if ($tpl = file_get_contents($path))
  {
    $this->templateDir=dirname($path)."\\";
    $this->replace($tpl); 
  }
}

/**
* replace() - Ersetzt placeholder für includierte Files und Kommentaren
*
* @param Str $str contains the template
* @return String
*/
protected function replace($str)
{
 // Includes ersetzen ( {include file="..."} )
 while(preg_match("/".'{'."include file=\"(.*)\.(.*)\"".'}'."/isUe", $str))
 {
  $str = preg_replace("/".'{'."include file=\"(.*)\.(.*)\"".'}'."/isUe", "file_get_contents(\$this->templateDir.'\\1'.'.'.'\\2')", $str);
 }
 // Kommentare löschen
 $str = preg_replace("/".'\{\*'."(.*)".'\*\}'."/isUe", "", $str);

 $this->template=$str;
}

/**
* assign() - Ersetze den Platzhalter mit dem Inhalt der Variable $replacement
*
* @param Str $placeholder
* @param Str $replacement
* 
*/
public function assign($placeholder, $replacement)
{   
 $this->template = str_replace('{$'.$placeholder.'}', $replacement, $this->template);
 # Wenn Include im Template ist neu Parsen
 if (preg_match("/".'{'."include file=\"(.*)\.(.*)\"".'}'."/isUe", $this->template))
 {
  $this->replace($this->template); 
 }
}

 /**
 * getTpl() - Gibt den Template Inhalt zurück
 *
 * @return String
 */
 public function getTpl()
 {
  return $this->template;
 }
} // Ende Klasse

Anwendungs Beispeil
PHP:
<?
$tpl = new Template('templates\index.tpl');
// Dem Platzhalter $titel den Text "Willkommen" zuweisen
$tpl->assign("title", "Willkommen");
// Dem Platzhalter $name den Text "Benutzer" zuweisen
$tpl->assign("name", "Benutzer");
// Weitere Template file includieren
$tpl->assign("inhalt", '{include file="othertemplate.tpl"}');
//Weiter Platzhalter in dem 2 Template file ersetzen
$tpl->assign("news", "Neue Nachrichten usw.");

// Und das letztendlich das fertige Template ausgeben
echo $tpl->getTpl();

Mfg Splasch
 
Da hier schon mit Code geworfen wird werfe ich mal einen Link zu Code. ;)
Unter http://php-classes.sourceforge.net/ findest Du meine kleine Template-Klasse fuer PHP5.
Dort hast Du dann auch nicht sowas wie $tpl->set('tpl_field','value'), sondern kannst das Feld "direkt" ansprechend, also mittels $tpl->tpl_field.
Dies ist auch der Grund warum die Klasse nur fuer PHP5 verfuegbar ist da hierfuer die Methoden __get() und __set() zum Einsatz kommen.

Ich nutze die Klasse fuer all meine Projekte und bin ziemlich zufrieden mit der Art und Weise wie sie arbeitet.
Code im Template ist hierbei allerdings nicht moeglich, hauptsaechlich weil ich persoenlich dies abartig finde...
 
Zurück