Toutefois, une transition vers un design à la Twig va s'opérer côté public. En 2.7, le moteur de templates de clearbricks va introduire deux nouvelles notions :

  • Les jeux de templates
  • L'héritage de templates

Les jeux de templates, ie. ne-cassons-pas-tout

Dans la version actuelle de dotclear, les fichiers templates "par défaut" sont positionnés dans le répertoire inc/public/default-templates.

Les nouvelles technologies avançant très vite, nous nous sommes vites rendu compte qu'il serait intéressant de les faire évoluer. Il fallait toutefois garder une compatibilité avec l'écosystème des thèmes actuels.

La version 2.7 intègre la notion de "tplset" (jeux de templates). Les fichiers de template par défaut seront réunis en jeux de templates, et un thème pourra définir sur quel jeu de templates il se base. Le jeu de templates de la 2.6 (qui sera celui sélectionné par défaut si le thème ne le spécifie pas) pourte le doux nom de "mustek". Un nouveau jeu de templates sera présent en 2.7 (il est en cours de développement) et portera le nom de "currywurst".

Pour indiquer le jeu de templates à utiliser, il faudra ajuster le fichier _define.php du thème en conséquence via la propriété "tplset":

<?php
// _define.php d'un thème
$this->registerModule(
	/* Name */		"MonThème",
	/* Description*/	"MonThèmeAMoi",
	/* Author */		"Moi",
	/* Version */		'1.0',
	/* Properties */	array(
					'tplset' => 'mustek',
					'type' => 'theme'
				)
);

L'héritage de templates

Dans sa version actuelle, dotclear a une approche procédurale des templates : pour une URL donnée côté publique, dotclear va chercher quel template afficher. Ce template est composé pour l'essentiel:

  • de balises de contenu (récupération de billets en base, affichage du titre du billet, des commentaires, ...)
  • de balises d'inclusion d'autres templates, via le tag {{tpl:include}}

Résultat : on a un grand nombre de fichiers de templates : défault.html, post.html, category.html, et pour les fichiers inclus : _top.html, _footer.html, ...

Or, si on regarde de plus près les templates qui affichent des listes, par exemple tag.html et category.html, il diffèrent extrêmement peu, et résultent de beaucoup de copier-coller. Effet collatéral : si je veux changer ne serait-ce qu'un iota dans le squelette du thème par défaut (par exemple : ajouter une classe au div id="wrapper"), je dois copier et modifier tous les fichiers du thème par défaut...

L'approche du système de templates de la 2.7 sera plus orienté objet, et embrasse l'approche DRY. Plutôt que de copier-coller le même fichier en plusieurs exemplaires (category, tag, home, ...) et de modifier chaque copie, on définit un patron commun à tous, dans lequel on définit quelles sont les sections personnalisables, et dans chacun des autres templates (category, tag, home), on indique hériter de ce patron de base, et on spécifie uniquement ce qui change.

Techniquement, côté template parent

Les blocs que l'on souhaite ouvrir à la personnalisation sont décrits à l'intérieur de la balise <tpl:Block name="nom"> ... </tpl:Block> Dans le template parent, cette balise se contente d'afficher son contenu, sans aucun traitement

Supposons que nous souhaitions définir un template servant de base au layout de toutes les pages, par exemple (au hasard) layout.html :

<!DOCTYPE html>
<html lang="{{tpl:BlogLanguage}}">
  <head>
    <tpl:Block name="html-header">
      <meta charset="UTF-8" />
      <meta name="ROBOTS" content="{{tpl:BlogMetaRobots}}" />
      <title><tpl:Block name="html-title">Page title</tpl:Block></title>
      {{tpl:include src="_head.html"}}
    </tpl:Block>
  </head>

  <body class="dc-home">
    <tpl:Block name="html-body">
      <div id="page">
        {{tpl:include src="_top.html"}}

        <div id="wrapper">
          <div id="main" role="main">
            <div id="content">
              <tpl:Block name="page-content">
                <p>Le contenu de la page va ici</p>
              </tpl:Block>
            </div>
          </div> <!-- End #main -->

          <div id="sidebar" role="complementary">
            <tpl:Block name="page-sidebar">
              <div id="blognav">
                {{tpl:Widgets type="nav"}}
              </div> <!-- End #blognav -->

              <div id="blogextra">
                {{tpl:Widgets type="extra"}}
              </div> <!-- End #blogextra -->
            </tpl:Block>
          </div>
        </div> <!-- End #wrapper -->
        <tpl:Block name="page-footer">
          {{tpl:include src="_footer.html"}}
        </tpl:Block>
      </div> <!-- End #page -->
    </tpl:Block>
  </body>
</html>

Nous sommes ici dans l'approche "patron global" de toutes les pages. Tout ce qui est écrit ici n'aura pas à être réécrit. Plusieurs blocs sont définis ici :

  • html-header : le header de la page, prérempli avec certaines informations
  • html-title : le titre de la page
  • html-body : le contenu (body) de la page
  • page-content : le contenu "utile" de la page
  • page-sidebar : la sidebar de la page
  • page-footer : le bas de page

Techniquement, côté enfant

Repartons de notre layout.html précédemment défini, et construisons un home.html (simpliste, c'est juste pour l'exemple) basé sur ce patron.

Dans un premier temps, il faut indiquer que l'on souhaite hériter de layout.html. Il suffit pour cela d'utiliser la nouvelle balise {{tpl:extends parent="layout.html"}}. A partir de ce moment, le template qui sera interprété sera layout.html, et non plus home.html. Autrement dit, tout ce que contient home.html sera ignoré, à l'exception des redéfinitions de block. En effet, c'est à ce moment qu'on peut spécialiser le contenu, toujours avec la balise <tpl:Block>.

Concrètement, voici ce à quoi le home.html peut ressembler :

{{tpl:extends parent="layout.html"}}

<tpl:Block name="html-title">Ceci est ma home</tpl:Block>

<tpl:Block name="page-content">
Ceci est le contenu de la page home
</tpl:Block>

Traduction :

  • On indique à dotclear de générer layout.html
  • On remplace le contenu du bloc "html-title" par un nouveau titre
  • On positionne un nouveau contenu de bloc "page-content"

On peut enrichir un contenu. Supposons que nous souhaitions, dans la home uniquement, ajouter un nouveau bloc de sidebar. Nous allons récupérer le contenu du bloc page-sidebar, et l'enrichir :

<tpl:Block name="page-sidebar">
  {{tpl:parent}}
  <div id="blogcustom">
  	{{tpl:Widgets type="custom"}}
  </div>
</tpl>

ici, {{tpl:parent}} va tout bêtement récupérer le contenu du bloc défini par le parent.

Auto-héritage

On peut aussi vouloir hériter d'un fichier déjà existant. Supposons par exemple qu'un thème repose sur un tplset définissant un home.html, et qu'on veuille remplacer seulement ce home.html dans notre thème. 2 solutions s'offrent à nous :

  • L'approche "copier-coller" : je duplique le home.html du tplset et j'y apporte les modifications souhaitées
  • Si le cas s'y prête : je définis mon home.html comme héritant du home.html du tplset.

Afin d'indiquer qu'on souhaite hériter du même fichier présent dans le parent (le parent étant soit le thème parent, soit le tplset utilisé), il suffit de faire référence au fichier parent "__parent__" .

Par exemple, si dans mon thème je souhaite ajouter une sidebar custom au fichier layout.html défini par un tplset, il me suffit de créer le fichier layout.html suivant dans mon thème :

<!-- layout.html de mon nouveau thème -->
{{{tpl:extends parent="__parent__"}}}
<tpl:Block name="page-content">
  {{tpl:parent}}
  <div id="blogcustom">
  	{{tpl:Widgets type="custom"}}
  </div>
</tpl>

En résumé

Ceux qui connaissent Twig ne seront pas bernés, les nouvelles règles implémentées en 2.7 permettent d'assurer un pas de plus vers Twig, en embrassant une partie de sa syntaxe.

Des travaux sont actuellements en cours pour définir un nouveau jeu de templates qui implémentera ces nouveaux mécanismes, stay tuned !