#1 15. April 2009 Templateengine Öhm, ich bastel grad ma wieder was in php und wollt mir so ne kleine templateengine bastewln, sodass ich im template nur stehn hab "{content}" und das ersetzt wird durch den content. Ists iwie möglich, dass ich dieses "{content}" dann durch ne Funktion ersetze? Mit str_replace() wirds nämlich nix, was ja auch klar ist. Hoffe, dass es da iwie ne Möglichkeit gibt, an der Stelle den content durchn include ersetzen zu lassen. Bin auch gern offen für andere Lösungsmöglichkeiten. + Multi-Zitat Zitieren
#2 15. April 2009 AW: Templateengine hallo, hier ist meine Templateklasse... sicher ausbaufähig... class_template.php PHP: <?class template { var $inhalt ; //Inhalt der gesamten Templatedatei var $tmp_file ; //Templatedatei var $mem_loop = '' ; //Speicher für Loop-Inhalt (Platzhalter + HTML Code) // __construct wird ausgeführt, wenn die Klasse zum ersten mal aufgerufen wird // Sie prüft die Templatedatei auf ihre Existenz. // Wenn es sie nicht gibt, wird das Script abgebrochen und eine Fehlermeldung ausgegeben public function __construct ( $file , $error = '' ) { // Überprüft, ob die Datei existiert, wenn ja dann if( file_exists ( $file )) { $this -> tmp_file = $file ; $this -> inhalt = file_get_contents ( $file ); } // Wenn die Datei nicht exisitert, wird die Fehlermeldung ausgegeben und das Script // abgebrochen. else { exit( "Die Datei <b>" . $file . "</b> konnte nicht gefunden werden!<br> Bitte stellen Sie sicher, dass die Datei exisitert!" ); } } // Die Funktion "ersetzen" wird aufgerufen um einzelne Platzhalter zu ersetzen public function ersetzen ( $key , $value ) { $suche = '/\{' . $key . '\}/' ; $this -> inhalt = preg_replace ( $suche , $value , $this -> inhalt , 1 ); } // Die Funktion "getLoop" wird aufgerufen um Loops zu ersetzen, // die in der HTML-Datei festgelegt wurden durch {loop:BEZEICHNUNG} ... {loop:end} public function getLoop ( $name , $anzahl , $replacement ) { // Speichern der Anzahl an Datensätzen; // ermittelt mit z.B. mysql_num_rows(..); $this -> data_count = $anzahl ; // Suchsyntax für das Durchsuchen der Templatedatei nach Loops // eventuelle Verbesserung: // Suchsyntax: '!\{loop:($name)\}(.*)\{loop:end\}!sU' $regex = '!\{loop:([^\}]+)\}(.*)\{loop:end\}!sU' ; // Sucht nach den Loops in der Templatedatei. preg_match_all ( $regex , $this -> inhalt , $match ); if (isset( $match [ 1 ]) && isset( $match [ 2 ])) { $total = sizeof ( $match [ 1 ]); for ( $i = 0 ; $i < $total ; $i ++) { // Entfernt Whitespaces am Anfang eines Strings // Mehr unter: http://at.php.net/manual/de/function.trim.php $nameObj = trim ( $match [ 1 ][ $i ]); // Speichert den HTML-Code zwischen {loop..} ... {loop:end} $codeSnippet = $match [ 2 ][ $i ]; // Loop Bauen! $this -> buildLoop ( $nameObj , $codeSnippet , $replacement ); } } // ersetzen des Loops mit den Platzhaltern $this -> replaceLoop (); } // Mit dieser Funktion wird der Loop zusammengebaut // Sprich: der HTML-Code wird sooft kopiert, wie es Datensätze gibt private function buildLoop ( $name , $snippet , $replacement ) { foreach ( $replacement as $replacer ) { // HTML-Code wird dieser Variabel zugeschrieben // und am Ende erneut hinzugefügt $this -> mem_loop .= $snippet ; // $i wird benötigt um zu erkennen wie viele Felder ersetzt werden müssen. $i = 1 ; do { foreach ( $replacer as $key => $value ) { // Baut die Suchsyntax zusammen // { } sind deliminater und müssen dh deaktiviert werden. // Andernfalls werden sie bei der Ausgbae auch angezeigt! // preg_quote baut den String zusammen. // ohne preg_quote ist der "." ein spezielles Zeichen.... // mehr Infos: http://regexp-evaluator.de/tutorial/metazeichen/#punkt $searcher = "~\{" . preg_quote ( $name . "." . $key , '~' ) . "\}~" ; // Ersetzt die Ergebnisse der Suchsyntax $this -> mem_loop = preg_replace ( $searcher , $value , $this -> mem_loop , 1 ); } $i ++; } while ( $i != count ( $replacer )); } } // Die Funktion replaceLoop wird von der Funktion buildLoop aufgerufen // Sie ersetzt den fertigen Loop mit den Platzhaltern in der Templatedatei private function replaceLoop () { // Suchsyntax zusammenbauen $regex = '!\{loop:([^\}]+)\}(.*)\{loop:end\}!sU' ; // Suchen und ersetzen in der eigentlichen Templatedatei! $this -> inhalt = preg_replace ( $regex , $this -> mem_loop , $this -> inhalt , 1 ); } // Gibt den kompletten Inhalt einer Templatedatei zurück und gibt sie nicht aus! public function returnTemplate () { return $this -> inhalt ; } // Die Funktion "ausgabe" gibt das Template aus! public function ausgabe () { echo $this -> inhalt ; }} ?> kurze erklärung: faq.php PHP: <?include( "class_template.php" ); 1 //Laden der Templatedatei $faq_tmp_file = "design/templates/faq.html" ; $faq_template = new template ( $faq_tmp_file ); //Abfrage der FAQ aus der Datenbank und anschließend speichern in einen 2. dim. Array $sql_a = mysql_query ( "SELECT `Frage` , `Antwort` FROM `faq`" ); $num_a = mysql_num_rows ( $sql_a ); $faq = array(); while( $res_a = mysql_fetch_array ( $sql_a )){ $faq [] = array( "frage" => $res_a [ 0 ], "antwort" => $res_a [ 1 ]); } //einzelne Felder ersetzen $faq_template -> ersetzen ( "UEBERSCHRIFT" , "hier deine statische Überschrift" ); //Ersetzen des Loops in der HTML Datei $faq_template -> getLoop ( "faq" , $num_a , $faq ); //Ausgabe der Templatedatei $inhalt = $faq_template -> returnTemplate (); ?> Glaube erklärt alles was php mäßig angeht... hier die templatefile (vorschlag) faq.html HTML: <div id="inhalt3"> <h1>{UEBERSCHRIFT}</h1> {loop:faq} <p> <a href="#">{faq.frage} <span>{faq.antwort}</span> </a> </p><br /> {loop:end} </div> bw wäre eventuell nett ^^ falls fragen, einfach stellen^^ + Multi-Zitat Zitieren
#3 15. April 2009 AW: Templateengine Ähm verstehe ich richtig du möchtest {content} durch z.b. function xyz() auswechseln? + Multi-Zitat Zitieren
#5 15. April 2009 AW: Templateengine ich rate dir von einer template-enegine ab, denn für einen anfänger isses fast nicht möglich was performantes zu erstellen. warum schreibst du nicht einfach <?php yxz(); ?> an die stelle wo du die funktion haben willst? php ist doch eh schon eine templatesprache ansonsten, wenn du wirklich eine template-engine haben willst, schau dir mal [g]php smarty[/g] an oder erstell dir was simples (smarty liefert ja grundlagen). (smarty hat nen haufen overhead -> würde ich an deiner stelle eher meiden) das templatesystem des [g]woltlab community framework[/g]s ist recht gut (zum abschaun ) + Multi-Zitat Zitieren
#6 18. April 2009 AW: Templateengine warum soll str_replace() nicht gehen? du kannst auch arrays übergeben. das ganze kannste dann auch mit funktionen und so weiter verbessern oder per schleife in mysql abfragen für newsletter o.Ä. PHP: <? $sHTML = " <p>News: {NewsHeader}, erstellt um {NewsCreateDate}</p> " ; $aFind = array ( 0 => "{NewsHeader}" , 1 => "{NewsCreateDate}" ); $aReplace = array ( 0 => "Template" , 1 => "10.10.2009" ; ); echo str_replace ( $aFind , $aReplace , $sHTML ); ausgabe ist etwas wie Code: <p>News: Template, erstellt um 10.10.2009</p> + Multi-Zitat Zitieren
#7 19. April 2009 AW: Templateengine Man kann sehr wohl einen String den man ersetzen will durch eine Funktion behandeln lassen, wenn man statt PHP: $suche = '/\{' . $key . '\}/' ; $this -> inhalt = preg_replace ( $suche , $value , $this -> inhalt , 1 ); das hier verwendet: PHP: $suche = '/\{' . $key . '\}/' ; $this -> inhalt = preg_replace_callback ( $suche , 'funktionsname' , $this -> inhalt ); und dann in der funktion PHP: function funktionsname ( $treffer ) { return $treffer [ 0 ]. "Hier gebe ich noch was zum treffer dazu" ;} die treffer auswertet (Beispiel siehe unter http://www.php.net/manual/de/function.preg-replace-callback.php). + Multi-Zitat Zitieren
#8 19. April 2009 AW: Templateengine nicht gestestet, aber simpler gehts wohl kaum: PHP: <? php function tpl_save_string ( $string ) { static $strings = array(); if( $string === true ) return $strings ; return '@@string_' . ( array_push ( $strings , stripslashes ( $string )) - 1 ) . '@@' ; } function tpl_no_way ( $func ) { exit( $func . ' is not allowed!' ); } function tpl_exec_tag ( $tag ) { $tag = preg_replace ( '~("(?:[^\\\\"]+|\\\\.)*"|\'' . '(?:[^\\\\\']+|\\\\.)*\')~e' , 'tpl_save_string(\'\\1\')' , $tag ); $doNotWant = array( 'eval' , 'exit' , 'die' , 'shell_exec' , 'exec' , 'popen' , 'pcntl_[a-z_0-9]+' , 'fsockopen' , 'socket_[a-z_0-9]+' 'system' , 'file_[a-z_0-9]+' , 'fopen' ); foreach( $doNotWant as $f ) $tag = preg_replace ( '~(' . $f . ')\s*\(~i' , 'tpl_no_way(\'\\1\'' , $tag ); foreach( tpl_save_string ( true ) as $i => $str ) $tag = str_replace ( '@@string_' . $i . '@@' , $str , $tag ); if(!eval( 'return false;' . $tag . ';' )) exit( 'syntax-error in tag: ' . $tag ); eval( $tag . ';' ); } function tpl_display ( $file ) { ( $content = file_get_contents ( $file )) || exit( 'file not readable' ); preg_replace ( '~\{(.*)\}~eU' , 'tpl_exec_tag(\'\\1\')' , $content ); } ?> HTML: hallo {print "welt"} + Multi-Zitat Zitieren
#9 20. April 2009 AW: Templateengine PHP: $html = str_replace ( '{content}' , contentgenerierfunktion (), $html ); Wie waers damit? + Multi-Zitat Zitieren
#11 20. April 2009 AW: Templateengine Ich muss mich Murdoc anschließen! Sich selber eine Template-Engine "zusammenzuschrauben" ist für Anfänger nicht unbedingt ein sinnvolles und einfaches Unterfangen . Außerdem gibt es ja schon einen Haufen fertiger Codes, die du ausprobieren und evaluieren könntest. Wie von Murdoc erwähnt, ist Smarty da sicherlich nicht der schlechteste Einstieg. Smarty ist meiner Meinung nach sehr einfach zu benutzen, gerade für Anfänger. Es gibt eine große Community und du findest eigentlich auf alle Fragen die passende Antwort. Der Aufruf von Funktionen innerhalb eines Smarty-Templates mit einem Template-Tag ist von Haus aus implementiert, von daher haste da eigentlich schon das, was du brauchst. Den Overhead von Smarty kannst du im weitesten Sinne umgehen, indem du dein System hybride aufbaust, sprich du speicherst/cachest die Ausgabe von Smarty und erstellst meinetwegen statische HTML-Seiten. Schau dir bei Gelegenheit mal das Zend Framework an. Es ist objektorientiert, kostenlos und bietet dir die Möglichkeit, alle Komponenten einzeln zu benutzen (z.B. Views (Templates), Datenbankabstraktion, Caching-Mechanismen etc.). Optimal, wenn du nicht jedes mal das Rad neu erfinden willst. MFG Chronos + Multi-Zitat Zitieren