[3.0.x] Tutorial sur les templates phpBB3 Difficile

[3.0.x] Tutorial sur les templates phpBB3


» Tutorial sur les templates phpBB3

Ce tutoriel a pour but de vous familiariser avec l'emploi des templates de phpBB3, c'est à dire avec la mise en page des forums phpBB ceci afin:
  • de pouvoir créer des mods (qui ne peuvent être publiés sur des sites officiels que si vous respectez, entre autre, les règles du templating)
  • de créer des pages personnelles, indépendantes de votre forum mais gardant la même mise en page


» Sommaire

  1. Introduction
    1. Un template qu'est-ce que c'est?
    2. Préalables
  2. Premier exemple: affectation d'une variable
    • Les blocs
      1. Les blocs simples
      2. Les blocs conditionnels
      3. Les blocs répétitifs
      4. Les compteurs de boucles
      5. Les blocs alternatifs
      6. Les blocs imbriqués
      7. Insérer un template dans un autre
      1. Inclure un fichier html
      2. Inclure le contenu d'un template dans une variable
      3. Insérer le même template dans plusieurs variables
    • Inclure du php


    » I-a Un template qu'est-ce que c'est?

    Le template (en anglais= modèle, gabarit) est un modèle de document destiné à la mise en page. Son utilisation entraine la séparation de votre code en 2 entités:
    • le code PHP qui servira à récupérer les données
    • et la mise en page, ne comportant que du code html et CSS, avec des zones prédéfinies où seront placées les données générées par le php
    les avantages sont:
    • une meilleure lisibilité: plus de echo dans tous les sens
    • cette séparation du code et de la mise en page permet de modifier totalement la mise en page sans avoir à chercher dans le code les directives d'affichage et inversement

    conseils

    • Ce tuto est plutôt touffu et complexe, mais de difficulté croissante, aussi
      • évitez de passer au chapitre suivant sans avoir bien compris le chapitre en cours
      • ne vous contentez pas de lire, testez les exemples sur votre forum, voire mieux, faites des essais de variations à partir des exemples
    • Ceci n'est pas un tuto de graphisme et de mise en page, vous verrez vite en testant les exemples que la mise en page n'est pas très soignée, mais c'est pour éviter que la complexité de la mise en page ne masque l'essentiel.


    » I-b Préalables

    Nous allons travailler sur 2 fichiers:

    • un fichier de templates nommé test_body.html que vous placerez dans le répertoire styles/prosilver/template/
    • un fichier php nommé test.php à mettre dans la racine du forum.
      Ce fichier devra toujours commencer par l'appel à une session phpBB:
      Code: Tout sélectionner
      <?php
      define('IN_PHPBB', true);
      $phpbb_root_path =  './';
      $phpEx = substr(strrchr(__FILE__, '.'), 1);
      include($phpbb_root_path . 'common.' . $phpEx);
      $user->session_begin();
      $auth->acl($user->data);
      $user->setup();    

      à la fin de ce code, nous disposons de:
      • $user->data qui est un tableau contenant tous les champs des tables user et sessions. Par exemple, le pseudo est obtenu à partir de
        Code: Tout sélectionner
        $username = $user->data['username'];
      • $user->lang qui permet d'accéder à toutes les clés de langage
      • $template qui est une entité de la classe template et que nous serons amenés à utiliser souvent


    » II Premier exemple: affectation d'une variable

    Nous allons faire un simple script qui souhaite la bienvenue au pseudo connecté.
    Dans votre fichier test.php placez le code suivant:
    Code: Tout sélectionner
    <?php
    define('IN_PHPBB', true);
    $phpbb_root_path =  './';
    $phpEx = substr(strrchr(__FILE__, '.'), 1);
    include($phpbb_root_path . 'common.' . $phpEx);
    $user->session_begin();
    $auth->acl($user->data);
    $user->setup();
    
    $username = $user->data['username'];
    $template->set_filenames(array('body' => 'test_body.html'));
    $template->assign_vars(array(
        'PSEUDO'     => $username,
    ));
    $template->display('body');
    ?>

    et dans test_body.html, cette simple ligne:
    Code: Tout sélectionner
    Bienvenue {PSEUDO}

    Exécutez le fichier test.php et observez le résultat.

    Explications

    • Code: Tout sélectionner
      $username = $user->data['username'];
      => récupère le nom de l'utilisateur
      • Code: Tout sélectionner
        $template->set_filenames(array('body' => 'test_body.html'));
        => attribue au fichier test_body.html un template ayant l'identifiant body. vous pouvez ainsi utiliser plusieurs fichiers html à condition de leur attribuer des identifiants différents
        • Code: Tout sélectionner
          $template->assign_vars(array(
          	'PSEUDO'	 => $username,
          ));
          => va affecter à la variable template PSEUDO la variable $username.
          Pour cela, le moteur de template va rechercher dans le fichier html toutes les occurences de {PSEUDO} et les remplacer par le contenu de $username.
            Dans cet exemple, nous n'avions assigné qu'une variable, mais si plusieurs variables sont à assigner, il n'est pas nécessaire de lancer à chaque fois la fonction assign_vars, il suffit d'ajouter des clés dans l'array:
            Code: Tout sélectionner
            $template->assign_vars(array(
            	'VAR1' => 'valeur 1',
            	'VAR2' => 'valeur 2',
            	'VAR3' => 'valeur3'
            ));
            
            avec à gauche, le nom de la variable qu'on trouvera entre accolades { } dans le template, et à droite la valeur qu'on veut lui assigner
            • Code: Tout sélectionner
              $template->display('body');
              => affiche le template ayant l'identifiant body
            Les erreurs possibles

            Dans test.php remplacez:
            Code: Tout sélectionner
            $template->set_filenames(array('body' => 'test_body.html'));

            par:
            Code: Tout sélectionner
            $template->set_filenames(array('body' => 'test_body2.html'));

            et exécutez-le. Vous allez voir s'afficher le message suivant:
            Erreur générale

            template->_tpl_load_file(): File ./styles/prosilver/template/test_body2.html does not exist or is empty

            vous avez attribué à votre template body un fichier qui n'existe pas où qui n'est pas à la bonne adresse.

            Travailler avec les clés de langue

            phpBB étant capable de fonctionner avec plusieurs langues, il faut éviter de mettre du texte en 'dur' dans votre fichier html mais au contraire utiliser les clés de langue.

            Reprenez le fichier test_body.tpl et remplacez son contenu par:
            Code: Tout sélectionner
            {L_WELCOME} {PSEUDO}


            Exécutez test.php après avoir effacé le cache.
            Vous voyez s'afficher {WELCOME} suivi du pseudo. Que s'est-il passé ?
            Quand le moteur de template trouve une variable commençant par L_ il va chercher dans les clés de langue une clé portant le nom de cette variable sans le L_. S'il la trouve il l'affiche, sinon il affiche le nom de la clé manquante entre accolades. Ceci est commode pour trouver les clés de langue manquantes.

            Nous allons donc devoir ici créer la clé WELCOME:
            Ouvrez languages/fr/common.php, cherchez:
            Code: Tout sélectionner
            	'WARN_USER'			=> 'Avertir l’utilisateur',

            et ajoutez après
            Code: Tout sélectionner
            	'WELCOME'			=> 'Bienvenue',

            Sauvegardez, effacez le cache et relancez test.php. Le message de bienvenue s'affiche correctement.

            Conventions de dénomination des variables templates

            • Les variables templates doivent être entre accolades {}
            • par convention elles sont écrites en majuscules afin de mieux les distinguer du code html
            • les variables de texte doivent commencer par L_, les urls par U_ , les urls javascript par UA_, les textes javascript par LA_, les données système par S_ et le reste à votre convenance (si vous ne respectez pas ces conventions, sauf pour les accolades, ça n'entrainera pas d'erreur, c'est juste pour améliorer la lisibilité de votre code)
            Un petit rappel

            On a pu voir, sur le forum, des utilisateurs tester:
            Code: Tout sélectionner
            $template->set_filenames(array('body' => 'mon_fichier.php');
            et s'étonner que les instructions php ne s'appliquent pas.
            Alors il est nécessaire de rappeler que les templates ne sont pas des fichiers d'éxécution.
            Une fois que les variables ont été remplacées par les données issues du script php, le template est destiné à l'affichage et les seuls scripts qui s'exécuteront sont les scripts javascript.

            Vous verrez au dernier chapitre qu'il est quand même possible d'insérer des scripts PHP à l'intérieur de votre template, mais avec une syntaxe particulière et cela doit rester exceptionnel.


            » III-a Les blocs simples

            Supposons que vous vouliez réserver certains affichages aux utilisateurs connectés. On va donc créer un bloc de code html dont l'affichage sera conditionné par le statut de connexion.

            Un bloc se définit par un début et une fin qui encadre le code html à afficher:

            • début de bloc code html de début de commentaire <!-- suivi de BEGIN suivi du nom du bloc suivi du code html de fin de commentaire -->
              par exemple:
              Code: Tout sélectionner
              <!-- BEGIN bloc -->

              • fin de bloc code html de début de commentaire <!-- suivi de END suivi du nom du bloc suivi du code html de fin de commentaire -->
                par exemple:
                Code: Tout sélectionner
                <!-- END bloc -->

              Côté php la directive d'affichage se fait par la méthode assign_block_vars. par exemple pour afficher le contenu du bloc 'bloc', on fera:
              Code: Tout sélectionner
              $template->assign_block_vars('bloc', array());

              A noter que, ici, on a une array qui est vide, mais elle peut contenir des variables à assigner, nous verrons ça plus loin.

              Voici l'exemple complet de l'affichage du message de bienvenue uniquement si l'utilisateur est connecté:

              • Côté php:
                Code: Tout sélectionner
                <?php
                define('IN_PHPBB', true);
                $phpbb_root_path =  './';
                $phpEx = substr(strrchr(__FILE__, '.'), 1);
                include($phpbb_root_path . 'common.' . $phpEx);
                $user->session_begin();
                $auth->acl($user->data);
                $user->setup();
                
                $username = $user->data['username'];
                $template->set_filenames(array('body' => 'test_body.html'));
                if ($user->data['user_id'] != ANONYMOUS)
                {
                	$template->assign_block_vars('bloc', array());
                }
                $template->assign_vars(array(
                	'PSEUDO'	 => $username,
                ));
                $template->display('body');
                ?>

                • Côté html:
                  Code: Tout sélectionner
                  <!-- BEGIN bloc -->
                  {L_WELCOME} {PSEUDO}
                  <!-- END bloc -->

                Les erreurs possibles

                Si vous omettez la fin de bloc ou faites une erreur de syntaxe dans la directive de bloc (il doit y avoir un espace avant BEGIN ou END et un espace après le nom de bloc, alors vous obtiendrez l'erreur suivante:
                Parse error: syntax error, unexpected $end in C:\wamp\www\phpBB3\includes\template.php(175) : eval()'d code on line 3


                Celaa signifie que template.php a essayé d'évaluer le fichier html et a échoué car il n'a pas trouvé la directive de fin de bloc.
                Rappelez vous ceci: la mention eval()'d code signifie qu'il s'agit d'une erreur de template et non d'une faute de syntaxe au niveau php.


                » III-b Les blocs conditionnels

                Nous avons vu au précédent paragraphe comment afficher ou non le contenu d'un bloc. Mais dans le précédent exemple, si l'utilisateur n'était pas connecté alors il ne s'affichait rien.
                C'est tout l'intérêt des blocs conditionnels qui sont encadrés par des <!-- IF condition -->, <!-- ELSE --> et <!-- ENDIF -->.

                Reprenons test_body.html. Nous allons utiliser une variable template S_USER_LOGGED_IN qui sera assignée à true ou false selon le statut de connexion:
                Code: Tout sélectionner
                <!-- IF S_USER_LOGGED_IN -->
                {L_WELCOME} {PSEUDO}
                <!-- ELSE -->
                {L_LOGIN_PAGE}
                <!-- ENDIF -->


                Là encore si vous omettez le ENDIF vous aurez droit, comme dans le précédent exemple, à une erreur d'évaluation de code.

                Les différents opérateurs peuvent être:
                • Egal à: == ou eq
                • différent de: !=, neq ou <>
                • supérieur à: >
                • inférieur à: <
                • supérieur ou égal, inférieur ou égal: >=, <=
                • modulo: % ou mod
                • ET: && ou and
                • OU: || ou or
                • NON: ! ou not
                • is even, is odd pour déterminer si un nombre est pair ou impair

                Notez la variable L_LOGIN_PAGE; elle fait référence à une clé de langue LOGIN_PAGE qu'il nous faudra créer dans language/fr/common.php en plaçant:
                Code: Tout sélectionner
                	'LOGIN_PAGE'						=> 'Vous devez être connecté pour voir cette page',


                Par exemple après:
                Code: Tout sélectionner
                	'LOGIN_INFO'						=> 'Vous devez être enregistré pour vous connecter. L’enregistrement ne prend que quelques secondes et augmente vos possibilités. L’administrateur du forum peut également accorder des permissions additionnelles aux utilisateurs enregistrés. Avant de vous enregistrer, assurez-vous d’avoir pris connaissance de nos conditions d’utilisation et de notre politique de vie privée. Assurez-vous de bien lire tout le règlement du forum.',


                Côté php, il faut assigner une valeur à la variable S_USER_LOGGED_IN en fonction du statut de connexion, on va pour celà utiliser la variable php $user_logged_in:
                Code: Tout sélectionner
                <?php
                define('IN_PHPBB', true);
                $phpbb_root_path =  './';
                $phpEx = substr(strrchr(__FILE__, '.'), 1);
                include($phpbb_root_path . 'common.' . $phpEx);
                $user->session_begin();
                $auth->acl($user->data);
                $user->setup();
                
                $username = $user->data['username'];
                $template->set_filenames(array('body' => 'test_body.html'));
                $user_logged_in = ($user->data['user_id'] != ANONYMOUS) ? true : false;
                $template->assign_vars(array(
                	'S_USER_LOGGED_IN' => $user_logged_in,
                	'PSEUDO'	 => $username,
                ));
                $template->display('body');
                ?>



                » III-c Les blocs répétitifs

                Il arrive fréquemment qu'on ait à répéter plusieurs fois une même ligne de code avec quelques variations.
                C'est ici l'intérêt du bloc répétitif.
                C'est similaire au bloc simple, sauf que l'instruction $template->assign_block_vars va être répétée plusieurs fois, avec à chaque passage l'assignation de valeurs différentes aux variables contenues dans le bloc.

                Dans notre exemple, nous allons afficher la liste des 10 premiers membres du forum, triés par ordre alphabétique:

                • Côté html ça donnera ceci:
                  Code: Tout sélectionner
                  <!-- BEGIN row -->
                  {row.USERNAME}<br />
                  <!-- END row -->


                  Vous remarquerez que la variable USERNAME est précédée de row.. C'est pour bien indiquer qu'elle est attachée au bloc 'row'. Si vous omettiez le nom du bloc, il ne s'afficherait rien.
                  • Côté php:
                    On effectue d'abord la requête sql qui récupère les 10 premiers pseudos:
                    Code: Tout sélectionner
                    $template->set_filenames(array('body' => 'test_body.html'));
                    $sql = 'SELECT username FROM ' . USERS_TABLE . '
                    		ORDER by username ASC LIMIT 0,10';
                    $result = $db->sql_query($sql);


                    Ensuite on parcourt la boucle, en assignant à chaque fois à la variable USERNAME le contenu du champ username:
                    Code: Tout sélectionner
                    while($row = $db->sql_fetchrow($result))
                    {
                    	$template->assign_block_vars('row', array(
                    		'USERNAME'	 => $row['username']
                    	));
                    }


                    Et voici le script complet:
                    Code: Tout sélectionner
                    <?php
                    define('IN_PHPBB', true);
                    $phpbb_root_path =  './';
                    $phpEx = substr(strrchr(__FILE__, '.'), 1);
                    include($phpbb_root_path . 'common.' . $phpEx);
                    $user->session_begin();
                    $auth->acl($user->data);
                    $user->setup();
                    $template->set_filenames(array('body' => 'test_body.html'));
                    $sql = 'SELECT username FROM ' . USERS_TABLE . '
                    		ORDER by username ASC LIMIT 0,10';
                    $result = $db->sql_query($sql);
                    while($row = $db->sql_fetchrow($result))
                    {
                    	$template->assign_block_vars('row', array(
                    		'USERNAME'	 => $row['username']
                    	));
                    }
                    $template->display('body');
                    ?>


                  » III-d Les compteurs de boucle

                  Quand on lance l'instruction $template->assign_block_vars, le moteur de template crée automatiquement certaines variables:
                  - S_FIRST_ROW indique qu'on est à la première occurence de la boucle
                  - S_LAST_ROW dernière occurence de la boucle
                  - S_ROW_COUNT indique l'occurence en cours, la première ayant pour valeur zéro

                  A titre d'exemple, nous allons reprendre la liste des 10 premiers users, mais cette fois affichée dans un tableau.
                  Le tag <table> sera affiché avec la première ligne, </table> avec la dernière ligne:

                  • Côté php: rien de changé par rapport à l'exemple précédent.
                    • Côté html:
                      Code: Tout sélectionner
                      <!-- BEGIN row -->
                      	<!-- IF row.S_FIRST_ROW -->
                      		<table border="1">
                      	<!-- ENDIF -->
                      	<tr>
                      		<td>
                      			{row.USERNAME}
                      		</td>
                      	</tr>
                      	<!-- IF row.S_LAST_ROW -->
                      		</table>
                      	<!-- ENDIF -->
                      <!-- END row -->

                    La variable S_COUNT_ROW peut être utilisée pour alterner la mise en page des lignes qui se succèdent.
                    Nous allons reprendre l'exemple précédent et alterner des lignes rouges et vertes:

                    • Côté php: pas de changement.
                      • Côté html:
                        Code: Tout sélectionner
                        <!-- BEGIN row -->
                        	<!-- IF row.S_FIRST_ROW -->
                        		<table border="1">
                        	<!-- ENDIF -->
                        	<!-- IF row.S_ROW_COUNT is even -->
                        		<tr bgcolor="#FF0000">
                        	<!-- ELSE -->
                        		<tr bgcolor="#00FF00">
                        	<!-- ENDIF -->
                        		<td>
                        			{row.USERNAME}
                        		</td>
                        	</tr>
                        	<!-- IF row.S_LAST_ROW -->
                        		</table>
                        	<!-- ENDIF -->
                        <!-- END row -->

                      Une autre façon d'utiliser le compteur de boucles est d'indicer le nom du bloc:
                      Code: Tout sélectionner
                      <!-- BEGIN row(2) -->
                      => n'affichera le bloc qu'à partir de la 3ème occurence de la boucle (la première étant zéro)
                        Code: Tout sélectionner
                        <!-- BEGIN row(-2) -->
                        => affichera à compter de l'avant dernière occurence


                        » III-e Les blocs alternatifs

                        Nous avons vu dans le paragraphe précédent comment afficher plusieurs fois un même bloc de code.
                        Mais si la requête avait aboutie à un résultat vide, nous aurions alors une page blanche, d'où l'intérêt de disposer d'un affichage alternatif.

                        Dans cet exemple, nous allons afficher les 10 premiers utilisateurs dont le pseudo commence par ZZZ; peu de chance que ça aboutisse à un résultat:

                        • Côté php, nous changeons juste la requête sql:
                          Code: Tout sélectionner
                          $sql = 'SELECT username FROM ' . USERS_TABLE . '
                          	WHERE username LIKE "ZZZ%"
                          		ORDER by username ASC LIMIT 0,10';

                          • Côté html, afin de ne pas trop surcharger le code, nous repartons du premier exemple, sans table:
                            Code: Tout sélectionner
                            <!-- BEGIN row -->
                            {row.USERNAME}<br />
                            <!-- BEGINELSE -->
                            {L_NO_USERS}
                            <!-- END row -->


                            Tout ce qui se trouve entre <!-- BEGINELSE --> et <!-- END row --> ne s'affichera que si le bloc 'row' ne fait l'objet d'aucune assignation $template->assign_block_vars. Donc ici, s'affichera la clé de langue 'NO_USERS' qui contient "Les utilisateurs demandés n'existent pas".

                            Une autre façon de parvenir au même résultat:

                            La condition:
                            Code: Tout sélectionner
                            <!-- IF .row -->

                            est vraie si le bloc row est l'objet d'au moins une assignation, ce qui donne ici:

                            Code: Tout sélectionner
                            <!-- IF .row -->
                            	<!-- BEGIN row -->
                            	{row.USERNAME}<br />
                            	<!-- END row -->
                            <!-- ELSE -->
                            	{L_NO_USERS}
                            <!-- ENDIF -->


                          » III-f Les blocs imbriqués

                          Un bloc peut contenir un ou plusieurs bloc "enfants".

                          A titre d'exemple, nous allons lister les catégories de forums et les forums que ces catégories contiennent.

                          Le résultat affichera quelque chose comme ça:

                          Catégorie 1
                          • Forum 1
                          • Forum 2
                          • Forum 3
                          Catégorie 2
                          • Forum 1
                          • Forum 2
                          • Forum 3


                          Nous aurons donc un bloc catégorie qui affichera le nom de la catégorie et un sous-bloc forum qui affichera les forums enfants de cette catégorie sous forme d'une liste à puce.

                          • Côté php:
                            • d'abord une requête listant les catégories, c'est à dire, dans la table phpbb_forums, les forums dont l'id_parent est zéro:
                              Code: Tout sélectionner
                              $template->set_filenames(array('body' => 'test_body.html'));
                              $sql = 'SELECT forum_id, forum_name FROM ' . FORUMS_TABLE . '
                              		WHERE parent_id = 0';
                              $catresult = $db->sql_query($sql);

                              • ensuite une boucle passant en revue toutes les lignes du résultat et assignant à chaque fois le nom de catégorie:
                                Code: Tout sélectionner
                                while($catrow = $db->sql_fetchrow($catresult))
                                {
                                	$template->assign_block_vars('catrow', array(
                                		'CAT_NAME'	=> $catrow['forum_name']
                                	));

                                • toujours dans la boucle catégorie, une requête va lister les forums dont le forum parent est la catégorie en cours:
                                  Code: Tout sélectionner
                                  	$sql = 'SELECT forum_name FROM ' . FORUMS_TABLE . '
                                  			WHERE parent_id = ' . $catrow['forum_id'];
                                  	$forumresult = $db->sql_query($sql);

                                  • ensuite une sous boucle qui parcourt tous ces forums et assigne la variable du sous-bloc:
                                    Code: Tout sélectionner
                                    	while($forumrow = $db->sql_fetchrow($forumresult))
                                    	{
                                    		$template->assign_block_vars('catrow.forumrow', array(
                                    			'FORUM_NAME' => $forumrow['forum_name']
                                    		));
                                    	}
                                    Vous remarquerez que l'appel à assign_block_vars doit comprendre le nom du bloc principal suivi du nom du sous-bloc.
                                    • Et voilà donc le script complet:
                                      Code: Tout sélectionner
                                      <?php
                                      define('IN_PHPBB', true);
                                      $phpbb_root_path =  './';
                                      $phpEx = substr(strrchr(__FILE__, '.'), 1);
                                      include($phpbb_root_path . 'common.' . $phpEx);
                                      $user->session_begin();
                                      $auth->acl($user->data);
                                      $user->setup();
                                      $template->set_filenames(array('body' => 'test_body.html'));
                                      $sql = 'SELECT forum_id, forum_name FROM ' . FORUMS_TABLE . '
                                      		WHERE parent_id = 0';
                                      $catresult = $db->sql_query($sql);
                                      while($catrow = $db->sql_fetchrow($catresult))
                                      {
                                      	$template->assign_block_vars('catrow', array(
                                      		'CAT_NAME'	=> $catrow['forum_name']
                                      	));
                                      	$sql = 'SELECT forum_name FROM ' . FORUMS_TABLE . '
                                      			WHERE parent_id = ' . $catrow['forum_id'];
                                      	$forumresult = $db->sql_query($sql);
                                      	while($forumrow = $db->sql_fetchrow($forumresult))
                                      	{
                                      		$template->assign_block_vars('catrow.forumrow', array(
                                      			'FORUM_NAME' => $forumrow['forum_name']
                                      		));
                                      	}
                                      }
                                      $template->display('body');
                                      ?>
                                  • Côté html:
                                    • d'abord le début du bloc categories et sa variable nom de catégorie:
                                      Code: Tout sélectionner
                                      <!-- BEGIN catrow -->
                                      	<b>{catrow.CAT_NAME}</b>

                                      • ensuite le début du bloc enfant:
                                        Code: Tout sélectionner
                                        	<!-- BEGIN forumrow -->
                                      • pour lequel on teste d'abord la première ligne, pour placer le tag <ul> d'ouverture de la liste à puce
                                        Code: Tout sélectionner
                                        		<!-- IF forumrow.S_FIRST_ROW -->
                                        		<ul>
                                        		<!-- ENDIF -->

                                        • affichage du nom de forum, vous remarquerez que la variable doit être précédée du nom de son bloc(forumrow) mais aussi du bloc parent de son bloc(catrow):
                                          Code: Tout sélectionner
                                          		<li>{catrow.forumrow.FORUM_NAME}</li>

                                          • on teste la dernière ligne pour placer le tag </ul> de fermeture de la liste à puces:
                                            Code: Tout sélectionner
                                            		<!-- IF forumrow.S_LAST_ROW -->
                                            		</ul>
                                            		<!-- ENDIF -->

                                            • un bloc alternatif pour les catégories ne possédant pas de forum:
                                              Code: Tout sélectionner
                                              	<!-- BEGINELSE -->
                                              	<br/>{L_NO_FORUMS}

                                              • et on ferme les deux blocs:
                                                Code: Tout sélectionner
                                                	<!-- END forumrow -->
                                                <!-- END catrow -->

                                                • et voilà le script dans son ensemble:
                                                  Code: Tout sélectionner
                                                  <!-- BEGIN catrow -->
                                                  	<b>{catrow.CAT_NAME}</b>
                                                  	<!-- BEGIN forumrow -->
                                                  		<!-- IF forumrow.S_FIRST_ROW -->
                                                  		<ul>
                                                  		<!-- ENDIF -->
                                                  		<li>{catrow.forumrow.FORUM_NAME}</li>
                                                  		<!-- IF forumrow.S_LAST_ROW -->
                                                  		</ul>
                                                  		<!-- ENDIF -->
                                                  	<!-- BEGINELSE -->
                                                  	<br/>{L_NO_FORUMS}
                                                  	<!-- END forumrow -->
                                                  <!-- END catrow -->


                                              » IV-a Inclure un fichier html

                                              Chacune de vos pages contient fréquemment des parties de code html identiques qu'il serait fastidieux de réécrire à chaque fois.

                                              Par exemple, vos pages contiennent généralement le même entête et le même pied de page, c'est tout l'intérêt de la directive INCLUDE qui permet d'insérer un autre fichier html dans votre template. Elle se présente ainsi:

                                              Code: Tout sélectionner
                                              <!-- INCLUDE votre_fichier.html -->

                                                Dans l'exemple suivant, qui reprend l'exemple du message d'accueil, nous allons afficher l'entête et le pied de page de phpBB3:

                                                • Côté html:
                                                  Code: Tout sélectionner
                                                  <!-- INCLUDE overall_header.html -->
                                                  {L_WELCOME} {PSEUDO}
                                                  <!-- INCLUDE overall_footer.html -->
                                                  

                                                  • Côté php:
                                                    Code: Tout sélectionner
                                                    <?php
                                                    define('IN_PHPBB', true);
                                                    $phpbb_root_path =  './';
                                                    $phpEx = substr(strrchr(__FILE__, '.'), 1);
                                                    include($phpbb_root_path . 'common.' . $phpEx);
                                                    $user->session_begin();
                                                    $auth->acl($user->data);
                                                    $user->setup();
                                                    
                                                    page_header();
                                                    $username = $user->data['username'];
                                                    $template->set_filenames(array('body' => 'test_body.html'));
                                                    $template->assign_vars(array(
                                                       'PSEUDO'    => $username,
                                                    ));
                                                    page_footer();
                                                    ?>


                                                    Ce qui a changé par rapport à l'exemple simple:
                                                    Code: Tout sélectionner
                                                    page_header();
                                                    =>appelle une fonction qui se charge d'assigner les variables du fichier overall_header.html
                                                      Code: Tout sélectionner
                                                      page_footer();
                                                      =>même chose avec overall_footer.html

                                                      et nous avons enlevé:
                                                      Code: Tout sélectionner
                                                      $template->display('body');
                                                      car la fonction page_footer s'en charge

                                                    Evidemment vous pourrez souhaiter afficher vos propres entêtes et bas de page. Dans ce cas vous incluerez d'autres fichiers html que overall_header et overall_footer, et côté php vous remplacerez page_header() et page_footer() par:
                                                    Code: Tout sélectionner
                                                    include($phpbb_root_path.'header.php');

                                                      et:
                                                      Code: Tout sélectionner
                                                      include($phpbb_root_path.'footer.php');

                                                      ou tout autre nom de fichier à votre convenance, ces scripts se chargeant de l'affichage de vos entête et bas de page.


                                                      » IV-b Insérer le contenu d'un template dans une variable

                                                      Imaginons une ébauche de portail avec un entête, un bas de page et entre les deux plusieurs blocs (connexion, accueil, dernières news, etc) ces blocs pourraient être représentés par un ensemble de variables templates dans lesquels on insérerait le contenu d'un template pour insérer un template dans une variable, on utilise la fonction assign_display qui se présente sous cette forme:
                                                      Code: Tout sélectionner
                                                      $template->assign_display($handle, $template_var, $return_code)


                                                      où:
                                                      • $handle (seul paramètre obligatoire) représente l'identifiant du template à insérer
                                                      • $template_var (vide par défaut) est la variable de template où l'on veut insérer le template
                                                      • $return_code (vrai par défaut) si vrai, on met le contenu du template dans une variable php

                                                      On a donc deux façons d'utiliser cette fonction:
                                                      • Code: Tout sélectionner
                                                        $template->assign_display('body', 'MA_VAR', false);
                                                        => va insérer dans la variable template MA_VAR le contenu du template d'identifiant body
                                                        • Code: Tout sélectionner
                                                          $html = $template->assign_display('body');
                                                          => va mettre dans la variable $html le contenu du template d'identifiant body

                                                        C'est la première méthode que nous allons utiliser dans l'exemple suivant:

                                                        • test_body.html
                                                          Il va comporter entête et bas de page et une suite de variables, chacune représentant un module du portail:
                                                          Code: Tout sélectionner
                                                          <!-- INCLUDE overall_header.html -->
                                                          <table width="100%" border="1">
                                                          <tr>
                                                          <td>{BLOC1}</td><td>{BLOC2}</td><td>{BLOC3}</td>
                                                          </tr>
                                                          <tr>
                                                          <td>{BLOC4}</td><td>{BLOC5}</td><td>{BLOC6}</td>
                                                          </tr>
                                                          <tr>
                                                          <td>{BLOC7}</td><td>{BLOC8}</td><td>{BLOC9}</td>
                                                          </tr>
                                                          </table>
                                                          <!-- INCLUDE overall_footer.html -->
                                                          Pour ne pas surcharger le code, nous allons nous contenter de remplir BLOC1 avec le message d'accueil et BLOC2 avec la liste des 10 premiers users.
                                                          • test.php
                                                            Il va comporter l'appel aux fonctions page_header et page_footer, déclarer l'association avec le template test_body.html et inclure les 2 scripts php qui rempliront BLOC1 et BLOC2: welcome.php et list_users.php
                                                            Code: Tout sélectionner
                                                            <?php
                                                            define('IN_PHPBB', true);
                                                            $phpbb_root_path =  './';
                                                            $phpEx = substr(strrchr(__FILE__, '.'), 1);
                                                            include($phpbb_root_path . 'common.' . $phpEx);
                                                            $user->session_begin();
                                                            $auth->acl($user->data);
                                                            $user->setup();
                                                            
                                                            page_header();
                                                            $template->set_filenames(array('body' => 'test_body.html'));
                                                            include($phpbb_root_path.'welcome.'.$phpEx);
                                                            include($phpbb_root_path.'list_users.'.$phpEx);
                                                            page_footer();
                                                            ?>

                                                            • Les 2 fichiers html des modules welcome et list_users
                                                              Ils reprennent les exemples précédents du message d'accueil et de la liste des 10 premiers users:
                                                            • Les 2 fichiers php des modules welcome et list_users
                                                              Ils reprennent les exemples précédents et en plus insèrent le contenu de leur template associé dans le bloc correspondant (plus une ligne de sécurité qui vérifie que IN_PHPBB existe pour éviter un accès direct)

                                                              • welcome.php
                                                                Code: Tout sélectionner
                                                                <?php
                                                                if (!defined('IN_PHPBB'))
                                                                {
                                                                	exit;
                                                                }
                                                                $username = $user->data['username'];
                                                                $template->set_filenames(array('welcome' => 'welcome.html'));
                                                                $template->assign_vars(array(
                                                                   'PSEUDO'    => $username,
                                                                ));
                                                                $template->assign_display('welcome', 'BLOC1', false);
                                                                ?>

                                                              • list_users.php
                                                                Code: Tout sélectionner
                                                                <?php
                                                                if (!defined('IN_PHPBB'))
                                                                {
                                                                	exit;
                                                                }
                                                                $template->set_filenames(array('list_users' => 'list_users.html'));
                                                                $sql = 'SELECT username FROM ' . USERS_TABLE . '
                                                                      ORDER by username ASC LIMIT 0,10';
                                                                $result = $db->sql_query($sql);
                                                                while($row = $db->sql_fetchrow($result))
                                                                {
                                                                	$template->assign_block_vars('row', array(
                                                                	   'USERNAME'    => $row['username']
                                                                	));
                                                                }
                                                                
                                                                $template->assign_display('list_users', 'BLOC2', false);
                                                                ?>


                                                            » Insérer le même template dans plusieurs variables

                                                            Alors là, accrochez-vous, ça devient compliqué: il s'agit d'insérer le contenu d'un template dans la variable d'un autre template qui va lui même être inséré dans une autre variable.

                                                            Dans un portail, on aime bien que tous les modules aient le même type de mise en page. Il leur faut donc un template commun.

                                                            Le souci c'est que si on insère plusieurs fois le même template, toutes les variables vont avoir le même contenu, qui sera la somme de tous les modules.
                                                            Il faut donc détruire le template après chaque insertion.

                                                            On dispose pour ça de la fonction destroy_block_vars:
                                                            Code: Tout sélectionner
                                                            $template->destroy_block_vars('body');
                                                            => va détruire le contenu du bloc 'body'

                                                            Notre template commun, que nous appellerons common_bloc.html, devra donc contenir un bloc. Il va se présenter ainsi: une table avec un titre sur fond bleu clair et un contenu:
                                                            common_bloc.html
                                                            Code: Tout sélectionner
                                                            <!-- BEGIN bloc -->
                                                            <table width="100%" border="1">
                                                            <tr>
                                                            	<th bgcolor="cyan">{bloc.TITLE}</th>
                                                            </tr>
                                                            <tr>
                                                            	<td>{bloc.CONTENT}</td>
                                                            </tr>
                                                            </table>
                                                            <!-- END bloc -->

                                                              test_body.html, welcome.html et list_users.html sont inchangés.
                                                                test.php offre un tout petit changement: l'association à common_bloc.html auquel ont donnera l'identifiant 'common_bloc'
                                                                Code: Tout sélectionner
                                                                <?php
                                                                define('IN_PHPBB', true);
                                                                $phpbb_root_path =  './';
                                                                $phpEx = substr(strrchr(__FILE__, '.'), 1);
                                                                include($phpbb_root_path . 'common.' . $phpEx);
                                                                $user->session_begin();
                                                                $auth->acl($user->data);
                                                                $user->setup();
                                                                
                                                                page_header();
                                                                $template->set_filenames(array(
                                                                	'body' => 'test_body.html',
                                                                	'common_bloc' => 'common_bloc.html'
                                                                ));
                                                                include($phpbb_root_path.'welcome.'.$phpEx);
                                                                include($phpbb_root_path.'list_users.'.$phpEx);
                                                                page_footer();
                                                                ?>

                                                                  les 2 scripts php des modules welcome et list_users
                                                                  C'est là que réside le plus gros changement: chaque script remplit son template associé, en insère le contenu dans la variable CONTENT du template common_bloc, ensuite le contenu du template common_bloc est inséré dans une des variables du template body, enfin le template common_bloc est détruit.
                                                                    welcome.php
                                                                    on va procéder pas à pas pour plus de compréhension:

                                                                    • récupère le nom de l'utilisateur connecté:
                                                                      Code: Tout sélectionner
                                                                      $username = $user->data['username'];

                                                                    • s'associe au template welcome.html avec l'identifiant welcome:
                                                                      Code: Tout sélectionner
                                                                      $template->set_filenames(array('welcome' => 'welcome.html'));

                                                                    • remplit ce template avec le nom de l'utilisateur:
                                                                      Code: Tout sélectionner
                                                                      $template->assign_vars(array(
                                                                         'PSEUDO'    => $username,
                                                                      ));

                                                                    • place dans la variable php $html le contenu du template d'identifiant welcome:
                                                                      Code: Tout sélectionner
                                                                      $html = $template->assign_display('welcome');

                                                                    • remplit le bloc d'identifiant 'bloc' (appartenant au template common_bloc) avec un titre (clé de langue 'WELCOME') et $html (qui représente le contenu du template welcome):
                                                                      Code: Tout sélectionner
                                                                      $template->assign_block_vars('bloc', array(
                                                                      	'TITLE'	 => $user->lang['WELCOME'],
                                                                      	'CONTENT' => $html
                                                                      ));

                                                                    • insère le contenu du template common_bloc dans la variable BLOC1 du template body:
                                                                      Code: Tout sélectionner
                                                                      $template->assign_display('common_bloc', 'BLOC1', false);

                                                                    • et enfin détruit le bloc d'identifiant 'bloc', donc tout le contenu du template 'common_bloc':
                                                                      Code: Tout sélectionner
                                                                      $template->destroy_block_vars('bloc');

                                                                    • et voici le script complet:
                                                                      Code: Tout sélectionner
                                                                      <?php
                                                                      if (!defined('IN_PHPBB'))
                                                                      {
                                                                      	exit;
                                                                      }
                                                                      $username = $user->data['username'];
                                                                      $template->set_filenames(array('welcome' => 'welcome.html'));
                                                                      $template->assign_vars(array(
                                                                         'PSEUDO'    => $username,
                                                                      ));
                                                                      $html = $template->assign_display('welcome');
                                                                      $template->assign_block_vars('bloc', array(
                                                                      	'TITLE'	 => $user->lang['WELCOME'],
                                                                      	'CONTENT' => $html
                                                                      ));
                                                                      $template->assign_display('common_bloc', 'BLOC1', false);
                                                                      $template->destroy_block_vars('bloc');
                                                                      ?>

                                                                    • list_users.php est bâti sur le même principe:
                                                                      Code: Tout sélectionner
                                                                      <?php
                                                                      if (!defined('IN_PHPBB'))
                                                                      {
                                                                      	exit;
                                                                      }
                                                                      $template->set_filenames(array('list_users' => 'list_users.html'));
                                                                      $sql = 'SELECT username FROM ' . USERS_TABLE . '
                                                                            ORDER by username ASC LIMIT 0,10';
                                                                      $result = $db->sql_query($sql);
                                                                      while($row = $db->sql_fetchrow($result))
                                                                      {
                                                                      	$template->assign_block_vars('row', array(
                                                                      	   'USERNAME'    => $row['username']
                                                                      	));
                                                                      }
                                                                      $html = $template->assign_display('list_users');
                                                                      $template->assign_block_vars('bloc', array(
                                                                      	'TITLE'	 => $user->lang['LIST_USERS'],
                                                                      	'CONTENT' => $html
                                                                      ));
                                                                      $template->assign_display('common_bloc', 'BLOC2', false);
                                                                      $template->destroy_block_vars('bloc');
                                                                      ?>


                                                                    » V Inclure du PHP dans votre template

                                                                    Insérer du php dans votre code HTML doit rester une exception. Il doit être à réserver à l'insertion de bannières publicitaires, de boutons 'Paypal', etc qui nécessitent des scripts externes et ne seraient pas facile à utiliser avec du templating 'standard'. Mais généraliser l'emploi de ces insertions ôterait tout intérêt au templating qui est précisément de séparer php de html.

                                                                    Pour utiliser les insertions de php, vous devez au préalable en avoir donné l'autorisation dans le panneau d'administration: onglet général -> Paramètres de sécurité, option 'Autoriser le PHP dans les templates'.

                                                                    Vous avez deux méthodes pour insérer du php:

                                                                    • l'insertion d'un fichier php:
                                                                      Code: Tout sélectionner
                                                                      <!-- INCLUDEPHP http://www.mon_domaine.com/mon_fichier.php -->

                                                                      • l'insertion de code php:
                                                                        Code: Tout sélectionner
                                                                        <!-- PHP -->
                                                                        	echo "salut tout le monde!";
                                                                        <!-- ENDPHP -->
                                                                        


                                                                        Quand vous insérez du code, ayez en tête la visibilité des variables. Par exemple, si vous faites votre insertion de code dans overall_header.html et que vous utilisez une variable $mavar créée dans index.php, elle ne sera "visible" que si vous commencez par:
                                                                        Code: Tout sélectionner
                                                                        global $mavar;

                                                                      Avatar de l’utilisateur
                                                                      spitfire pat
                                                                      MOD Contest Winner
                                                                      MOD Contest Winner
                                                                       
                                                                      Rédigé le: 20 Oct 2008 à 13:42
                                                                      Articles: 2
                                                                      Noter cet article: 123456 Votants: 3
                                                                      Mots-clés: Tutorial, sur, les, templates, phpBB3, 30x

                                                                      Retourner vers Coding


                                                                      cron