Advanced Features Objekte Smarty erlaubt es, auf PHP Objekt durch das Template zuzugreifen. Dafür gibt es zwei Wege. Der erste ist, Objekte zu registrieren und wie auf eine eigene Funktion zuzugreifen. Der andere Weg ist, das Objekt dem Template zuzuweisen und darauf wie auf andere Variablen zuzugreifen. Die erste Methode hat eine nettere Template Syntax und ist sicherer da der Zugriff auf ein registriertes Objekt mit Sicherheitseinstellungen kontrolliert werden kann. Der Nachteil ist, dass registrierte Objekte nicht in Loops verwendet werden können. Welchen Weg Sie einschlagen wird von Ihren Bedürfnissen definiert, die erste Methode ist jedoch zu bevorzugen. Wenn die Sicherheitsfunktionen eingeschaltet sind, können keine private Methoden (solche die einen '_'-Prefix tragen) aufgerufen werden. Wenn eine Methode und eine Eigeschaft mit dem gleichen Namen existieren wird die Methode verwendet. Sie können den Zugriff auf Methoden und Eigenschaften einschränken indem Sie sie als Array als dritten Registrationsparameter übergeben. Normalerweise werden Parameter welche einem Objekt via Template übergeben werden genau so übergeben wie dies bei normalen eigenen Funktionen der Fall ist. Das erste Objekt ist ein assoziatives Array und das zweite das Smarty Objekt selbst. Wenn Sie die Parameter einzeln erhalten möchten können Sie den vierten Parameter auf FALSE setzen. Der optionale fünfte Parameter hat nur einen Effekt wenn format = true ist und eine Liste von Methoden enthält die als Block verarbeitet werden sollen. Das bedeutet, dass solche Methoden ein schliessendes Tag im Template enthalten müssen ({foobar->meth2}...{/foobar->meth2}) und die Parameter zu den Funktionen die selbe Syntax haben wie block-function-plugins: sie erhalten also die 4 Parameter $params, $content, &$smarty und &$repeat, und verhalten sich auch sonst wie block-function-plugins. registierte oder zugewiesene Objekte verwenden <?php // das objekt class My_Object { function meth1($params, &$smarty_obj) { return "meine meth1"; } } $myobj = new My_Object; // objekt registrieren (referenz) $smarty->register_object("foobar",$myobj); // zugriff auf methoden und eigeschaften einschränken $smarty->register_object("foobar",$myobj,array('meth1','meth2','prop1')); // wenn wir das traditionelle parameter format verwenden wollen, übergeben wir false für den parameter format $smarty->register_object("foobar",$myobj,null,false); // objekte zuweisen (auch via referenz möglich) $smarty->assign_by_ref("myobj", $myobj); $smarty->display("index.tpl"); ?> TEMPLATE: {* zugriff auf ein registriertes objekt *} {foobar->meth1 p1="foo" p2=$bar} {* ausgabe zuweisen *} {foobar->meth1 p1="foo" p2=$bar assign="output"} ausgabe war: {$output} {* auf unser zugewiesenes objekt zugreiffen *} {$myobj->meth1("foo",$bar)} 'pre'-Filter Template 'pre'-Filter sind Filter, welche auf das Template vor dessen Kompilierung angewendet werden. Dies ist nützlich, um zum Beispiel Kommentare zu entfernen oder um den Inhalt des Templates zu analysieren. 'pre'-Filter können auf verschiedene Arten geladen werden. Man kann sie registrieren, aus dem Plugin-Verzeichnis mit load_filter() laden oder $autoload_filters verwenden. Smarty übergibt der Funktion als ersten Parameter den Template-Quellcode und erwartet als Rückgabewert den bearbeiteten Quellcode. Template 'pre'-Filter verwenden <?php // fügen Sie folgende Zeilen in Ihre Applikation ein function remove_dw_comments($tpl_source, &$smarty) { return preg_replace("/<!--#.*-->/U","",$tpl_source); } // registrieren Sie den 'pre'-Filter $smarty->register_prefilter("remove_dw_comments"); $smarty->display("index.tpl"); ?> {* Smarty Template 'index.tpl' *} <!--# diese Zeile wird vom 'pre'-Filter entfernt--> 'post'-Filter Template 'post'-Filter sind Filter, welche auf das Template nach dessen Kompilierung angewendet werden. 'post'-Filter können auf verschiedene Arten geladen werden. Man kann sie registrieren, aus dem Plugin-Verzeichnis mit load_filter() laden oder $autoload_filters verwenden. Smarty übergibt der Funktion als ersten Parameter den Template-Quellcode und erwartet als Rückgabewert den bearbeiteten Quellcode. Template 'post'-Filter verwenden <?php // fügen Sie folgende Zeilen in Ihre Applikation ein function add_header_comment($tpl_source, &$smarty) { return "<?php echo \"<!-- Created by Smarty! -->\n\" ?>\n".$tpl_source; } // registrieren Sie den 'post'-Filter $smarty->register_postfilter("add_header_comment"); $smarty->display("index.tpl"); ?> {* kompiliertes Smarty Template 'index.tpl' *} <!-- Created by Smarty! --> {* Rest des Template Inhalts... *} Ausgabefilter Wenn ein Template mit 'display()' oder 'fetch()' benutzt wird, kann die Ausgabe durch verschieden Ausgabefilter geschleust werden. Der Unterschied zu 'post'-Filtern ist, dass Ausgabefilter auf die durch 'fetch()' oder 'display()' erzeugte Ausgabe angewendet werden, 'post'-Filter aber auf das Kompilat vor seiner Speicherung im Dateisystem. Ausgabefilter können auf verschiede Arten geladen werden. Man kann sie registrieren, aus dem Plugin-Verzeichnis mit load_filter() laden oder $autoload_filters verwenden. Smarty übergibt der Funktion als ersten Parameter die Template-Ausgabe und erwartet als Rückgabewert die bearbeitete Ausgabe. Ausgabefilter verwenden <?php // fügen Sie folgende Zeilen in Ihre Applikation ein function protect_email($tpl_output, &$smarty) { $tpl_output = preg_replace('!(\S+)@([a-zA-Z0-9\.\-]+\.([a-zA-Z]{2,3}|[0-9]{1,3}))!', '$1%40$2', $tpl_output); return $tpl_output; } // Ausgabefilter registrieren $smarty->register_outputfilter("protect_email"); $smarty->display("index.tpl"); // von nun an erhalten alle ausgegebenen e-mail Adressen einen // einfach Schutz vor Spambots. ?> Cache Handler Funktion Als Alternative zum normalen dateibasierten Caching-Mechanismus können Sie eine eigene Cache-Handler Funktion zum lesen, schreiben und löschen von Cache-Dateien definieren. Schreiben Sie eine Funktion in Ihrer Applikation, die Smarty als Cache-Handler verwenden soll und weisen Sie deren Name der Variable $cache_handler_func zu. Smarty wird von da an Ihre Funktion zur Bearbeitung des Caches verwenden. Als erster Parameter wird die 'action' mit einem der folgendende Werte übergeben: 'read', 'write' und 'clear'. Als zweiter Parameter wird das Smarty-Objekt übergeben, als dritter der gecachte Inhalt. Bei einem 'write' übergibt Smarty den gecachten Inhalt, bei 'read' übergibt Smarty die Variable als Referenz und erwartet, dass Ihre Funktion die Inhalte zuweist. Bei 'clear' können Sie eine dummy-Variable übergeben. Als vierter Parameter wird der Template-Name übergeben (verwendet bei 'write'/'read'), als fünfter Parameter die 'cache_id' (optional) und als sechster die 'compile_id' (auch optional). Beispiel mit einer MySQL Datenbank als Datenquelle <?php /* Beispiel Anwendung: include('Smarty.class.php'); include('mysql_cache_handler.php'); $smarty = new Smarty; $smarty->cache_handler_func = 'mysql_cache_handler'; $smarty->display('index.tpl'); die Datenbank hat folgendes Format: create database SMARTY_CACHE; create table CACHE_PAGES( CacheID char(32) PRIMARY KEY, CacheContents MEDIUMTEXT NOT NULL ); */ function mysql_cache_handler($action, &$smarty_obj, &$cache_content, $tpl_file=null, $cache_id=null, $compile_id=null) { // Datenbank Host, Benutzer und Passwort festlegen $db_host = 'localhost'; $db_user = 'myuser'; $db_pass = 'mypass'; $db_name = 'SMARTY_CACHE'; $use_gzip = false; // enmalige 'cache_id' erzeugen $CacheID = md5($tpl_file.$cache_id.$compile_id); if(! $link = mysql_pconnect($db_host, $db_user, $db_pass)) { $smarty_obj->_trigger_error_msg("cache_handler: could not connect to database"); return false; } mysql_select_db($db_name); switch ($action) { case 'read': // Cache aus der Datenbank lesen $results = mysql_query("select CacheContents from CACHE_PAGES where CacheID='$CacheID'"); if(!$results) { $smarty_obj->_trigger_error_msg("cache_handler: query failed."); } $row = mysql_fetch_array($results,MYSQL_ASSOC); if($use_gzip && function_exists("gzuncompress")) { $cache_contents = gzuncompress($row["CacheContents"]); } else { $cache_contents = $row["CacheContents"]; } $return = $results; break; case 'write': // Cache in Datenbank speichern if($use_gzip && function_exists("gzcompress")) { // compress the contents for storage efficiency $contents = gzcompress($cache_content); } else { $contents = $cache_content; } $results = mysql_query("replace into CACHE_PAGES values( '$CacheID', '".addslashes($contents)."') "); if(!$results) { $smarty_obj->_trigger_error_msg("cache_handler: query failed."); } $return = $results; break; case 'clear': // Cache Informationen löschen if(empty($cache_id) && empty($compile_id) && empty($tpl_file)) { // alle löschen $results = mysql_query("delete from CACHE_PAGES"); } else { $results = mysql_query("delete from CACHE_PAGES where CacheID='$CacheID'"); } if(!$results) { $smarty_obj->_trigger_error_msg("cache_handler: query failed."); } $return = $results; break; default: // Fehler, unbekannte 'action' $smarty_obj->_trigger_error_msg("cache_handler: unknown action \"$action\""); $return = false; break; } mysql_close($link); return $return; } ?> Ressourcen Ein Template kann aus verschiedenen Quellen bezogen werden. Wenn Sie ein Template mit 'display()' ausgeben, die Ausgabe mit 'fetch()' in einer Variablen speichern oder innnerhalb eines Template ein weiteres Template einbinden, müssen Sie den Ressourcen-Typ, gefolgt von Pfad und Template-Namen angeben. Wenn kein Resourcetyp angegeben wird, wird $default_resource_type verwendet. Templates aus dem '$template_dir' Templates aus dem '$template_dir' benötigen normalerweise keinen Ressourcen-Typ, es wird jedoch empfohlen 'file:' zu verwenden. Übergeben Sie einfach den Pfad, in dem sich das Template relativ zu '$template_dir' befindet. Templates aus '$template_dir' verwenden // im PHP-Skript $smarty->display("index.tpl"); $smarty->display("admin/menu.tpl"); $smarty->display("file:admin/menu.tpl"); // entspricht der vorigen Zeile {* im Smarty Template *} {include file="index.tpl"} {include file="file:index.tpl"} {* entspricht der vorigen Zeile *} Templates aus beliebigen Verzeichnissen Templates ausserhalb von '$template_dir' benötigen den 'file:' Ressourcen-Typ, gefolgt von absolutem Pfadnamen und Templatenamen. Templates aus beliebigen Verzeichnissen benutzen // im PHP-Skript $smarty->display("file:/export/templates/index.tpl"); $smarty->display("file:/path/to/my/templates/menu.tpl"); {* im Smarty Template *} {include file="file:/usr/local/share/templates/navigation.tpl"} Windows Dateipfade Wenn Sie auf einer Windows-Maschine arbeiten, enthalten absoluten Dateipfade normalerweise den Laufwerksbuchstaben (C:). Stellen Sie sicher, dass alle Pfade den Ressourcen-Typ 'file:' haben, um Namespace-Konflikten vorzubeugen. Templates aus Windows Dateipfaden verwenden // im PHP-Skript $smarty->display("file:C:/export/templates/index.tpl"); $smarty->display("file:F:/path/to/my/templates/menu.tpl"); {* im Smarty Template *} {include file="file:D:/usr/local/share/templates/navigation.tpl"} Templates aus anderen Quellen Sie können Templates aus jeder für PHP verfügbaren Datenquelle beziehen: Datenbanken, Sockets, LDAP, usw. Dazu müssen sie nur ein Ressource-Plugin schreiben und registrieren. Konsultieren Sie den Abschnitt über Ressource-Plugins für mehr Informationen über die Funktionalitäten, die ein derartiges Plugin bereitstellen muss. Achtung: Sie können die interne file Ressource nicht überschreiben. Es steht Ihnen jedoch frei, ein Plugin zu schreiben, das die gewünschte Funktionalität implementiert und es als alternativen Ressource-Typ zu registrieren. Eigene Quellen verwenden // im PHP-Skript // definieren Sie folgende Funktion in Ihrer Applikation function db_get_template ($tpl_name, &tpl_source, &$smarty_obj) { // Datenbankabfrage um unser Template zu laden, // und '$tpl_source' zuzuweisen $sql = new SQL; $sql->query("select tpl_source from my_table where tpl_name='$tpl_name'"); if ($sql->num_rows) { $tpl_source = $sql->record['tpl_source']; return true; } else { return false; } } function db_get_timestamp($tpl_name, &$tpl_timestamp, &$smarty_obj) { // Datenbankabfrage um '$tpl_timestamp' zuzuweisen $sql = new SQL; $sql->query("select tpl_timestamp from my_table where tpl_name='$tpl_name'"); if ($sql->num_rows) { $tpl_timestamp = $sql->record['tpl_timestamp']; return true; } else { return false; } } function db_get_secure($tpl_name, &$smarty_obj) { // angenommen alle Templates sind sicher return true; } function db_get_trusted($tpl_name, &$smarty_obj) { // wird für Templates nicht verwendet } // Ressourcen-Typ 'db:' registrieren $smarty->register_resource("db", array("db_get_template", "db_get_timestamp", "db_get_secure", "db_get_trusted")); // Ressource im PHP-Skript verwenden $smarty->display("db:index.tpl"); {* Ressource in einem Smarty Template verwenden *} {include file="db:/extras/navigation.tpl"} Standard Template-Handler Sie können eine Funktion definieren, die aufgerufen wird, wenn ein Template nicht aus der angegeben Ressource geladen werden konnte. Dies ist z. B. nützlich, wenn Sie fehlende Templates on-the-fly generieren wollen. Standard Template-Handler verwenden <?php // fügen Sie folgende Zeilen in Ihre Applikation ein function make_template ($resource_type, $resource_name, &$template_source, &$template_timestamp, &$smarty_obj) { if( $resource_type == 'file' ) { if ( ! is_readable ( $resource_name )) { // erzeuge Template-Datei, gib Inhalte zurück $template_source = "This is a new template."; $template_timestamp = time(); $smarty_obj->_write_file($resource_name, $template_source); return true; } } else { // keine Datei return false; } } // Standard Handler definieren $smarty->default_template_handler_func = 'make_template'; ?>