Phpbb2_Template

[ phpBB - phpBB2 ]

Le système de templates de phpBB2

Cet article va vous apprendre comment vous servir du système de template de phpBB2.

Cette documentation est en partie valable pour phpBB3, puisque le système de phpBB3 est une amélioration du système de phpBB2

Les Bases

Avant de créer un template, commencez par considérer si vous en avez besoin ou non. Si cela est très semblable, voire quasi identique à un autre template qui existe déjà, sauf peut être que vous ajouterez une colonne ici ou là, ou que vous ajouterez un tableau avec quelques données supplémentaires en haut ou en bas de la page, c'est une meilleure idée de modifier le template actuel. Si vous ne créez pas le template, mais au contraire en modifiez un ancien, ne vous préoccupez pas des sections (2) et (3), et sautez directement à la section (4).

Création d'un nouveau fichier de template

Un fichier de template peut avoir n'importe quelle extension, mais par standard phpBB, nous préférons que vous vous limitiez à l'extension .tpl (cela le rendra compatible avec la plupart des systèmes de fichier et permettra à d'autres programmeurs à savoir où les templates sont stockés pour les modifier plus facilement). Le fichier en lui même est un fichier texte (text/html), avec juste des balises de style supplémentaires qui vous permettrions de formater vos données proprement.

Spécifier un fichier de template

Pour débuter, vous avez besoin d'inclure le code standard de phpBB (si ce n'est pas déjà fait) pour obtenir l'accès au template, entre autres choses.

define('IN_PHPBB', true);
$phpbb_root_path = './';
include($phpbb_root_path . 'extension.inc');
include($phpbb_root_path . 'common.'.$phpEx);

//
// Début du gestionnaire de sessions
//
$userdata = session_pagestart($user_ip, PAGE_PROFILE);
init_userprefs($userdata);
//
// Fin du gestionnaire de sessions
//

L'inclusion du template est assez facile:

$template->set_filenames(array(
  'body' => 'your_template.tpl')
);

C'est aussi une bonne idée à ce moment d'obtenir les en-têtes spécifiques (si ce n'est pas déjà fait), en supposant que vous voulez le menu normal de phpBB et les choses avez en haut de toutes les pages phpBB. Ceci vous permettra aussi de définir le titre de la page.

$page_title = $lang['My_title']; // Vous devrez placer ceci dans $lang, dans un fichier de langue quelque part
include($phpbb_root_path . 'includes/page_header.'.$phpEx);

Assurez vous aussi d'afficher le template à la fin du fichier

$template->pparse('body');

Ne faites pas cela avant d'avoir fini de passer les variables au moteur de template... tout ce que vous ferez ensuite ne sera pas inclut ! Le 'body' dans pparse correspond au 'body' de set_filenames()

Finalement, vous pouvez inclure le bas de la page (si ce n'a pas déjà été fait)

include($phpbb_root_path . 'includes/page_tail.'.$phpEx);

Les variables de template "basiques"

Il y a deux parties dans la création d'une variable de template. La première partie est la partie en .php, pour générer la donnée qui ira dans la variable. La seconde est la partie en .tpl, qui montre où la donnée doit se trouver dans le document.

Coté PHP : Une fois que vous avez spécifié votre fichier de template, vous pouvez placer la variable de template ainsi:

$template->assign_var('VARIABLE' , $value );

Coté template : vous devrez placer la variable au milieu du html, entourée d'accolades

{VARIABLE}

Le nom des variable de template peut contenir à la fois des majuscules et des minuscules (a-zA-Z), des nombres (0-9), des tirets (-), et des underscores (_). Cependant, le standard phpBB utilise uniquement des lettres majscules, des nombres et des underscores.

Si vous voulez assigner plus d'une variable à la fois, vous devez faire de la façon suivante:

Coté PHP :

   $template->assign_vars(array( 'VARNAME1' => $phpstringval1,
                       'VARNAME2' => $phpstringval2,
                       'VARNAME3' => $phpstringval3,
                       ... etc ..
                       'VARNAMEn' => $phpstringvaln
                     )
                  );

Coté template :

   {VARNAME1} {VARNAME2} {VARNAME3} ... etc ... {VARNAMEn}

Les blocs de test ("Switches")

Les blocs de test sont une partie "optionnelle" des template. Ils apparaissent uniquement si la condition est remplie, sinon le contenu du bloc est caché.

Coté PHP : C'est très facile de créer un bloc de test. Essayez juste le bloc à l'endroit où vous voulez l'appliquer, puis utilisez la méthode assignblockvars() pour l'activer effectivement:

   if ( $userdata['session_logged_in'] )
   {
      $template->assign_block_vars('switch_user_logged_in',array() );
   }

Coté template : Dans le template, vous devrez placer les balises ainsi:

   <!-- BEGIN switch_user_logged_in -->
   ... stuff that only shows up when the user is logged in...
   <!-- END switch_user_logged_in -->

Notez qu'il est important que les blocs <!-- BEGIN ... --> et <!-- END ... --> apparaissent seuls sur leur ligne , autrement, cela pourrais ne pas fonctionner.

Malheureusement, il n'y a aucun type de test "if - else" (contrairement à phpBB3), mais il y a plusieurs autres moyens de s'en passer, regardez:

Coté PHP :

     if ( $userdata['session_logged_in'] )
     {
         $template->assign_block_vars('switch_user_logged_in',array() );
     }
     else
     {
         $template->assign_block_vars('switch_user_logged_out',array() );
     }

Coté template :

     <!-- BEGIN switch_user_logged_in -->
     ... s'affiche uniquement si l'utilisateur est loggué...
     <!-- END switch_user_logged_in -->
     <!-- BEGIN switch_user_logged_out -->
     ... s'affiche uniquement si l'utilisateur n'est pas loggué...
     <!-- END switch_user_logged_out -->

Boucles

A présent nous allons commencer qulque chose d'un peu plus compliqué. Que se passe il si vous voulez afficher quelque chose plus d'une fois ? Vous pouvez dupliquer le code html dans le template, ce qui est facile, mais que se passe il si ce n'est pas statique, et de plus, définit dans le PHP ?

Par exemple, nous voulons répéter un texte 10 fois:

Coté PHP : Cela ressemble beaucoup à la création d'un test, sauf que vous appelez la même chaine dans assignblockvars() plusieurs fois.

   $n = 10;
   for ( $i = 0; $i < $n; $i++ )
   {
      $template->assign_block_vars('my_loop',array() );
   }

Coté template : Ceci est à peu de choses près la même chose:

   <!-- BEGIN my_loop -->
   This text will show up ten times
   <!-- END my_loop -->

C'est assez simple. Mais ce n'est pas très utile... Sinon bien sur, vous avez différentes données dans chaque boucle, ce qui nous amène à...

Les variables de boucle

Vous êtes vous déjà demandé à quoi ce tableau vide array()@ dans assignblockvars()@@ peut bien servir ? C'est cela. Laissez moi vous montrer comment on affiche le nombre d'iterations de la boucle, et combien on en fera:

Coté PHP : Semblable au fait que nous avons des variables de template, nous pouvons spécifier des variables de boucle à l'intérieur de la boucle array()

   $n = 10;
   for ( $i = 0; $i < $n; $i++ )
   {
      $template->assign_block_vars('my_loop',array( 'CETTE_ITERATION' => ($i + 1),
                                        'ITERATIONS_TOTALES' => $n
                                       )
                            );
   }

Coté template :

   <!-- BEGIN my_loop -->
   Ce texte sera affiché dix fois (Il s'agit de la #{my_loop.CETTE_ITERATION} itération sur {my_loop.ITERATIONS_TOTALES} )
   <!-- END my_loop -->

Une chose importante à noter ici est qu'avant la variable, vous devez mettre le nom de la boucle suivi d'un point (.), si vous ne le faites pas, le moteur de template pensera qu'il s'agit d'une variable de template, et (sans doute) ne trouvera pas de correspondance, et donc n'affichera rien du tout.

Vous remarquerez que le nombre ITERATIONSTOTALES est toujours le même. C'est un peu de gaspillage, car nous stockons ITERATIONSTOTALES pour chaque itérations, alors qu'il n'y a qu'une valeur. Tant que vous êtes dans la même boucle d'une structure de plus haut niveau, (si vous ne comprenez pas ce que cela veut dire, ne vous inquiétez pas) vous pouvez afficher des variables qui ne sont pas dans la boucle elle même:

Coté PHP :

   $n = 10;
   $template->assign_vars(array ( 'TOTAL_LOOPS' => $n ) );
   for ( $i = 0; $i < $n; $i++ )
   {
      $template->assign_block_vars('my_loop',array( 'THIS_LOOP' => ($i + 1) ) );
   }

Coté template

   <!-- BEGIN my_loop -->
   This text will show up ten times (this is #{my_loop.THIS_LOOP} of {TOTAL_LOOPS} )
   <!-- END my_loop -->

Ici aussi, un exemple plus compliqué (et plus applicable): Liste tous les utilisateurs avec l'user_id entre 1 et 25

Coté PHP :

   $sql = "SELECT user_id, username FROM " . USERS_TABLE . " WHERE user_id >= 1 AND user_id <= 25";
   if ( ! ( $result = $db->sql_query($sql) ) )
   {
   message_die(GENERAL_ERROR, 'Error retrieving user data', '', __LINE__, __FILE__, $sql);
   }
   while ( $row = $db->sql_fetchrow($result) )
   {
   $template->assign_block_vars('user_row',array( 'USERNAME' => htmlspecialchars($row['username']),
                                       'USER_ID' => $row['user_id']
                                      )
                         );
   }

Coté template :

   <table>
   <!-- BEGIN user_row -->
   <tr><td>{user_row.USER_ID}</td><td>{user_row.USERNAME}</td></tr>
   <!-- END user_row -->
   </table>

Boucles/Tests imbriqués

C'est ici que les choses deviennent plus compliquées, et que les auteurs de template se retrouvent souvent perdus. Que se passe-t-il si vous voulez faire un boucle dans une autre boucle ou test ?

Par exemple, vous voulez afficher une liste des 25 premiers utilisateurs, et leurs emails, mais ne l'afficher que si l'utilisateur de la page est administrateur ou modérateur ? Ajoutons un peu de code à l'exemple précédent:

Coté PHP :

   $sql = "SELECT user_id, username, user_email FROM " . USERS_TABLE . " WHERE user_id >= 1 AND user_id <= 25";
   if ( ! ( $result = $db->sql_query($sql) ) )
   {
   message_die(GENERAL_ERROR, 'Error retrieving user data', '', __LINE__, __FILE__, $sql);
   }
   while ( $row = $db->sql_fetchrow($result) )
   {
   $template->assign_block_vars('user_row',array( 'USERNAME' => htmlspecialchars($row['username']),
                                       'USER_ID' => $row['user_id'],
                                       'USER_EMAIL' => $row['user_email']
                                      )
                         );
   if ( ($userdata['user_level'] == ADMIN) || ($userdata['user_level'] == MOD) )
   {
      $template->assign_block_vars('user_row.switch_admin_or_mod',array());
   }
   }

Coté template :

   <table>
   <!-- BEGIN user_row -->
   <tr><td>{user_row.USER_ID}</td><td>{user_row.USERNAME}</td>
   <!-- BEGIN switch_admin_or_mod -->
   <td>{user_row.USER_EMAIL}</td>
   <!-- END switch_admin_or_mod -->
   </tr>
   <!-- END user_row -->
   </table>

Une des choses importantes à noter est le fait que dans le PHP, le nom du test est user_row.switch_admin_or_mod, mais que dans le template, le nom est uniquement switch_admin_or_mod, ce qui est dans le @@userrow@@. Cela veut dire que vous ne pouvez pas créer deux tests dans le même bloc et espérer que les deux fonctionnent:_

Coté PHP :

   $template->assign_block_vars('switch_user_logged_in',array() );
   $template->assign_block_vars('switch_admin_or_mod',array() );

Coté template :

   <!-- BEGIN switch_user_logged_in -->
   <!-- BEGIN switch_admin_or_mod -->
   some text if it's an admin or mod, logged in
   <!-- END switch_admin_or_mod -->
   <!-- END switch_user_logged_in -->

Ceci ne fonctionnera pas car le moteur de template recherchera switch_user_logged_in.switch_admin_or_mod et ne le trouvera pas. Une façon de contourner ceci pourrais être:

   $template->assign_block_vars('switch_user_logged_in',array() );
   $template->assign_block_vars('switch_user_logged_in.switch_admin_or_mod',array() );

Sinon, nous pouvons avoir un test séparé. Il y a pour le moment plusieurs moyens de faire cela proprement, si vous y pensez.

Variables de boucles imbriquées

Juste pour que vous sachiez coment ça marche.

Laissez moi vous donner comme exemple un tableau d'utilisateurs, chacun d'eux a un nom et un identifiant d'attribut, comme par exemple l'attribut 'friends' qui sera donc un tableau contenant le nom de ses amis, et vous voulez afficher la liste des utilisateurs, et qui sont leurs amis.

Coté PHP :

   for ($i = 0; $i < count($dataset); $i++ )
   {
      $template->assign_block_vars('user_row', array( 'USER_ID' => $dataset[$i]['user_id'],
                                          'USER_NAME' => $dataset[$i]['user_name']
                                        )
                           );
      for($j = 0; $j < count($dataset[$i]['friends']); $j++ )
      {
         $template->assign_block_vars('user_row.friend_row',array( 'NAME' => $dataset[$i]['friends'][$j] ) );
      }
   }

Coté template :

   <table>
   <!-- BEGIN user_row -->
   <tr><td>{user_row.USER_ID}</td><td>{user_row.USERNAME}</td><td><table>
   <!-- BEGIN friend_row -->
   <tr><td>{user_row.friend_row.NAME}</td></tr>
   <!-- END friend_row -->
   </table></td>
   </tr>
   <!-- END user_row -->
   </table>

Assigner des variables depuis un pointeur

Vous pouvez aussi créer des "sous" templates indépendants pour éviter les tests massifs. Par exemple, la boite de sondage dans l'affichage du sujet. Elle ne sera jamais affiché, affichera l'option pour voter, ou affichera le résultat du sondage.

Coté PHP : Le sous-template reçois les variables de template normales, donc vous pouvez les assigner normalement. Pour spécifier un sous-template, vous préférerez l'appeler come s'il étais un template normal.

   if ( $poll_exists )
   {
   if ( $user_voted)
   {
      $template->set_filenames(array(
         'pollbox' => 'viewtopic_poll_result.tpl')
      );
   }
   else
   {
      $template->set_filenames(array(
         'pollbox' => 'viewtopic_poll_ballot.tpl')
      );
   }
   $template->assign_var('POLL_NAME' => $poll_name); // Fictional example
   for ($i = 0; $i < count($poll_options); $i++ )
   {
      $template->assign_block_vars('poll_option',array('OPTION_NAME' => $poll_options[$i]) ); // Another fictional example
   }
   $template->assign_var_from_handle('POLL_DISPLAY', 'pollbox');
   }

Les variabes que vous voulez afficher dans le sous-template doivent être assignées avant d'appeler la méthode assign_var_from_handle()

Côté template : Affichez le tout simplement comme une variable normale.

   {POLL_DISPLAY}

Vous ne pouvez pas assigner des variables de boucle par pointeur.

La clef dans l'appel de set_filenames() (par exemple, 'pollbox') doit être identique à la valeur dans l'appel de assign_var_ from_handle().

Les erreurs fréquentes

Cette erreur signifie que votre fichier .tpl n'a pas été trouvé, ou n'est pas accessible en lecture. Vérifiez le chemin mis lors de l'instance de la classe.

Cette erreur signifie que vous avez une erreur de syntaxe lors de la fusion des fichiers PHP et template, normalement c'est que vous avez fait une erreur au niveau des blocs. Vérifiez bien que chacun de vos blocs <!-- BEGIN ... --> sont fermés par des <!-- END ... -->, que vous n'avez pas mis de caractères bizarres (ne mettez que des caractères alphanumériques pour les variables et les blocs), que vous n'avez pas oublié un espace dans la syntaxe du bloc.

Cette erreur signifie que vous tentez d'utiliser un alias dans la méthode pparse() qui n'a pas été créé. Vérifiez bien la concordance avec la méthode set_filenames()

Documentation réalisée librement à partir de Knowledge Base - phpBB2 Template Tutorial et de Développez.com

Creative Commons License