Template-System mit Kontrollstrukturen und Schleifen (Zwischenspeicherung)

HansSarpei

Grünschnabel
Hallo,

ich versuche mich gerade an einer Template-Engine, welche u.a. auch Kontrollstrukturen sowie Schleifen unterstützt.
Dabei werden die Templates zunächst geparst und anschließend "compiliert" abgespeichert. Angefangen habe ich zunächst mit Variablen, welche einfach durch <?php echo $var ?> ersetzt wurden (compiliert) und anschließend mit einem Wert besetzt, vereinfacht sah das ganze so aus:
PHP:
protected $registeredVariables = array(); // Enthaelt alle mit einem Wert zu gewiesenen Variablen

public function registerVariable($name, $value) {
   $this->registeredVariables[$name] = $value;
}

public function compileTemplate() {
   // $source = template quelltext
   $source = preg_replace('variable', '<?php $_TPL[variable] ?>', $source);
}

public function showTemplate() {
   if (!$this->isCompiled()) {
      $this->compileTemplate();
   }

   unset($_TPL);
   $_TPL['var'] = $this->registeredVariables;

   require_once($this->compiledTemplate);
}
Wie gesagt, das ganze vereinfacht, damit die Funktionsweise verdeutlicht wird. Das Template wird compiled gespeichert, somit wird das Template nur einmal geparst, die Variablen können jedoch über die $_TPL-Methode variable bleiben (es wird kein konstanter Wert für die Variablen geparst).

Bei nur Variablen funktioniert das ganze noch relativ gut, problematisch wird es jedoch wenn bsw. Funktionen hinzu kommen, welche die Variablen verändern, da ich jedes einzelne "<?php $_TPL" mit "<?php echo $_TPL" ersetzt habe, für eine Bedingung in einer If brauchte ich einfach nur das "<?php" zu entfernen, bei Funktionen kann ich nur nicht mehr einfach nur nach "<?php $_TPL "suchen, da das ganze wenn "<?php funktion($_TPL" heißen würde, sprich der Regex müsste alle Funktionen im Format A-Z finden, dabei würde er aber auch zwangsläufig auf "if(" stoßen und dieses mit "echo if(" ersetzen, nicht gut ...

Als Beispiel noch ein Template vor und nach der "Compilierung":
Vor (ohne Variablen mit Funktionen):
Code:
Hallo {$Bla}

{if true}
If
{/if}

Nach:
Code:
Hallo <?php echo $_TPL['bla']; ?>

<?php if (true): ?>
If
<?php endif; ?>

Vor (mit Variablen mit Funktionen):
Code:
Hallo {$Bla|macheFunktion}

{if $bla == true}
If
{/if}

Nach:
Code:
Hallo <?php echo macheFunktion($_TPL['bla']); ?> // Funktion ersetzt

<?php echo if ($_TPL['bla'] == true): ?> // if wird als Funktion erkannt -> mit echo if ersetzt ...
If
<?php endif; ?>
Natürlich könnte man if einfach vom Regex nicht erfassen lassen, dabei bestände jedoch das Problem auch bei Schleifen oder ähnlichem, d.h. man würde bestimmt 10 Ausnahmen im Regex nicht erfassen lassen ...

Für alternative Vorschläge mit der Umsetzung wäre ich auch offen, jedoch sollte das Template nur einmal geparst werden und dann für längere Zeit gespeichert werden.

Wie kann ich das Problem umgehen? Ich hoffe es ist deutlich geworden was ich meine. Sitz schon seit ein paar Tagen an dem Problem finde jedoch keine Lösung und googeln bringt auch nicht viel, man findet nur Lösungen welche Variablen mit einem konstanten Wert ersetzen ...
 
Hallo und willkommen bei tutorials.de/php.

Vorweg: Schau dir doch an, wie Smarty das macht.

Erläuterung: Ich verstehe ohnehin nicht, warum man nicht PHP selbst als Template-Engine verwendet. Damit kann man alles machen, auch den Vorgang, den du als Compilen bezeichnest, obwohl da nichts kompiliert wird. Sei's drum, das kannst du mit ob_get_contents() viel einfacher lösen.

Warum muss man es sich immer so unnötig kompliziert machen.

Nochmal: PHP ist eine Template-Engine, dafür wurde PHP ursprünglich entwickelt. Wenn du Code von Layout trennen willst, aber dennoch die Vorzüge einer Script-Sprache im Template haben willst, verwende allgemeine Konventionen wie .php für Code und .phtml für Template/HTML/CSS/JS und trenne es auf diese Weise. Schau dir das MVC-Pattern an, das geht eher in die Richtung, in die du wahrscheinlich willst.
 
Zurück