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 fonctions les modificateurs les fonctions de blocs les fonctions de compilation les filtres de pré-compilation les filtres de post-compilation les filtres de sorties les ressources les 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
type est l'une des valeurs suivantes : function modifier block compiler prefilter postfilter outputfilter resource insert 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 templates void smarty_function_name array $params object &$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_name mixed $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 blocs void smarty_block_name array $params mixed $content object &$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_name string $tag_arg object &$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_name string $source object &$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_name string $compiled object &$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_name string $template_output object &$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_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 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_name array $params object &$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; } ?>