Etendre Smarty avec des plugins
La version 2.0 a introduit l'architecture de plugin qui est
utilisée pour pratiquement toute les fonctionnalités
personnalisables de Smarty. Ceci comprend :
les fonctionsles modificateursles fonctions de blocsles fonctions de compilationles filtres de pré-compilationles filtres de post-compilationles filtres de sortiesles ressourcesles insertions
A part pour les ressources, la compatibilité avec les anciennes
fatons d'enregistrer les fonctions de gestion avec l'API register_
est conservée. Si vous n'avez pas utilisé cette API et que vous avez
a la place directement modifié les variables de classes
$custom_funcs, $custom_mods et
d'autres, vous devez alors modifier vos scripts pour utiliser
l'API ou convertir vos fonctionnalités personnalisées en plugins.
Comment fonctionnent les plugins
Les plugins sont toujours chargés a la demande. Seuls les modificateurs
de variables, les ressources, etc invoqués dans les scripts de templates
seront chargés. De plus, chaque plugin n'est chargé qu'une fois, et ce
même si vous avez plusieurs instances de Smarty qui tournent dans
la même requête.
Les filtres de post/pré-compilation et les filtres de sortie sont des cas
un peu spéciaux.
Comme ils ne sont pas mentionnés dans les templates, ils doivent être déclarés
ou chargés explicitement via les fonctions de l'API avant que le template
ne soit exécuté. L'ordre dans lequel les filtres multiples d'un même type
sont exécutés dépend de l'ordre dans lequel ils sont enregistrés ou chargés.
Il n'existe qu'un seul répertoire de plugin (pour des raisons de performances).
Pour installer un plugin, copiez-le simplement dans le répertoire et Smarty
l'utilisera automatiquement.
Conventions de nommage
Les fichiers et les fonctions de plugins doivent suivre une convention
de nommage trés spécifique pour être localisés par Smarty.
Les fichiers de plugins doivent être nommés de la faton suivante :
type.nom.php
Oú type est l'une des valeurs suivantes :
functionmodifierblockcompilerprefilterpostfilteroutputfilterresourceinsert
Et nom doit être un identifiant valide (lettres, nombres
et underscore seulement).
Quelques exemples : function.html_select_date.php,
resource.db.php,
modifier.spacify.php.
Les fonctions de plugins dans les fichiers de plugins doivent être
nommées de la faton suivante :
smarty_type_nom
Les significations de type et de nom sont les mêmes
que précédemment.
Smarty donnera des messages d'erreur approprié si le fichier de plugin
n'est pas trouvé, ou si le fichier ou la fonction de plugin ne sont
pas nommés correctement.
Ecrire des plugins
Les plugins peuvent être soit chargés automatiquement par Smarty
depuis le systéme de fichier, soit être déclarés
pendant l'exécution via une fonction register_* de l'API. Ils peuvent
aussi être désalloués en utilisant une fonction unregister_* de
l'API.
Pour les plugins qui ne sont pas enregistrés pendant l'exécution, le nom
des fonctions n'ont pas a suivre la convention de nommage.
Si certaines fonctionnalités d'un plugin dépendent d'un autre plugin
(comme c'est le cas de certains plugins accompagnant Smarty), alors la maniére appropriée
de charger le plugin est la suivante :
require_once SMARTY_DIR . 'plugins/function.html_options.php';
Une régle générale est que chaque objet Smarty est toujours passé au plugin
en tant que dernier paramétre (a part pour les modificateurs).
Les fonctions de templatesvoid smarty_function_namearray $paramsobject &$smarty
Tous les attributs passés aux fonctions de template a partir du template
sont contenus dans le tableau associatif $params.
Vous pouvez accéder a ces valeurs soit directement, par exemple
$params['start'], soit en utilisant
extract($params) pour les importer dans la table
des symboles.
Le retour de la fonction sera substituée a la balise de fonction
du template (fonction fetch par exemple). Sinon,
la fonction peut simplement accomplir une autre tGche sans sortie
(la fonction assign par exemple)
Si la fonction a besoin d'assigner des variables aux templates ou d'utiliser
d'autres fonctionnalités fournies par Smarty, elle peut recevoir un
objet $smarty pour cela.
Référez-vous aussi a :
register_function(),
unregister_function().
fonction de plugin avec sortie
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Fichier : function.eightball.php
* Type : fonction
* Nom : eightball
* Rôle : renvoie une phrase magique au hasard
* -------------------------------------------------------------
*/
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);
return $answers[$result];
}
?>
peut être utilisée dans le template de la faton suivante :
Question: Will we ever have time travel?
Answer: {eightball}.fonction de plugin sans sortie
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Fichier : function.assign.php
* Type : fonction
* Nom : assign
* Purpose : assigne une valeur a une variable de template
* -------------------------------------------------------------
*/
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);
}
?>Modificateurs
Les modificateurs sont des petites fonctions appliquées a une variable
de template avant qu'elle ne soit affichée ou utilisée dans un autre contexte.
Les modificateurs peuvent être chaenés entre eux.
mixed smarty_modifier_namemixed $value[mixed $param1, ...]
Le premier paramétre passé au modificateur est la valeur
sur laquelle le modificateur est supposé opérer. Les autres paramétres
peuvent être optionnels, dépendant de quel genre d'opération doit être
effectué.
Le modificateur doit retourner le résultat de son exécution.
Regardez aussi
register_modifier(),
unregister_modifier().
plugin modificateur simple
Ce plugin est un alias d'une fonction PHP. Il n'a aucun paramétre
supplémentaires.
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Fichier : modifier.capitalize.php
* Type : modificateur
* Name : capitalize
* Rôle : met une majuscule aux mots d'une phrase
* -------------------------------------------------------------
*/
function smarty_modifier_capitalize($string)
{
return ucwords($string);
}
?>un plugin modificateur un peu plus complexe
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Fichier : modifier.truncate.php
* Type : modificateur
* Name : truncate
* Rôle : Tronque une chaene a une certaine longueur si
* nécessaire, la coupe optionnellement au milieu
* d'un mot et ajoute la chaene $etc
* -------------------------------------------------------------
*/
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;
}
?>Fonctions de blocsvoid smarty_block_namearray $paramsmixed $contentobject &$smarty
Les fonctions de blocs sont des fonctions de la forme {func} .. {/func}.
En d'autres mots, elles englobent des blocs de template et opérent sur les
contenus de ces blocs. Les fonctions de blocs ont la priorité sur les
fonctions utilisateurs de même nom, ce qui signifie que vous ne
pouvez avoir une fonction utilisateur {func} et une fonction de bloc
{func} .. {/func}.
L'implémentation de votre fonction est appelée deux fois par Smarty :
une fois pour la balise ouvrante et une autre fois pour la balise
fermante.
Seule la balise ouvrante d'une fonction de bloc peut avoir des attributs.
Tous les attributs passés par le template aux fonctions de templates sont
contenues dans le tableau associatif $params.
Vous pouvez accéder a ces valeurs soit directement, par exemple
$params['start'], soit en utilisant
extract($params) pour les importer dans la table
des symboles. Votre fonction a aussi accés aux attributs de la balise
ouvrante quand c'est la balise fermante qui est exécutée.
La valeur de la variable $content est différente
selon si votre fonction est appelée pour la balise ouvrante ou la
balise fermante. Si c'est pour la balise ouvrante, elle sera a
null et si c'est la balise fermante elle sera
égale au contenu du bloc de template. Notez que le bloc de template
aura déjà été exécuté par Smarty, vous recevrez donc la sortie du
template et non sa source.
Si vous imbriqué des fonctions de bloc, il est possible de connaetre
la fonction de bloc parente grGce a la variable $smarty->_tag_stack.
Faites un var_dump() dessus et la structure devrait apparaetre.
Regardez aussi :
register_block(),
unregister_block().
fonction de bloc
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Fichier : block.translate.php
* Type : bloc
* Nom : translate
* Rôle : traduire un bloc de texte
* -------------------------------------------------------------
*/
function smarty_block_translate($params, $content, &$smarty)
{
if ($content) {
$lang = $params['lang'];
// fait une traduction de $content
echo $translation;
}
}Fonctions de compilation
Les fonctions de compilation sont appelées durant la compilation du template.
Elles sont utiles pour injecter du code PHP ou du contenu "statique variant
avec le temps" (bandeau de pub par ex.). Si une fonction de compilation et
une fonction personnalisée ont le même
nom, la fonction de compilation a priorité.
mixed smarty_compiler_namestring $tag_argobject &$smarty
Les fonctions de compilation ont deux paramétres : une chaene contenant
la balise - en gros, tout, depuis le nom de la fonction jusqu'au délimiteur de fin - et
l'objet Smarty. Elles sont censées retourner le code PHP qui doit être
injecté dans le template compilé.
Regardez aussi
register_compiler_function(),
unregister_compiler_function().
fonction de compilation simple
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Fichier : compiler.tplheader.php
* Type : compilation
* Nom : tplheader
* Rôle : Renvoie l'en-tête contenant le nom du fichier
* source et le temps de compilation.
* -------------------------------------------------------------
*/
function smarty_compiler_tplheader($tag_arg, &$smarty)
{
return "\necho '" . $smarty->_current_file . " compiled at " . date('Y-m-d H:M'). "';";
}
?>
Cette fonction peut-être appelé depuis le template comme suivant :
{* cette fonction n'est executée que lors de la compilation *}
{tplheader}
Le code PHP résultant dans les templates compilés ressemblerait a ta :
<php
echo 'index.tpl compiled at 2002-02-20 20:02';
?>filtres de pré-compilation/filtres de post-compilation
Les filtres de pré-compilation et les filtres de post-compilation ont des concepts trés
proches. Ils différent dans leur exécution, plus précisément dans le
moment oú ils sont exécutés.
string smarty_prefilter_namestring $sourceobject &$smarty
Les filtres de pré-compilation sont utilisés pour transformer la source d'un template
juste avant la compilation. Le premier paramétre passé a la fonction
de filtre de pré-compilation est la source du template, éventuellement modifiée par
d'autres filtre de pré-compilations. Le plugin est supposé retourner la source modifiée.
Notez que cette source n'est sauvegardée nulle part, elle est seulement
utilisé pour la compilation.
string smarty_postfilter_namestring $compiledobject &$smarty
Les filtres de post-compilation sont utilisés pour modifier la sortie du template
(le code PHP) juste aprés que la compilation a été faite mais juste
avant que le template ne soit sauvegardé sur le systéme de fichiers.
Le premier paramétre passé a la fonction de filtre de post-compilation est le code
du template compilé, éventuellement déja modifié par d'autres filtre de post-compilations.
Le plugin est censé retourner la version modifié du code.
plugin de filtre de post-compilation
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Fichier : prefilter.pre01.php
* Type : filtre de pré-compilation
* Nom : pre01
* Rôle : Passe les balises HTML en minuscules.
* -------------------------------------------------------------
*/
function smarty_prefilter_pre01($source, &$smarty)
{
return preg_replace('!<(\w+)[^>]+>!e', 'strtolower("$1")', $source);
}
?>plugin de filtre de post-compilation
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Fichier : postfilter.post01.php
* Type: filtre de post-compilation
* Nom : post01
* Rôle : Renvoie du code qui liste toutes les variables
* du template.
* -------------------------------------------------------------
*/
function smarty_postfilter_post01($compiled, &$smarty)
{
$compiled = "<pre>\n<?php print_r(\$this->get_template_vars()); ?>\n</pre>" . $compiled;
return $compiled;
}
?>Filtres de sortie
Les plugins de filtres de sortie opérent sur la sortie du template,
aprés que le template a été chargé et exécuté, mais avant que
la sortie ne soit affichée.
string smarty_outputfilter_namestring $template_outputobject &$smarty
Le premier paramétre passé a la fonction du filtre de sortie est la
sortie du template qui doit être modifiée et le second paramétre
est l'instance de Smarty appelant le plugin. Le plugin est supposé
faire un traitement et en retourner le résultat.
plugin de filtre de sortie
/*
* Smarty plugin
* -------------------------------------------------------------
* Fichier : outputfilter.protect_email.php
* Type : filtre de sortie
* Nom : protect_email
* Rôle: Convertie les @ en %40 pour protéger des
* robots spammers.
* -------------------------------------------------------------
*/
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);
}
Ressources
Les plugins ressources sont un moyen générique de fournir des sources
de templates ou des composants de scripts PHP a Smarty. Quelques exemples
de ressources : bases de données, LDAP, mémoire partagée, sockets, et ainsi
de suite.
Il y au total 4 fonctions qui ont besoin d'être enregistrées pour
chaque type de ressource. Chaque fonction retoit le nom de la ressource demandée
comme premier paramétre et l'objet Smarty comme dernier paramétre.
Les autres paramétres dépendent de la fonction.
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
La premiére fonction est supposée récupérer la ressource. Son second
paramétre est une variable passée par référence oú le résultat doit être
stocké. La fonction est supposée retourner true si
elle réussi a récupérer la ressource et false sinon.
La seconde fonction est supposée récupérer la date de derniére modification
de la ressource demandée (comme un timestamp UNIX). Le second paramétre
est une variable passée par référence dans laquelle la date doit
être stockée. La fonction est supposée renvoyer true si elle
a réussi a récupérer la date et false sinon.
La troisiéme fonction est supposée retourner true
ou false selon si la ressource demandée est svre
ou non. La fonction est utilisée seulement pour les ressources templates
mais doit tout de même être définie.
La quatriéme fonction est supposée retourner true
ou false selon si on peut faire confiance ou
non a la ressource demandée. Cette fonction est utilisée seulement
pour les composants de scripts PHP demandés par les balises
include_php ou insert
ayant un attribut src. Quoiqu'il en soit,
elle doit être définie pour les ressources templates.
Regardez aussi
register_resource(),
unregister_resource().
resource plugin
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Fichier : resource.db.php
* Type : ressource
* Nom : db
* Rôle : Récupére des templates depuis une base de données
* -------------------------------------------------------------
*/
function smarty_resource_db_source($tpl_name, &$tpl_source, &$smarty)
{
// fait des requêtes BD pour récupérer votre template
// et remplir $tpl_source
$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)
{
// fait des requêtes BD pour remplir $tpl_timestamp
$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)
{
// suppose que tous les templates sont svrs
return true;
}
function smarty_resource_db_trusted($tpl_name, &$smarty)
{
// inutilisée pour les templates
}
?>Insertions
Les plugins d'insertion sont utilisés pour implémenter les fonctions
qui sont appelées par les balises
insert
dans les templates.
string smarty_insert_namearray $paramsobject &$smarty
Le premier paramétre passé a la fonction est une tableau associatif
d'attributs. Vous pouvez accéder a ces valeurs soit directement, par exemple
$params['start'], soit en utilisant
extract($params) pour les importer dans la table
des symboles.
La fonction d'insertion est supposée retourner le résultat qui sera
substitué a la balise insert dans le template.
plugin d'insertion
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Fichier : insert.time.php
* Type : temps
* Nom : time
* Rôle : Insert la date/heure courante conformément
* au 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;
}
?>