Smarty durch Plugins erweitern In Version 2.0 wurde die Plugin-Architektur eingeführt, welche für fast alle anpassbaren Funktionalitäten verwendet wird. Unter anderem: Funktionen Modifikatoren Block-Funktionen Compiler-Funktionen 'pre'-Filter 'post'-Filter Ausgabefilter Ressourcen Inserts Für die Abwärtskompatibilität wurden das register_* API zur Funktions-Registrierung beibehalten. Haben Sie früher nicht die API-Funktionen benutzt, sondern die Klassen-Variablen $custom_funcs, $custom_mods und andere direkt geändert, müssen Sie Ihre Skripte so anpassen, dass diese das API verwenden. Oder sie implementieren die Funktionalitäten alternativ mit Plugins. Wie Plugins funktionieren Plugins werden immer erst bei Bedarf geladen. Nur die im Template verwendeten Funktionen, Ressourcen, Variablen-Modifikatoren, etc. werden geladen. Des weiteren wird jedes Plugin nur einmal geladen, selbst wenn mehrere Smarty-Instanzen im selben Request erzeugt werden. 'pre'/'post'-Filter machen die Ausnahme. Da sie in den Templates nicht direkt erwähnt werden, müssen sie zu Beginn der Ausführung explizit via API geladen oder registriert werden. Die Reihenfolge der Anwendung mehrerer Filter desselben Typs entspricht der Reihenfolge in der sie geladen/registriert wurden. Die plugins directory Variable kann eine Zeichenkette, oder ein Array mit Verzeichnisnamen sein. Um einen Plugin zu installieren können Sie ihn einfach in einem der Verzeichnisse ablegen. Namenskonvention Plugin-Dateien müssen einer klaren Namenskonvention gehorchen, um von Smarty erkannt zu werden. Die Plugin-Dateien müssen wie folgt benannt werden:
type.name.php
Wobei Typ einen der folgenden Werte haben kann: function modifier block compiler prefilter postfilter outputfilter resource insert und Name ein erlaubter Identifikator (bestehend aus Buchstaben, Zahlen und Unterstrichen) ist. Ein paar Beispiele: function.html_select_date.php, resource.db.php, modifier.spacify.php. Die Plugin-Funktion innerhalb das Plugin-Datei muss wie folgt benannt werden:
smarty_type_name
type und name haben die selbe Bedeutung wie bei den Plugin-Dateien. Smarty gibt Fehlermeldungen aus, falls ein aufgerufenes Plugin nicht existiert, oder eine Datei mit falscher Namensgebung im Verzeichnis gefunden wurde.
Plugins schreiben Plugins können von Smarty automatisch geladen oder zur Laufzeit dynamisch mit den register_* API-Funktionen registriert werden. Um registrierte Plugins wieder zu entfernen, können die unregister_* API-Funktionen verwendet werden. Bei Plugins, die zur Laufzeit geladen werden, müssen keine Namenskonventionen beachtet werden. Wenn ein Plugin auf die Funktionalität eines anderen Plugins angewiesen ist (wie dies bei manchen Smarty Standard-Plugins der Fall ist), sollte folgender Weg gewählt werden, um das benötigte Plugin zu laden: require_once $smarty->_get_plugin_filepath('function', 'html_options'); Das Smarty Objekt wird jedem Plugin immer als letzter Parameter übergeben (ausser bei Variablen-Modifikatoren und bei Blücken wird &$repeat nach dem Smarty Objekt übergeben um Rückwärtskompatibel zu bleiben). Template-Funktionen void smarty_function_name array $params object &$smarty Alle einer Funktion übergebenen Parameter werden in der Variable $params als assoziatives Array abgelegt. Sie können auf diese Werte entweder direkt mit $params['start'] zugreifen oder sie mit extract($params) in die Symbol-Tabelle importieren. Die Ausgabe der Funktion wird verwendet, um das Funktions-Tag im Template (fetch Funktion, zum Beispiel) zu ersetzen. Alternativ kann sie auch etwas tun, ohne eine Ausgabe zurückzuliefern (assign Funktion, zum Beispiel). Falls die Funktion dem Template Variablen zuweisen oder auf eine andere Smarty-Funktionalität zugreifen möchte, kann dazu das übergebene $smarty Objekt verwendet werden. Sehen Sie dazu: register_function(), unregister_function(). Funktionsplugin mit Ausgabe <?php /* * Smarty plugin * ------------------------------------------------------------- * File: function.eightball.php * Type: function * Name: eightball * Purpose: outputs a random magic answer * ------------------------------------------------------------- */ function smarty_function_eightball($params, &$smarty) { $answers = array('Yes', 'No', 'No way', 'Outlook not so good', 'Ask again soon', 'Maybe in your reality'); $result = array_rand($answers); echo $answers[$result]; } ?> Es kann im Template wie folgt angewendet werden: Question: Will we ever have time travel? Answer: {eightball}. Funktionsplugin ohne Ausgabe <?php /* * Smarty plugin * ------------------------------------------------------------- * File: function.assign.php * Type: function * Name: assign * Purpose: assign a value to a template variable * ------------------------------------------------------------- */ function smarty_function_assign($params, &$smarty) { extract($params); if (empty($var)) { $smarty->trigger_error("assign: missing 'var' parameter"); return; } if (!in_array('value', array_keys($params))) { $smarty->trigger_error("assign: missing 'value' parameter"); return; } $smarty->assign($var, $value); } ?> Variablen-Modifikatoren Variablen-Modifikatoren sind kleine Funktionen, die auf eine Variable angewendet werden, bevor sie ausgegeben oder weiterverwendet wird. Variablen-Modifikatoren können aneinadergereiht werden. mixed smarty_modifier_name mixed $value [mixed $param1, ...] Der erste an das Modifikator-Plugin übergebene Parameter ist der Wert mit welchem er arbeiten soll. Die restlichen Parameter sind optional und hängen von den durchzuführenden Operationen ab. Der Modifikator muss das Resultat seiner Verarbeitung zurückgeben. Sehen Sie dazu: register_modifier(), unregister_modifier(). Einfaches Modifikator-Plugin Dieses Plugin dient als Alias einer PHP-Funktion und erwartet keine zusätzlichen Parameter. <?php /* * Smarty plugin * ------------------------------------------------------------- * File: modifier.capitalize.php * Type: modifier * Name: capitalize * Purpose: capitalize words in the string * ------------------------------------------------------------- */ function smarty_modifier_capitalize($string) { return ucwords($string); } ?> Komplexes Modifikator-Plugin <?php /* * Smarty plugin * ------------------------------------------------------------- * File: modifier.truncate.php * Type: modifier * Name: truncate * Purpose: Truncate a string to a certain length if necessary, * optionally splitting in the middle of a word, and * appending the $etc string. * ------------------------------------------------------------- */ function smarty_modifier_truncate($string, $length = 80, $etc = '...', $break_words = false) { if ($length == 0) return ''; if (strlen($string) > $length) { $length -= strlen($etc); $fragment = substr($string, 0, $length+1); if ($break_words) $fragment = substr($fragment, 0, -1); else $fragment = preg_replace('/\s+(\S+)?$/', '', $fragment); return $fragment.$etc; } else return $string; } ?> Block-Funktionen void smarty_function_name array $params mixed $content object &$smarty Block-Funktionen sind Funktionen, die in der Form {func} .. {/func} notiert werden. Mit anderen Worten umschliessen sie einen Template-Abschnitt und arbeiten danach auf dessen Inhalt. Eine Block-Funktion {func} .. {/func} kann nicht mir einer gleichnamigen Template-Funktion {func} überschrieben werden. Ihre Funktions-Implementation wird von Smarty zweimal aufgerufen: einmal für das öffnende und einmal für das schliessende Tag. (konsultieren Sie den Abschnitt zu &$repeat um zu erfahren wie Sie dies ändern können.) Nur das Öffnungs-Tag kann Attribute enthalten. Alle so übergebenen Attribute werden als assoziatives Array $params der Template-Funktion übergeben. Sie können auf die Werte entweder direkt mit $params['start'] zugreifen oder sie mit extract($params) in die Symbol-Tabelle importieren. Die Attribute aus dem Öffnungs-Tag stehen auch beim Aufruf für das schliessende Tag zur Verfügung. Der Inhalt der $content Variable hängt davon ab, ob die Funktion für das öffnende Tag oder für das schliessende Tag aufgerufen wird. Für das öffnende Tag ist der Wert null, für das schliessende Tag ist es der Inhalt des Template-Abschnitts. Achtung: Der Template-Abschnitt den Sie erhalten, wurde bereits von Smarty bearbeitet. Sie erhalten also die Template-Ausgabe, nicht den Template-Quelltext. Der Parameter &$repeat wird als Referenz übergeben und kontrolliert wie oft ein Block dargestellt werden soll. Standardwert von $repeat ist beim ersten Aufruf (für das öffnende Tag) true, danach immer false. Jedes Mal wenn eine Funktion für &$repeat TRUE zurück gibt, wird der Inhalt zwischen {func} .. {/func} erneut mit dem veränderten Inhalt als $content Parameter aufgerufen. Wenn Sie verschachtelte Block-Funktionen haben, können Sie die Eltern-Block-Funktion mit der $smarty->_tag_stack Variable herausfinden. Lassen Sie sich ihren Inhalt mit 'var_dump()' ausgeben. Die Struktur sollte selbsterklärend sein. Sehen Sie dazu: register_block(), unregister_block(). Block-Funktionen <?php /* * Smarty plugin * ------------------------------------------------------------- * File: block.translate.php * Type: block * Name: translate * Purpose: translate a block of text * ------------------------------------------------------------- */ function smarty_block_translate($params, $content, &$smarty) { if (isset($content)) { $lang = $params['lang']; // den $content irgendwie intelligent übersetzuen return $translation; } } Compiler-Funktionen Compiler-Funktionen werden während der Kompilierung des Template aufgerufen. Das ist nützlich, um PHP-Code oder zeitkritische statische Inhalte in ein Template einzufügen. Sind eine Compiler-Funktion und eine eigene Funktion unter dem selben Namen registriert, wird die Compiler-Funktion ausgeführt. mixed smarty_compiler_name string $tag_arg object &$smarty Die Compiler-Funktion erhält zwei Parameter: die Tag-Argument Zeichenkette - also alles ab dem Funktionsnamen bis zum schliessenden Trennzeichen - und das Smarty Objekt. Gibt den PHP-Code zurück, der in das Template eingefügt werden soll. Sehen Sie dazu: register_compiler_function(), unregister_compiler_function(). Einfache Compiler-Funktionen <?php /* * Smarty plugin * ------------------------------------------------------------- * File: compiler.tplheader.php * Type: compiler * Name: tplheader * Purpose: Output header containing the source file name and * the time it was compiled. * ------------------------------------------------------------- */ function smarty_compiler_tplheader($tag_arg, &$smarty) { return "\necho '" . $smarty->_current_file . " compiled at " . date('Y-m-d H:M'). "';"; } ?> Diese Funktion kann aus dem Template wie folgt aufgerufen werden: {* diese Funktion wird nur zum Kompilier-Zeitpunkt ausgeführt *} {tplheader} Der resultierende PHP-Code würde ungefähr so aussehen: <php echo 'index.tpl compiled at 2002-02-20 20:02'; ?> 'pre'/'post'-Filter 'pre'-Filter und 'post'-Filter folgen demselben Konzept. Der einzige Unterschied ist der Zeitpunkt der Ausführung. string smarty_prefilter_name string $source object &$smarty 'pre'-Filter werden verwendet, um die Quellen eines Templates direkt vor der Kompilierung zu verarbeiten. Als erster Parameter wird die Template-Quelle, die möglicherweise bereits durch eine weiteren 'pre'-Filter bearbeitet wurden, übergeben. Das Plugin muss den resultierenden Wert zurückgeben. Achtung: Diese Werte werden nicht gespeichert und nur zum Kompilier-Zeitpunkt verwendet. string smarty_postfilter_name string $compiled object &$smarty 'post'-Filter werden auf die kompilierte Ausgabe direkt vor dem Speichern angewendet. Als erster Parameter wird der kompilierte Template-Code übergeben, der möglicherweise zuvor von anderen 'post'-Filtern bearbeitet wurde. Das Plugin muss den veränderten Template-Code zurückgeben. 'pre'-Filter Plugin <?php /* * Smarty plugin * ------------------------------------------------------------- * File: prefilter.pre01.php * Type: prefilter * Name: pre01 * Purpose: Convert html tags to be lowercase. * ------------------------------------------------------------- */ function smarty_prefilter_pre01($source, &$smarty) { return preg_replace('!<(\w+)[^>]+>!e', 'strtolower("$1")', $source); } ?> 'post'-Filter Plugin <?php /* * Smarty plugin * ------------------------------------------------------------- * File: postfilter.post01.php * Type: postfilter * Name: post01 * Purpose: Output code that lists all current template vars. * ------------------------------------------------------------- */ function smarty_postfilter_post01($compiled, &$smarty) { $compiled = "<pre>\n<?php print_r(\$this->get_template_vars()); ?>\n</pre>" . $compiled; return $compiled; } ?> Ausgabefilter Ausgabefilter werden auf das Template direkt vor der Ausgabe angewendet, nachdem es geladen und ausgeführt wurde. string smarty_outputfilter_name string $template_output object &$smarty Als erster Parameter wird die Template-Ausgabe übergeben, welche verarbeitet werden soll und als zweiter Parameter das Smarty-Objekt. Das Plugin muss danach die verarbeitete Template-Ausgabe zurückgeben. Ausgabefilter Plugin /* * Smarty plugin * ------------------------------------------------------------- * File: outputfilter.protect_email.php * Type: outputfilter * Name: protect_email * Purpose: Converts @ sign in email addresses to %40 as * a simple protection against spambots * ------------------------------------------------------------- */ function smarty_outputfilter_protect_email($output, &$smarty) { return preg_replace('!(\S+)@([a-zA-Z0-9\.\-]+\.([a-zA-Z]{2,3}|[0-9]{1,3}))!', '$1%40$2', $output); } Ressourcen Ressourcen-Plugins stellen einen generischen Weg dar, um Smarty mit Template-Quellen oder PHP-Skripten zu versorgen. Einige Beispiele von Ressourcen: Datenbanken, LDAP, shared Memory, Sockets, usw. Für jeden Ressource-Typ müssen 4 Funktionen registriert werden. Jede dieser Funktionen erhält die verlangte Ressource als ersten Parameter und das Smarty Objekt als letzten. Die restlichen Parameter hängen von der Funktion ab. bool smarty_resource_name_source string $rsrc_name string &$source object &$smarty bool smarty_resource_name_timestamp string $rsrc_name int &$timestamp object &$smarty bool smarty_resource_name_secure string $rsrc_name object &$smarty bool smarty_resource_name_trusted string $rsrc_name object &$smarty Die erste Funktion wird verwendet, um die Ressource zu laden. Der zweite Parameter ist eine Variable, die via Referenz übergeben wird und in der das Resultat gespeichert werden soll. Die Funktion gibt true zurück, wenn der Ladevorgang erfolgreich war - andernfalls false. Die zweite Funktion fragt das letzte Änderungsdatum der angeforderten Ressource (als Unix-Timestamp) ab. Der zweite Parameter ist die Variable, welche via Referenz übergeben wird und in der das Resultat gespeichert werden soll. Gibt true zurück, wenn das Änderungsdatum ermittelt werden konnte und false wenn nicht. Die dritte Funktion gibt true oder false zurück, je nachdem ob die angeforderte Ressource als sicher bezeichnet wird oder nicht. Diese Funktion wird nur für Template-Ressourcen verwendet, sollte aber in jedem Fall definiert werden. Die vierte Funktion gibt true oder false zurück, je nachdem ob die angeforderte Ressource als vertrauenswürdig angesehen wird oder nicht. Diese Funktion wird nur verwendet, wenn PHP-Skripte via include_php oder insert eingebunden werden sollen und ein 'src' Attribut übergeben wurde. Die Funktion sollte aber in jedem Fall definiert werden. Sehen Sie dazu: register_resource(), unregister_resource(). Ressourcen Plugin <?php /* * Smarty plugin * ------------------------------------------------------------- * File: resource.db.php * Type: resource * Name: db * Purpose: Fetches templates from a database * ------------------------------------------------------------- */ function smarty_resource_db_source($tpl_name, &$tpl_source, &$smarty) { // Datenbankabfragen machen, um '$tpl_source' das template 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 smarty_resource_db_timestamp($tpl_name, &$tpl_timestamp, &$smarty) { // Datenbankabfragen durchführen 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 smarty_resource_db_secure($tpl_name, &$smarty) { // angenommen alle Templates seien sicher... return true; } function smarty_resource_db_trusted($tpl_name, &$smarty) { // wird für Templates nicht verwendet } ?> Inserts Insert-Plugins werden verwendet, um Funktionen zu implementieren, die via insert aufgerufen werden. string smarty_insert_name array $params object &$smarty Als erster Parameter wird der Funktion ein assoziatives Array aller Attribute übergeben, die im Insert-Tag notiert wurden. Sie können auf diese Werte entweder direkt mit $params['start'] zugreifen oder sie mit extract($params) importieren. Als Rückgabewert muss das Resultat der Ausführung geliefert werden, das danach den Platz des insert-Tags im Template einnimmt. Insert-Plugin <?php /* * Smarty plugin * ------------------------------------------------------------- * File: insert.time.php * Type: time * Name: time * Purpose: Inserts current date/time according to format * ------------------------------------------------------------- */ function smarty_insert_time($params, &$smarty) { if (empty($params['format'])) { $smarty->trigger_error("insert time: missing 'format' parameter"); return; } $datetime = strftime($params['format']); return $datetime; } ?>