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:
FunktionenModifikatorenBlock-FunktionenCompiler-Funktionen'pre'-Filter'post'-FilterAusgabefilterRessourcenInserts
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:
functionmodifierblockcompilerprefilterpostfilteroutputfilterresourceinsert
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-Funktionenvoid smarty_function_namearray $paramsobject &$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_namemixed $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-Funktionenvoid smarty_function_namearray $paramsmixed $contentobject &$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_namestring $tag_argobject &$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_namestring $sourceobject &$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_namestring $compiledobject &$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_namestring $template_outputobject &$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_sourcestring $rsrc_namestring &$sourceobject &$smartybool smarty_resource_name_timestampstring $rsrc_nameint &$timestampobject &$smartybool smarty_resource_name_securestring $rsrc_nameobject &$smartybool smarty_resource_name_trustedstring $rsrc_nameobject &$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_namearray $paramsobject &$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;
}
?>