Voilà, j'ai voulu simplement mettre en oeuvre un système de template avec juste les fonctions native de php. Beaucoup se donnent la peine de coder de gros systèmes de template alors que leur application est moyenne. D'autres s'adonnent à la même pratique sans bien comprendre la notion de template. Et c'est ainsi que m'est venue l'idée d'utiliser les fonctions que propose déjà php et qui font la quasi-totalité de ce qu' un moteur de template de renommée peut faire.
Le véritable challenge pour un codeur en PHP n'est pas le code mais le design et la mise à jour de celui-ci ou de son code.
Mais comment ? C'est moi qui l'ai écrit, comment cela sera difficile ?
Le pire ennemi est ici le « pèle mêle » c'est à dire le mélange du code html au php.
Vous verrez qu'à la longue vous ne pourrez plus différencier la raison pour laquelle telle portion du code ou telle autre est là ou ne l'est pas.
Mais le deuxième point le plus crucial c'est la mise à jour du design d'un site. Dans le cas d'un « pèle mêle », on sera obligé de mettre à niveau le code php en même temps que celui du html, ce qui s'avère un peu délicat dans le cas d'une grosse application.
Le système de Template, voilà notre sauveur. Mais qui est il et à quoi sert-il ?
Un système de Template est un système permettant de scinder le code d'une page en deux, la partie html et la partie php. Ce système présente plusieurs avantages :
Modifier le code sans se soucier du design
On n'utilisera que les fonctions de bufferisation principales à savoir :
Note : il existe des fonctions similaires à ob_clean () et ob_flush () qui sont ob_end_clean () et ob_end_flush () qui en plus de faire la même chose que ob_clean () et ob_flush () mettent fin à la bufferisation.
Exemple d'utilisation
< ?php // On démarre la bufferisation ob_start () ; // On affiche quelque chose echo `j'ai déjà démarré la bufferisation' ; // On récupère le contenu du buffer $buffer = ob_get_content () ; // Notre traitement ici // On a récupéré le contenu du buffer dans $buffer, on peut l'effacer ob_clean () ; // On envoie le tout au navigateur ob_flush () ; ?>
Les autres fonctions, je crois que tout le monde les connaît mais qui ne veut pas se rafraichir la mémoire.
split () cette fonction permet d`exploser une chaîne de caractères en tableaux ; elle prend en paramètre le critère pour lequel on veut scinder la chaîne.
Imaginez par exemple que vous disposez d'un moteur de recherche sur votre site et vous utilisez les fonctionnalités « or » ou « and » pour la comparaison. On ne dira pas à l'utilisateur de saisir le premier puis le deuxième mot ainsi de suite mais naturellement il va séparer les mots par un espace. Et là, avec split () on pourra récupérer les différents mots tapés dans le champ.
< ?php $mot = $_POST [`mot'] ; // Notre critère pour scinder la chaîne est l'espace que l'utilisateur a mis entre les mots $mots = split (` `,$mot) ; //maintenant $mots est un tableau contenant tous les mots saisis ?>
Donc, c'est un tuto dans un autre pour les codeurs de moteur de recherche. Voilà une idée.
str_replace () c'est la fonction de remplacement la plus facile. Il est conseillé de l'utiliser si on veut faire des remplacements simples. Ah bon mais qu'est-ce qu'elle remplace ? On va utiliser notre split () sur str_replace (), ce qui donne string replace, ou en français facile « remplacer chaîne ». Ce qui implique qu'on peut avec cette fonction remplacer une chaîne dans une chaîne par une autre chaîne. Voilà un exemple pour ne pas rester chaînés
< ?php //notre chaîne initiale ; $str_intiale = `hello {str_remplacer} how are you ?`; // ce que l'on veut ici, c'est remplacer {str_remplacer} par devil_may_cry. //Notez bien cette notation car c'est elle qu'on utilisera dans notre système de Template $str_finale = str_replace (`{str_remplacer}','devil_may_cry',$str_initiale) ; // on affiche echo `avant modification '.$str_initiale. `<br>' ; echo `après modification '.$str_finale. `<br>' ; ?>
vous aurez à l'écran :
avant modification hello {str_remplacer} how are you ?
après modification hello devil_may_cry how are you ?
file () : c'est une fonction qui permet de récupérer rapidement le contenu d'un fichier. Elle retourne un tableau dont chaque ligne correspond à une ligne du fichier.
Attention, cette fonction tient compte des indentations du fichier. On verra dans le point suivant comment exploiter ce tableau.
implode () : elle permet de concaténer les éléments d'un tableau. Elle prend en paramètre la chaîne de jointure et le tableau. C'est avec elle qu'on va exploiter le tableau retourné par file ()
ca y'est, c'en est fini pour les révisions ; on retrousse les manches
Les pages dont on aura besoin sont :
Template_func.php // c'est là qu'on mettra toutes nos fonctions de gestion du template
Index.php // c'est notre page principale. C'est là que se fera l'appel de template_func.php en tout début de page ;
Test.html // le template
Note : on suppose que tous ces fichiers se trouvent dans le même répertoire
En temps normal, on traite et on affiche en même temps, alors que là, on va tout afficher. « afficher » veut dire ici qu'on envoie nos echo vers le buffer et non vers la sortie standard (l'écran) ; on effectue ensuite nos traitements mais seul le résultat final sera visible à l'écran naturellement après que l'on en aura donné ordre.
Pour aboutir au résultat souhaité, il faudra respecter les conventions ci-dessous. N'hésitez pas à les relire afin de comprendre pourquoi telle ou telle chose est là ou ne l'est pas.
Ces conventions ne sont là que pour un meilleur suivi du tutoriel mais dès que vous aurez saisi le truc, libre à vous d'écrire vos propres conventions.
< !-- BEGIN nom_du_block --> // ici le contenu du block < !-- END nom_du_block -->
Ce script contient 3 fonctions
Init ($file) : cette fonction prend en paramètre le fichier Template qui va se charger de l'afficher
Set_var ($varray) : cette fonction se charge de remplacer une constante n'appartenant pas à un block par sa valeur. Elle prend en paramètre un tableau associatif de la forme $varray = array (`const1'=>'valconst1','const2'=>'valconst2','constN'=>'valconsN') ;
set_varray ($blockname,$varray) : celle-ci se charge de remplacer les constantes d'un block. Elle prend en paramètre le nom du block $blockname ainsi que les différentes valeurs des constantes du block.
$varray est de la forme :
$varray [$cpt] = array (`const1'=>'valconst1','const2'=>'valconst2','constN'=>'valconsN') ;
$cpt est un compteur on verra par la suite comment il marche.
Voici les codes sources de ces trois fonctions
Init ($file)
<?php //on démarre la bufferisation ob_start() ; function init ($file) { // on ouvre le fichier en lecture et on récupère son contenu $fp = file($file); // On réunit le contenu du fichier dans $fileContent $fileContent = implode("",$fp); // On affiche le contenu mais celui ci ne sera pas visible il sera bufferisé echo $fileContent; }
set_var($varray)
function set_var($varray) { // On récupère le contenu du buffer avec ob_get_contents $buffer = ob_get_contents(); //$varray représente un tableau sous la forme nom_variable=>valeur_variable // On parcourt alors $varray avec une boucle foreach foreach ($varray as $key=>$val) { // On utilise str_replace pour remplacer la constante par sa valeur $buffer = str_replace('{'.$key.'}',$val,$buffer); } // Efface le contenu du buffer ob_clean(); // et on envoie le nouveau contenu echo $buffer; }
Set_varray($blockname,$varray)
function set_varray($blockname,$varray) { // On récupère le contenu du buffer avec ob_get_contents $buffer = ob_get_contents(); // on doit récupérer le contenu du block et lui assigner ces valeurs // il y a plusieurs méthodes pour le faire mais je ne vais pas compliquer les choses // on utilisera split // Avec le premier split, on ne récupère que le contenu du block délimité à la fin // par le tag <!-- End nom_du_block --> c'est là qu'intervient // notre deuxième split pour ne laisser que le contenu du block; $block = split("<!-- BEGIN ".$blockname." -->",$buffer); $blockf = split("<!-- END ".$blockname." -->",$block[1]); // on assigne le contenu du block dans $blockContent $blockContent = $blockf[0]; // On doit maintenant marquer l'emplacement du block dans le buffer // pour dire que c'est là qu'on va revenir pour replacer les donnes du block $buffer = str_replace("<!-- BEGIN ".$blockname." -->".$blockContent."<!-- END ".$blockname." -->","{".$blockname."}",$buffer); // on remplace maintenant les valeurs du block // On parcourt alors $varray avec une boucle for d'abord pour gérer chaque itération, ensuite avec une boucle foreach pour remplacer les constantes par leur valeur $max = count($varray); $content = $blockContent; for ( $i = 0; $i < $max ;$i++ ) { foreach( $varray[$i] as $key=>$val ) { // On utilise str_replace pour remplacer la constante par sa valeur $content = str_replace('{'.$key.'}',$val,$content); } //on vérifie si on doit concaténer à nouveau le block ou pas if ( $i+1 < $max ) { // On concatène à nouveau le block $content .= $blockContent; } } // Toutes les variables ont été correctement assignées // On les replace dans notre variable $buffer $buffer = str_replace("{".$blockname."}",$content,$buffer); // Efface le contenu du buffer ob_clean(); // et on envoie le nouveau contenu echo $buffer; }
C'est le fichier template qu'on va utiliser. Il ressemble à quelque chose comme ca
<html> <head> <title>Mon Premier gestionnaire de template</title> </head> <body> <div> Un tutoriel sur la gestion des templates par {AUTHOR_NAME} publié sur le site {SITE_NAME} que vous pouvez visiter à l'adresse {SITE_ADDRESS} </div> <!-- BEGIN LIST_TUTO --> <div> <p> <span>{TUTO_TITLE}</span> <span>Format {TUTO_FORMAT}</span> <span>Consultés {TUTO_NBREAD} fois</span> </p> </div> <!-- END LIST_TUTO --> </body> </html>
Ce template comporte donc 3 constantes qui sont {AUTHOR_NAME} {SITE_NAME} et {SITE_ADDRESS}. Et pour les remplacer par leur valeur, on fera appel à set_var ()
Il contient aussi un block « LIST_TUTO » qui comporte les constantes > {TUTO_TITLE} {TUTO_FORMAT} et {TUTO_NBREAD} ; ici set_var () ne fera pas l'affaire, on fera donc appel à set_vararray () ;
C'est le script de base. C'est lui qui fera appel à toutes les fonctions
< ?php //on inclut notre gestionnaire de template include 'template_func.php' ; //on initialise le template Init('test.html') ; //on remplace les constantes qui ne sont pas dans des blocks // pour faciliter l'écriture, on déclare un tableau infos avec les constantes comme clefs et leur valeur $infos = array('AUTHOR_NAME'=>'devil_may_cry', 'SITE_NAME'=>'phpcs.com', 'SITE_ADDRESS'=>'http://www.phpcs.com'); set_var($infos); // on remplace pour les blocks maintenant // mais il faut impérativement créer un tableau avec toutes les constantes et leur valeur en indiquent le nombre d'itérations $infos[0] = array('TUTO_TITLE'=>'tuto1','TUTO_FORMAT'=>'pdf','TUTO_NBREAD'=>'5'); $infos[1] = array('TUTO_TITLE'=>'tuto2','TUTO_FORMAT'=>'doc','TUTO_NBREAD'=>'0'); $infos[2] = array('TUTO_TITLE'=>'tuto3','TUTO_FORMAT'=>'html','TUTO_NBREAD'=>'2'); //pour remplacer dans le block « LIST_TUTO » on fait $tp->set_varray('LIST_TUTO',$infos); //on peut utiliser ici ob_clean() ensuite ob_end_flush() ob_clean(); ob_end_flush (); ?>
Et voilà notre gestionnaire de template, simple et efficace. Mais la solution exposée ici n'est qu'une manière simple pour faire comprendre le système de template. Ce n'est en aucun cas une solution adéquate pour un site web ou une grosse application.
J'ai skippé aussi plusieurs étapes comme la sécurité et la consolidation du code. Mais comme je l'ai dit, j'ai juste essayé de mettre en oeuvre une technique simple pour que le code soit à la portée de tous. Vous pouvez prendre le temps d'améliorer les scripts pour mieux saisir les notions utilisées ici et enfin essayer de le modéliser. A ce moment vous disposerez d'un vrai système de template car sans la POO votre gestionnaire de template restera dans la zone rouge
Si vous avez des remarques ou des questions, je serai là pour ça.