Webdesign in Siegen

Templateengine

Fragen zum Thema PHP können hier gestellt werden

Moderator: Basti

Templateengine

Beitragvon .wired am 06.04.2008, 15:46

So, mal eine Frage zum Aufbau einer Templateengine... Und zwar würd ich gerne wissen, wie ihr eure eigene Templateengine aufbauen würdet. Zum einen kann man da nach dem MVC-Prinzip (model - view - control) vorgehen mithilfe eines Frontcontrollers, so würdet ihr für jede neue Seite auch neue Klassen schreiben müssen. Oder man könnte herkömmlich mit Platzhaltern arbeiten, so setzt man z.B. mitten in eine Tamplatedatei simpel irgendwo "<div id="bla bla">[@Fließtext@]</div>" ein und lässt es ersetzen, dann müsste man für jede neue Seiten halt keine Klasse schreiben, aber immerhin einfach neue Dateien mit den Platzhalterdefinitionen. Wozu würdet ihr tendieren und aus welchen Gründen?

MfG .wired
Bild
Benutzeravatar
.wired
Mitglied
 
Beiträge: 342
Registriert: 24.06.2007
Wohnort: Diekholzen

Re: Templateengine

Beitragvon Avedo am 06.04.2008, 18:25

Also ich würde auf jeden Fall mit Platzhaltern arbeiten. Da würde ich auch zwischen drei Sorten unterscheiden. Platzhalter, die angeben, dass eine bestimmte Datei an ihrer Stelle included werden sollen. Allgemeine Platzhalter und Comment-Platzhalter. Zudem würde ich ermöglichen, dass man Templates verschachtelt. Das ist sehr hilfreich. Zum Beispiel, wenn man das Design der Boxen in einer Sidebar ändern will.
MfG, Andy
Ich bin zu Mimis Religion konvertiert!
I'm so tired of slitting the throats of people calling me a violent psychopath.
Benutzeravatar
Avedo
Mitglied
 
Beiträge: 596
Registriert: 09.12.2007
Wohnort: Göttingen

Re: Templateengine

Beitragvon mAu am 12.04.2008, 13:41

Das geht auch ganz komfortabel mit PHP. Du schreibst dir lediglich ne kleine Klasse alà
Code: Alles auswählen
<?php
class Template
{
    protected $_template;
    protected $_vars;

    public function __construct($template)
    {
        $this->setFile($template);
    }

    public function assign($var, $value)
    {
        if(isset($this->_vars[$var]))
        {
            throw new InvalidArgumentException('Variable has already been set');
        }
       
        $this->_vars[$var] = $value;
    }
   
    public function render()
    {
        ob_start();
        include_once($this->_template);
        $data = ob_get_clean();
   return $data;
    }

   public function setFile($template)
   {
        if(!file_exists($template) || !is_readable($template))
        {
            throw new InvalidArgumentException("Template file {$template} not found");
           
            return false;
        }   
      
      $this->_template = $template;
      
      return true;
   }

    public function __get($var)
    {
        return isset($this->_vars[$var]) ? $this->_vars[$var] : '';
    }
}
?>


Und deine Templates sehen dann etwa so aus:
Code: Alles auswählen
<html>
    <head>
        <title><?php echo $this->title; ?></title>
    </head>
    <body>
        <table>
            <?php foreach($this->users as $user): ?>
            <tr>
                <td><?php echo $user['name']; ?></td>
                <td><?php echo $user['email']; ?></td>
            </tr>
            <?php endforeach; ?>
        </table>
    </body>
</html>


Und die aufzurufende Datei
Code: Alles auswählen
<?php
require_once 'class.Template.php';

$tpl = new Template('index.html');

$users = array(array('name' => 'Foo Bar', 'email' => 'foo@bar.baz'), array('name' => 'Bar Foo', 'email' => 'bar@foo.baz'));

$tpl->assign('users', $users);
$tpl->assign('title', 'Templatetest');

echo $tpl->render();
?>


Keine Garantie auf Funktionsfähigkeit, hab das gerade so runtergetippt, aber vom Prinzip sollte es klar sein :)

Das Gute daran ist, dass du bei Schleifen nicht so ein gefrickel in deiner Klasse hast, denn Schleifen über Platzhalter zu parsen ist schon recht komplex, habs einmal gemacht, aber dadurch verlangsamt sich dein Code doch deutlich!
mAu
Mitglied
 
Beiträge: 13
Registriert: 12.04.2008

Re: Templateengine

Beitragvon Manuel am 12.04.2008, 13:51

Hi mAu!

Aber genau das "<td><?php echo $user['email']; ?></td>" würde ich persönlich nicht mehr haben wollen und das ist quasi der Hauptgrund, warum ich Templates verwende. Mir ist es zudem wichtig, dass ich keine Schleifen mehr in den HTML-Code reinschreiben muss, denn das machts meist sehr häßlich.
Falsch ist die Idee demnach nicht, aber ich würde dennoch die andere Variante bevorzugen.

Lg,
Manuel ;-]
Benutzeravatar
Manuel
Site Admin
 
Beiträge: 8912
Registriert: 10.12.2004
Wohnort: Asbach

Re: Templateengine

Beitragvon mAu am 12.04.2008, 15:14

Über das Thema wurde und wird ja im Web viel Diskutiert. Im Endeffekt gibt es nicht DIE Lösung. Jeder sollte es so machen wie er will. Ich finde nur, dass man sich über eine Templateengine, welche zusätzliche Tags/Befehle einführt, nur alles komplizierter macht, da man diese zusätzlich "lernen" muss.
Weiterhin finde ich das auslagern von Schleifen in den Programmcode (ich gehe mal aus, Manuel, dass du es so meinst, dass man ein extra Template hat, welches dann geparsed wird, der Rückgabewert dann wiederum in ein anderes Template als "normale" Variable eingebunden wird) nicht sonderlich toll, da man dann mit sehr vielen Templatedateien hantieren muss.
Und bedenkt, PHP war ursprünglich ja auch als eine Art Templateengine konzipiert worden :)
mAu
Mitglied
 
Beiträge: 13
Registriert: 12.04.2008

Re: Templateengine

Beitragvon Manuel am 12.04.2008, 17:12

Ja das stimmt wohl, es führen viele Wege nach Rom. Es ist auf jeden Fall eine Frage des Geschmacks und was man für sich selbst dann am besten verwenden kann, ist ebenfalls jedem selbst überlassen.
Ich persönlich bin jedenfalls froh, dass ich somit PHP und HTML sehr sauber voneinander trennen kann. Sicherlich ist es oft etwas umständlich, aber das Erlernen der neuen Tags würde ich auf gar keinen Fall als Kontra sehen, denn das geht bei den meisten TemplateEngines innerhalb weniger Minuten. Wichtig ist lediglich, dass der Gedanke dahinter verstanden wird und man weiss, wann was ausgeführt wird, quasi wie bei der OpenGL-Pipeline.

Hast du dir mal TinyButStrong angeschaut? Das ist wirklich klasse und du brauchst auch nicht unendlich viele Templatedateien. Lediglich eine PHP- und eine TPL-Datei und schon kanns los gehn :)

Lg,
Manuel ;-]
Benutzeravatar
Manuel
Site Admin
 
Beiträge: 8912
Registriert: 10.12.2004
Wohnort: Asbach

Re: Templateengine

Beitragvon mAu am 12.04.2008, 17:33

Ich meine, dass ich die schon mal angetestet hab. Aber ich persönlich halte nicht mehr viel von Templateengines, wie gesagt :) Also die Version, wie ich sie oben beschrieben habe, benutze ich schon, um die Präsentationsschicht von der eigendlichen Anwendung zu trennen.
Oft wird ja auch der Grund angeführt, dass der Designer, sollten denn mehrere Leute an einem Projekt beteiligt sein, durch eine zwischengeschaltete Templateengine keinen Zugriff auf die Applikation an sich hat und somit die Verarbeitung nicht stören kann (da er ja nur auf die Befehle der Engine zugreifen kann). Aber da denke ich, sollte man schon so weit Vertrauen in seinen Designer haben, um den oben beschriebenen Weg zu gehen (ohne Templateengine).
mAu
Mitglied
 
Beiträge: 13
Registriert: 12.04.2008

Re: Templateengine

Beitragvon Avedo am 13.04.2008, 10:13

Hallo!
Ich löse das lieber auch ähnlich wie Manuel ohne PHP-Code, also nur mit Platzhaltern. Hab mal kurz meine alte TemplateEngine rausgekramt. Vielleicht hilft sie ja jemandem weiter. Werde den Code noch ein bisschen besser für euch kommentieren und noch ein paar Sachen verbessern (War so ziemlich meine erste Klasse). Kann noch ein bisschen dauern. Bin gerade etwas im Stress. Über Anregungen, Meinungen und Hilfestellungen bin ich natürlich, wie immer, auch glücklich.

temaplate.php
Code: Alles auswählen
<pre>

<?php 
error_reporting(E_ALL);

/***
* Template class allows filling templates with life

* @package Template
* @version 0.5.6
* @author Andreas Wilhelm <Andreas2209@web.de>
* @copyright Andreas Wilhelm
**/ 
class Template
{

   /* Template variables */
   private static $tmp_dir;                  // Path to templates
   private static $l_delimiter = '{$';         // Left delimeter for standard placeholders
   private static $r_delimiter = '}';            // Right delimeter for standard placeholders
   private static $l_delimiter_c = '\{\*';         // Left delimeter for comments
   private static $r_delimiter_c = '\*\}';         // Right delimeter for comments
   private static $l_delimiter_i = '{';         // Left delimeter for includes
   private static $r_delimiter_i = '}';         // Right delimeter for includes
   private static $tmp_file;               // Path of template-file
   private static $tmp_name;               // Filename of template
   private static $template;               // Substance of the Template

   /**
   * Cunstructor - Is called if a entity of the class is build
   *
   * @access public
   * @param Str $dir
   * @return boolean
   */
   public function __construct($dir = '')
   {      
      if (!empty($dir))
      {      
         $this->tmp_dir = $dir;
         return true;
      }
      else
      {
         return true;       
      }
      
   }

   /**
   * load() - Loads template file
   *
   * @access public
   * @param Str $file
   * @return String
   */
   public function load($file = '')
   {   
      if (empty($file))
      {
         echo 'There is no filename';
         exit;
      }
      
      $this->tmp_file = $this->tmp_dir.$file;

      if($tpl = file_get_contents($this->tmp_file))
      {
         $this->template = $tpl;
         $this->replace($tpl);
      }
         
      else
      {
         return false;
      }
      
      return $tpl;       
   }

   /**
   * replace() - Replaces placeholder for includes and comments
   *
   * @access public
   * @param Str $str contains the template
   * @return String
   */
   protected function replace($str)
   {   
      // replace includes ( {include file="..."} )
      while(preg_match('/'.$this->l_delimiter_i.'include*=*\"(.*)\"'.$this->r_delimiter_i.'/isUe', $str)) {
         $str = preg_replace('/{include*=*\"(.*)\"}/isUe', '$this->parse(("\\1"))', $str);
      }

      // delete comments ( {* thecomment *} )
      $str = preg_replace("/".$this->l_delimiter_c."(.*)".$this->r_delimiter_c."/isUe", "", $str);
      
      $this->template = $str;
      
      return $str;
   }

   /**
   * assign() - Replaces standard placeholders like {$placeholder}
   *
   * @access public
   * @param Str $replace contains the name of the placeholder
   * @param Str $replacement contains the value the placeholder should replaced with
   * @return String
   */
   public function assign($replace, $replacement)
   {   
      $this->template = str_replace($this->l_delimiter.$replace.$this->r_delimiter, $replacement, $this->template);
      return  $this->template;
   }

   /**
   * parse() - Parses a file and saves it in a string
   *
   * @access public
   * @param Str $file a file path
   * @return String
   */
   public function parse($file='file.php')
   {   
      ob_start();
      include($file);
      $file = ob_get_contents();
      ob_end_clean();
      return $file;
   }

   /**
   * out() - Returs whole and parsed template
   *
   * @access public
   * @param Str $tpl contains the template
   * @return String
   */
   public function out($tpl) {
      
      echo $tpl;
      return true;
   }
}
?>

</pre>


Hier noch ein kleines Beispiel:
index.php
Code: Alles auswählen
<?php   
   $content= 'Lorem ipsum dolor sit amet!';

   require_once("template.php");
   $tpl = new Template('templates/');
   $str = $tpl->load('template.tpl');
   $str = $tpl->assign('name','Besucher');
   $str = $tpl->assign('time', date('d.m.Y'));
   $str = $tpl->assign('copyright', date('Y'));
   $str = $tpl->assign('content', $content);
   $tpl->out($str);   
?>
Ich bin zu Mimis Religion konvertiert!
I'm so tired of slitting the throats of people calling me a violent psychopath.
Benutzeravatar
Avedo
Mitglied
 
Beiträge: 596
Registriert: 09.12.2007
Wohnort: Göttingen

Re: Templateengine

Beitragvon Manuel am 13.04.2008, 12:28

Was heißt denn alt? Wie lange ist das denn her und wie sauber ist der Quellcode, ohne dass ich jetzt genauer reinschauen muss? Sonst wäre das doch fast ein Tutorial wert, was sicherlich auch als Codeschnipsel mit ein paar Kommentaren dabei reichen würde. ;)
Benutzeravatar
Manuel
Site Admin
 
Beiträge: 8912
Registriert: 10.12.2004
Wohnort: Asbach

Re: Templateengine

Beitragvon Avedo am 13.04.2008, 12:40

Also das ganze ist so ca. 4 Jahre alt. Stammt also noch aus meinen Anfängen mit PHP. Der Code ist relativ ordentlich. Habe noch ein paar Sachen vor einigen Wochen angepasst, was die Kommentierung angeht. Das verschachteln von Templates ist hiermit zwar etwas aufwendig, aber mit Clonen der Objekte möglich. Habe leider keine Zeit für weitere Beispiele. Habe am Samstag Abi-Klausur Deutsch geschrieben und es folgen am Dienstag Politik, Donnerstag Mathe und abschließen am übernächsten Montag Geschichte. Es bleibt also noch einiges zu tun. Kann aber gerne in naher Zukunft mal ein kleines Tutorial dazu schreiben.
MfG, Andy
Ich bin zu Mimis Religion konvertiert!
I'm so tired of slitting the throats of people calling me a violent psychopath.
Benutzeravatar
Avedo
Mitglied
 
Beiträge: 596
Registriert: 09.12.2007
Wohnort: Göttingen

Re: Templateengine

Beitragvon .wired am 13.04.2008, 12:56

Gut, ich gehe einfach mal davon aus, dass du vor dem Posten noch ein paar Veränderungen reingebracht hast, sonst wärst du PHP damals ja seiner Zeit voraus gewesen (==> __construct...) ;) Täusche ich mich, oder hast du da auch ein wenig von phpBB damals gelernt? Einige Passagen kommen mir nämlich recht bekannt vor ;) (Bitte versteh mich nicht falsch, soll jetzt kein Vorwurf sein :)

MfG .wired

Noch ein Nachtrag: Mal auch einfach eine Diskussion anzetteln. Und zwar:

Im Grunde ist PHP bereits eine Templatesprache, also wozu gibt es denn nun die Templateengine? Ist das nicht eigentlich überflüssig? Warum nicht, wie mAu gesagt hat mit "<?=$inhalt; ?> und Ähnlichem arbeiten? Eigentlich baut man mit der Templateengine nur einen Präprozessor für einen Präprozessor, und das ist überflüssig und sogar noch performancelastiger... Und selbst der Codeunfähigste Designer, der ein Tamplate baut, wird sich die paar PHP-Befehle einprägen können, da sie im Grunde genauso arbeiten wie halt {inhalt} oder bei Blöcken äquivalent dazu while()... => {loop} oder was da so der Standard bei den Templateengines ist...

Wie steht ihr nun dazu? Argumente gegen eine Engine habe ich wohl doch genug geliefert, oder? ;)
Bild
Benutzeravatar
.wired
Mitglied
 
Beiträge: 342
Registriert: 24.06.2007
Wohnort: Diekholzen

Re: Templateengine

Beitragvon Avedo am 13.04.2008, 13:52

Das ist dazu dar, um Design und Code zu trennen. So können Designer und Coder vollkommen unabhängig arbeiten. Zudem kann man durch die Verschachtelung von Templates und dieser Methode ganz einfach zum Beispiel neue Boxen in der Sidebar hinzufügen, die einen neuen aktiven Inhalt haben. Von phpBB habe ich mir eigentlich nichts abgeschaut. Es geht eigentlich fast nicht anders. Aber ich habe vor einigen Monaten fast alle meine Scripte auf Basis von PHP5 gebracht. Daher auch der Constructor.
MfG, Andy
Ich bin zu Mimis Religion konvertiert!
I'm so tired of slitting the throats of people calling me a violent psychopath.
Benutzeravatar
Avedo
Mitglied
 
Beiträge: 596
Registriert: 09.12.2007
Wohnort: Göttingen

Re: Templateengine

Beitragvon .wired am 13.04.2008, 14:04

Nun, ob man nun als Begrenzer "{" oder "<?=" benutzt, wird sogar den Designer wenig stören (Wie ich oben bereits erwähnt habe ;) ) Die Templatedateien selber kann man auch wieder untereinander verschachteln, und der Code ist auch vom Design getrennt. Beispiel:

Code: Alles auswählen
template.tpl
#############

<body>
<table>
<th><?=$ueberschrift; ?></th>
<tr><td><? require_once('navigation.tpl'); ?></td><td><?=$hauptinhalt; ?></td></tr>
</table>


index.php
#############

$ueberschrift = 'Hallo Welt!';
$besucher = mysql_query(... Liest die Anzahl aus dem Counter ab...);
$hauptinhalt = <<< INHALT
Hallo und herzlich willkommen auf Hallo Welt!
Wir freuen uns sehr, dass Sie uns besuchen. Sie
sind übrigens unser '$besucher'er Besucher!
Viel Spaß noch!
INHALT;


Ich glaube ich muss das Beispiel nicht noch weiter ausarbeiten, oder? ;) PHP ist nunmal von Anfang an bereits eine Templatesprache, also wozu diese unnötige Templateengine? Gebt mir mehr Argumente für eine Templateengine, ich bin nämlich gerade tatsächlich am Überlegen, ob sich dieser ganze Aufwand und der Leistungsschwund lohnt ;)

MfG .wired
Bild
Benutzeravatar
.wired
Mitglied
 
Beiträge: 342
Registriert: 24.06.2007
Wohnort: Diekholzen

Re: Templateengine

Beitragvon mAu am 14.04.2008, 10:21

Glaub mir, er lohnt sich definitiv nicht (also für mich :)). Wenn du alleine an einem Projekt arbeitest, steht so eine komplexe Templateengine gar nicht zur Debatte. Und als kleinen Bonus hat man im Allgemeinen - ein guten Editor vorausgesetzt - Syntaxhighlighting sowohl für das HTML-Markup, sowie den PHP-Teil in der Anwendung :)

Und Andreas (Avedo):
Das ist dazu dar, um Design und Code zu trennen. [...]


Nun ja, in gewisser Hinsicht sind die Befehle der Templateengine ja auch als Code zu sehen, denn eine Trennung von Code & Design ist bei dynamischen Seiten nicht zu Realisieren. Einzig die Geschäfts-/Anwendungslogik kann man von der Darstellungslogik trennen.
Z.B: Ob ein Schriftzug bei eingeloggtem Benutzer fett ausgegeben werde soll, bei Gästen jedoch kursiv, hat in der Anwendungslogik einer Webseite nichts verloren, sowas gehört in das Template.
mAu
Mitglied
 
Beiträge: 13
Registriert: 12.04.2008

Re: Templateengine

Beitragvon Avedo am 14.04.2008, 10:59

Das heißt du würdest die volle Programmlogik, zum Beispiel um zu Überprüfen, welche Boxen es momentan in der Sidebar gibt, in eine Datei auslagern, dort die Daten meinetwegen aus einer Datenbank holen und den HTML-Code in einer Schleife erzeugen lassen? Abschließend das ganze via PHP in das Template includen? Ist es da nicht einfacher, wenn der Designer, der nur über HTML und CSS Kenntnisse verfügt nur drei Platzhalter an diesen Stellen einsetzen muss? Der Programmierer kann sich dann darum kümmern, dass an diesen Stellen das richtige erscheint bzw. die verschiedenen Templates von verschiedenen Anwendungen (Foren, Gästebüchern, Chats, News, etc.) zusammengefügt werden? Das kann dann in dem Fall doch ganz einfach eine zentrale index.php machen. Solange ich nur Variablen als Platzhalter benötige, wie von dir bereits vorgeschlagen, Mauricio, dann macht es natürlich Sinn nur auf die Funktionen von PHP zu bauen, aber sobald das ganze eine Logik enthält, sollte soetwas aus Templates gehalten werden oder nicht? Auf jeden Fall solte man generell auf eine der beiden Methoden zurückgreifen, um den Gesamtumfang eines Projekts möglichst klein zu halten, da man vorallem bei größeren Projekten mit aufwendigen Layouts, das ganze so etwas kompakter und übersichtlicher gestallten kann, da man nicht immer und immer wieder die Grundstruktur abspeichert.
MfG, Andy
Ich bin zu Mimis Religion konvertiert!
I'm so tired of slitting the throats of people calling me a violent psychopath.
Benutzeravatar
Avedo
Mitglied
 
Beiträge: 596
Registriert: 09.12.2007
Wohnort: Göttingen

Nächste

Zurück zu PHP

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast