Files
smarty/docs/de/programmers/advanced-features.xml

558 lines
19 KiB
XML
Raw Normal View History

2004-03-28 15:20:52 +00:00
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- $Revision$ -->
<chapter id="advanced.features">
<title>Advanced Features</title>
<sect1 id="advanced.features.objects">
<title>Objekte</title>
<para>
Smarty erlaubt es, auf PHP Objekt durch das Template zuzugreifen. Daf&uuml;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&ouml;nnen. Welchen Weg Sie einschlagen
wird von Ihren Bed&uuml;rfnissen definiert, die erste Methode ist jedoch zu bevorzugen.
</para>
<para>
Wenn die Sicherheitsfunktionen eingeschaltet sind, k&ouml;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.
</para>
<para>
Sie k&ouml;nnen den Zugriff auf Methoden und Eigenschaften einschr&auml;nken
indem Sie sie als Array als dritten Registrationsparameter &uuml;bergeben.
</para>
<para>
Normalerweise werden Parameter welche einem Objekt via Template &uuml;bergeben
werden genau so &uuml;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&ouml;chten k&ouml;nnen Sie den vierten
Parameter auf FALSE setzen.
</para>
<para>
Der optionale f&uuml;nfte Parameter hat nur einen Effekt wenn
<parameter>format</parameter> = <literal>true</literal> ist und eine Liste von
Methoden enth&auml;lt die als Block verarbeitet werden sollen.
Das bedeutet, dass solche Methoden ein schliessendes Tag im Template
enthalten m&uuml;ssen (<literal>{foobar->meth2}...{/foobar->meth2}</literal>)
und die Parameter zu den Funktionen die selbe Syntax haben wie block-function-plugins:
sie erhalten also die 4 Parameter
<parameter>$params</parameter>,
<parameter>$content</parameter>,
<parameter>&amp;$smarty</parameter> und
<parameter>&amp;$repeat</parameter>,
und verhalten sich auch sonst wie block-function-plugins.
</para>
<example>
<title>registierte oder zugewiesene Objekte verwenden</title>
<programlisting>
&lt;?php
// das objekt
class My_Object {
function meth1($params, &amp;$smarty_obj) {
return "meine meth1";
}
}
$myobj = new My_Object;
// objekt registrieren (referenz)
$smarty->register_object("foobar",$myobj);
// zugriff auf methoden und eigeschaften einschr&auml;nken
$smarty->register_object("foobar",$myobj,array('meth1','meth2','prop1'));
// wenn wir das traditionelle parameter format verwenden wollen, &uuml;bergeben wir false f&uuml;r den parameter format
$smarty->register_object("foobar",$myobj,null,false);
// objekte zuweisen (auch via referenz m&ouml;glich)
$smarty->assign_by_ref("myobj", $myobj);
$smarty->display("index.tpl");
?&gt;
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)}</programlisting>
</example>
</sect1>
<sect1 id="advanced.features.prefilters">
<title>'pre'-Filter</title>
<para>
Template 'pre'-Filter sind Filter, welche auf das Template vor dessen Kompilierung
angewendet werden. Dies ist n&uuml;tzlich, um zum Beispiel Kommentare zu entfernen
oder um den Inhalt des Templates zu analysieren. 'pre'-Filter k&ouml;nnen auf verschiedene
Arten geladen werden. Man kann sie <link linkend="api.register.prefilter">registrieren</link>,
aus dem Plugin-Verzeichnis mit <link linkend="api.load.filter">load_filter()</link> laden
oder <link linkend="variable.autoload.filters">$autoload_filters</link> verwenden.
Smarty &uuml;bergibt der Funktion als ersten Parameter den Template-Quellcode und erwartet
als R&uuml;ckgabewert den bearbeiteten Quellcode.
</para>
<example>
<title>Template 'pre'-Filter verwenden</title>
<programlisting>
&lt;?php
// f&uuml;gen Sie folgende Zeilen in Ihre Applikation ein
function remove_dw_comments($tpl_source, &amp;$smarty)
{
return preg_replace("/&lt;!--#.*--&gt;/U","",$tpl_source);
}
// registrieren Sie den 'pre'-Filter
$smarty->register_prefilter("remove_dw_comments");
$smarty->display("index.tpl");
?&gt;
{* Smarty Template 'index.tpl' *}
&lt;!--# diese Zeile wird vom 'pre'-Filter entfernt--&gt;</programlisting>
</example>
</sect1>
<sect1 id="advanced.features.postfilters">
<title>'post'-Filter</title>
<para>
Template 'post'-Filter sind Filter, welche auf das Template nach dessen Kompilierung
angewendet werden. 'post'-Filter k&ouml;nnen auf verschiedene Arten
geladen werden. Man kann sie <link linkend="api.register.prefilter">registrieren</link>,
aus dem Plugin-Verzeichnis mit <link linkend="api.load.filter">load_filter()</link> laden
oder <link linkend="variable.autoload.filters">$autoload_filters</link> verwenden.
Smarty &uuml;bergibt der Funktion als ersten Parameter den Template-Quellcode und erwartet
als R&uuml;ckgabewert den bearbeiteten Quellcode.
</para>
<example>
<title>Template 'post'-Filter verwenden</title>
<programlisting>
&lt;?php
// f&uuml;gen Sie folgende Zeilen in Ihre Applikation ein
function add_header_comment($tpl_source, &amp;$smarty)
{
return "&lt;?php echo \"&lt;!-- Created by Smarty! --&gt;\n\" ?&gt;\n".$tpl_source;
}
// registrieren Sie den 'post'-Filter
$smarty->register_postfilter("add_header_comment");
$smarty->display("index.tpl");
?&gt;
{* kompiliertes Smarty Template 'index.tpl' *}
&lt;!-- Created by Smarty! --&gt;
{* Rest des Template Inhalts... *}</programlisting>
</example>
</sect1>
<sect1 id="advanced.features.outputfilters">
<title>Ausgabefilter</title>
<para>
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.
</para>
<para>
Ausgabefilter k&ouml;nnen auf verschiede Arten
geladen werden. Man kann sie <link linkend="api.register.prefilter">registrieren</link>,
aus dem Plugin-Verzeichnis mit <link linkend="api.load.filter">load_filter()</link> laden
oder <link linkend="variable.autoload.filters">$autoload_filters</link> verwenden.
Smarty &uuml;bergibt der Funktion als ersten Parameter die Template-Ausgabe und erwartet
als R&uuml;ckgabewert die bearbeitete Ausgabe.
</para>
<example>
<title>Ausgabefilter verwenden</title>
<programlisting>
&lt;?php
// f&uuml;gen Sie folgende Zeilen in Ihre Applikation ein
function protect_email($tpl_output, &amp;$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.
?&gt;</programlisting>
</example>
</sect1>
<sect1 id="section.template.cache.handler.func">
<title>Cache Handler Funktion</title>
<para>
Als Alternative zum normalen dateibasierten Caching-Mechanismus k&ouml;nnen Sie
eine eigene Cache-Handler Funktion zum lesen, schreiben und l&ouml;schen von
Cache-Dateien definieren.
</para>
<para>
Schreiben Sie eine Funktion in Ihrer Applikation, die Smarty als
Cache-Handler verwenden soll und weisen Sie deren Name der Variable
<link linkend="variable.cache.handler.func">$cache_handler_func</link> zu.
Smarty wird von da an Ihre Funktion zur Bearbeitung des Caches verwenden.
Als erster Parameter wird die 'action' mit einem der folgendende Werte
&uuml;bergeben: 'read', 'write' und 'clear'. Als zweiter Parameter
wird das Smarty-Objekt &uuml;bergeben, als dritter der gecachte Inhalt. Bei einem
'write' &uuml;bergibt Smarty den gecachten Inhalt, bei 'read' &uuml;bergibt Smarty die
Variable als Referenz und erwartet, dass Ihre Funktion die Inhalte zuweist.
Bei 'clear' k&ouml;nnen Sie eine dummy-Variable &uuml;bergeben. Als vierter Parameter
wird der Template-Name &uuml;bergeben (verwendet bei 'write'/'read'), als f&uuml;nfter
Parameter die 'cache_id' (optional) und als sechster die 'compile_id' (auch optional).
</para>
<example>
<title>Beispiel mit einer MySQL Datenbank als Datenquelle</title>
<programlisting>
&lt;?php
/*
Beispiel Anwendung:
include('Smarty.class.php');
include('mysql_cache_handler.php');
$smarty = new Smarty;
$smarty-&gt;cache_handler_func = 'mysql_cache_handler';
$smarty-&gt;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, &amp;$smarty_obj, &amp;$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-&gt;_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-&gt;_trigger_error_msg("cache_handler: query failed.");
}
$row = mysql_fetch_array($results,MYSQL_ASSOC);
if($use_gzip &amp;&amp; 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 &amp;&amp; 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-&gt;_trigger_error_msg("cache_handler: query failed.");
}
$return = $results;
break;
case 'clear':
// Cache Informationen l&ouml;schen
if(empty($cache_id) &amp;&amp; empty($compile_id) &amp;&amp; empty($tpl_file)) {
// alle l&ouml;schen
$results = mysql_query("delete from CACHE_PAGES");
} else {
$results = mysql_query("delete from CACHE_PAGES where CacheID='$CacheID'");
}
if(!$results) {
$smarty_obj-&gt;_trigger_error_msg("cache_handler: query failed.");
}
$return = $results;
break;
default:
// Fehler, unbekannte 'action'
$smarty_obj-&gt;_trigger_error_msg("cache_handler: unknown action \"$action\"");
$return = false;
break;
}
mysql_close($link);
return $return;
}
?&gt;</programlisting>
</example>
</sect1>
<sect1 id="template.resources">
<title>Ressourcen</title>
<para>
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&uuml;ssen Sie den Ressourcen-Typ,
gefolgt von Pfad und Template-Namen angeben. Wenn kein Resourcetyp angegeben
wird, wird <link linkend="variable.default.resource.type">$default_resource_type</link>
verwendet.
</para>
<sect2 id="templates.from.template.dir">
<title>Templates aus dem '$template_dir'</title>
<para>
Templates aus dem '$template_dir' ben&ouml;tigen normalerweise keinen Ressourcen-Typ,
es wird jedoch empfohlen 'file:' zu verwenden. &Uuml;bergeben Sie einfach den Pfad,
in dem sich das Template relativ zu '$template_dir' befindet.
</para>
<example>
<title>Templates aus '$template_dir' verwenden</title>
<programlisting>
// 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 *}</programlisting>
</example>
</sect2>
<sect2 id="templates.from.any.dir">
<title>Templates aus beliebigen Verzeichnissen</title>
<para>
Templates ausserhalb von '$template_dir' ben&ouml;tigen den 'file:' Ressourcen-Typ,
gefolgt von absolutem Pfadnamen und Templatenamen.
</para>
<example>
<title>Templates aus beliebigen Verzeichnissen benutzen</title>
<programlisting>
// 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"}</programlisting>
</example>
2004-03-29 11:09:14 +00:00
<sect3 id="templates.windows.filepath">
2004-03-28 15:20:52 +00:00
<title>Windows Dateipfade</title>
<para>
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.
</para>
<example>
<title>Templates aus Windows Dateipfaden verwenden</title>
<programlisting>
// 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"}</programlisting>
</example>
</sect3>
</sect2>
<sect2 id="templates.from.elsewhere">
<title>Templates aus anderen Quellen</title>
<para>
Sie k&ouml;nnen Templates aus jeder f&uuml;r PHP verf&uuml;gbaren Datenquelle beziehen:
Datenbanken, Sockets, LDAP, usw. Dazu m&uuml;ssen sie nur ein
Ressource-Plugin schreiben und registrieren.
</para>
<para>
Konsultieren Sie den Abschnitt &uuml;ber <link linkend="plugins.resources">Ressource-Plugins</link>
f&uuml;r mehr Informationen &uuml;ber die Funktionalit&auml;ten, die ein derartiges Plugin bereitstellen muss.
</para>
<note>
<para>
Achtung: Sie k&ouml;nnen die interne <literal>file</literal> Ressource nicht
&uuml;berschreiben. Es steht Ihnen jedoch frei, ein Plugin zu schreiben,
das die gew&uuml;nschte Funktionalit&auml;t implementiert und es als alternativen
Ressource-Typ zu registrieren.
</para>
</note>
<example>
<title>Eigene Quellen verwenden</title>
<programlisting>
// im PHP-Skript
// definieren Sie folgende Funktion in Ihrer Applikation
function db_get_template ($tpl_name, &amp;tpl_source, &amp;$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, &amp;$tpl_timestamp, &amp;$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, &amp;$smarty_obj)
{
// angenommen alle Templates sind sicher
return true;
}
function db_get_trusted($tpl_name, &amp;$smarty_obj)
{
// wird f&uuml;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"}</programlisting>
</example>
</sect2>
<sect2 id="default.template.handler.function">
<title>Standard Template-Handler</title>
<para>
Sie k&ouml;nnen eine Funktion definieren, die aufgerufen wird,
wenn ein Template nicht aus der angegeben Ressource geladen werden konnte.
Dies ist z. B. n&uuml;tzlich, wenn Sie fehlende Templates on-the-fly
generieren wollen.
</para>
<example>
<title>Standard Template-Handler verwenden</title>
<programlisting>
&lt;?php
// f&uuml;gen Sie folgende Zeilen in Ihre Applikation ein
function make_template ($resource_type, $resource_name, &amp;$template_source, &amp;$template_timestamp, &amp;$smarty_obj)
{
if( $resource_type == 'file' ) {
if ( ! is_readable ( $resource_name )) {
// erzeuge Template-Datei, gib Inhalte zur&uuml;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';
?&gt;</programlisting>
</example>
</sect2>
</sect1>
</chapter>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"../../../../manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
2004-03-29 11:09:14 +00:00
-->