Advanced FeaturesObjekte
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';
?>