fastix®: Mal was zu den ungeheuer komplizierten Template-Engines

Beitrag lesen

Moin!

Ich glaube kaum, dass ein unbedarfter Benutzer die Smarty Sprache beherrscht.

Dem stimme ich zu. Allerdings gebe ich zu bedenken, dass Smarty keine alleinstehende Applikation ist, ja explizit nicht für unbedarfte Anwender geschrieben ist. Insofern gäbe es durchaus Probleme bei Webseiten, bei denen Inhalt (Texte), Layout (grafische Gestaltung) und Programmierung auch personell getrennt sind. Allerdings gibt es hier einen Programmierer, der eben kein unbedarfter Benutzer ist und dem grafisch orientierten "Templatefritze" Support leisten kann.

Was (das eigentlich tolle!) Smarty betrifft habe ich - wegen des Funktionsumfanges - hin und wieder meine Bauchschmerzen hinsichtlich der Effizienz. Ich weiß, dass Smarty - zum Ausgleich - auch Caching-Mechanismen zur Verfügung stellt. Nur ist das - in einfachen Fällen - alles wieder "overhead" und jeder "overhead" macht mir eben etwas Bauchschmerzen, da ich auf Grund des Umfanges der Software diese wieder nicht verstehe, deren Quelltext aus rein zeitlichen Gründen nicht prüfen kann.

Meine, in einfachen Fällen bevorzugte Methode ist auch ganz ähnlich der hier schon genannten, also etwa:

  
$strVor='$arTemplate[\'';  
$strNach='\']';  
foreach (array_keys($arTemplate) as $key) {  
    $arSearch[]=$strVor.$key.$strNach;  
    $arReplace[]=$arTemplate[$key];  
}  
print str_replace($arSearch, $arReplace, file_get_contents($arTemplate['TemplateFile']));  

Das geht schneller als man gucken kann. Die Prüfung ist auch ganz einfach: Man sehe sich den Output an :)
Natürlich geht es auch anders. Für jeden Aufruf im Template wird der Rückgabewert einer Funktion, eventuell unter Übergabe von Werten aufgerufen:

Im Template:
<myExec:myHallo>Welt</myExec>

Im PHP:

  
  
print execFunctionsInTpl(file_get_contents($strTemplateFileName));  
exit;  
  
function execFunctionsInTpl($str) {  
	$suchmuster = '/<myExec:(.*)>(.*)<\/myExec>/e';  
	return preg_replace($suchmuster, "execFunction('\\1','\\2')", $str);  
}  
  
function execFunction($fnName, $strValue) {  
     if ('my' != substr($fnName,0,2)) {  
          die ("Netter Versuch mit Funktion: $fnName.<br>\nExit!\n");  
     }  
  
     if (function_exists($fnName)) {  
          $str="return $fnName('$strValue');";  
          return eval($str);  
     } else {  
         die ("Fatal: Die Funktion $fnName ist nicht implementiert!\n");  
     }  
}  
  
function myHallo($str) {  
    return 'Hallo, '.$str."!\n";  
}  

Das geht, zur Vermeidung mehrere Durchläufe, natürlich auch mit bloßen Variablen, kann aber gefährlich sein:

<myExec:myGetOut>str</myExec>

dann muss natürlich die Funktion myGetOut() vorhanden sein:

function myGetOut($str) {  
    return $$str;  
}

Wenn man jetzt noch ein paar Funktionen in einem Include unterbringt, dann hat man fast zusammen, was Smarty kann... Ich wüsste jetzt auch nicht, welche der von Smarty gebotenen Funktion ich nicht ohne weiteres selbst in PHP coden könnte.

Nehmen wir z.B. mal aus dem Smarty-Crashkurs:

<table>  
{section name=mysec loop=$name}  
{strip}  
   <tr bgcolor="{cycle values="#eeeeee,#dddddd"}">  
      <td>{$name[mysec]}</td>  
   </tr>  
{/strip}  
{/section}  
</table>

das 'cycle values="#eeeeee,#dddddd"' sieht ja ganz nett aus...;

  
$intKlassen=2;  
$arTemplate['Tabelle']='<table><tbody>';  
$z=0;  
foreach ($arTabelle as $arZeile) {  
     $arTemplate['Tabelle']=.'<tr class="bgColor_'.($z % $intKlassen).'">';  
     foreach ($arZeile as $item) {  
         $arTemplate['Tabelle'].='<td>'.$arZeilen[$item].'</td>';  
     }  
     $z ++;  
     $arTemplate['Tabelle'].='</tr>';  
}  
$arTemplate['Tabelle'].='</tbody></table>';  

Im Template: steht dann nur: $arTemplate['Tabelle'], das versteht auch der Template-Designer. Die Farbe der Zeilen kommt eben in den Stylesheet als:

tr.bgColor_0 {background-color:#eee;}  
tr._bgColor1 {background-color:#ddd;}

(wo sie auch hin gehört) - und ich wüsste nicht, was Smarty hier besser kann als ich, denn ich kann auch:

tr.bgColor_0:hover, tr.bgColor_1:hover {background-color:#ffa;} - und da ist alles schön im CSS zusammen.  
  
  
Noch besser ist fast:  
  
[code lang=php]<div>{$smarty.now|date_format:"%Y-%m-%d"}</div>

vers.:
$arTemplate['heute']=date('Y-m-d');

Allerdings erspart mir da Smarty eine simple Zeile Code. Aber ob es sich wirklich lohnt, deshalb Smarty zu lernen? Immerhin könnte es auch bei Mehrsprachigkeit contraproduktiv sein:

$_SESSION['lang']='de'; # im Endeffekt aus Browsereinstellungen, Benutzereingaben, Domain, URL, ...  
  
$arDateFormat['de_de']='d.m.Y'; # aus Konfiguration  
$arDateFormat['fr_fr']='d/m/Y';  
$arDateFormat['en_us']='m.d.Y';  
...  
$arDateFormat['iso8601']='Y-m-d';  
  
if ( isset($arDateFormat[$_SESSION['lang']]) ) {  
    $arTemplate['heute']=date($arDateFormat[$_SESSION['lang']]);  
} else {  
    $arTemplate['heute']=date($arDateFormat['iso8601']);  
}

ist deutlich flexibler.

Eines will ich aber feststellen: Anders als mit Templates will ich gar nicht mehr arbeiten. In einem Spezialfall habe ich sogar sowas implementiert wie:

<uebersetze>Preis</uebersetze>: <currency>$arTemplate['Preis']</currency>

Dann muss natürlich nach dem Ersetzen der Inhalte nochmals das Template "geparst" werden und es müssen die entsprechenden Funktionen ausgeführt werden. Geht so ähnlich, wie oben beschrieben.

Klar. Das könnte Smarty bestimmt auch. Aber die Verwendung muss man eben von Fall zu Fall entscheiden. Es kann mit Smarty einfacher und schneller gehen - es muss aber nicht. Und in vielen Fällen glaube ich nicht daran.

MFFG (Mit freundlich- friedfertigem Grinsen)

fastix