2.3 - Génération récursive

Attention : Ce tutoriel est ancien, incomplet, et n'est pas mis à jour. Il ne contient pas toutes les nouveautés du système de template de Gecko 1.9 / Firefox 3.0 qui est largement simplifié et permet d'utiliser sqlite ou xml comme source de données. Aussi est-il préférable d'aller consulter la version anglaise sur developer.mozilla.org.

Dans l'exemple précédent, le constructeur de gabarits générait une série de deux boutons supplémentaires sur la seconde ligne. Toutefois, les libellés de cette seconde série de boutons étaient différents de la première série. Si vous regardez de nouveau le graphe, vous commencerez à comprendre pourquoi. Dans le graphe, un arc 'relatedItem' relie l'item C à l'item D. Cet arc supplémentaire que B ou D n'ont pas, est la cause de la création de cette série supplémentaire de boutons.

Après avoir généré le contenu, le constructeur de gabarits continue de répéter la génération pour les niveaux intérieurs aussi loin que possible. Ainsi, le constructeur génère récursivement le contenu à partir du graphe. Après la création du contenu d'un résultat, le constructeur recommence en utilisant un nouveau parent et un nouveau point de départ. Naturellement, le parent sera un nouveau contenu plutôt qu'une inclusion dans un élément, et le point de départ sera le point d'arrivée de l'itération précédente. Dans cet exemple, le point d'insertion initial parent pour le niveau de génération le plus élevé est l'élément avec l'attribut datasources, un vbox. Pour les résultats imbriqués, le point d'insertion est l'élément généré. Voici ci-après, le contenu qui a été généré après une seule itération  :

<vbox datasources="http://www.xulplanet.com/ds/sample.rdf"
         ref="http://www.xulplanet.com/rdf/A">
  <template>
    <rule>
      <conditions>
        <content uri="?start"/>
        <triple subject="?start"
                predicate="http://www.xulplanet.com/rdf/relatedItem"
                object="?relateditem"/>
      </conditions>
      <action>
        <hbox uri="?relateditem">
          <button label="?start"/>
          <button label="?relateditem"/>
        </hbox>
      </action>
    </rule>
  </template>
  <hbox id="http://www.xulplanet.com/rdf/B">
    <button label="http://www.xulplanet.com/rdf/A"/>
    <button label="http://www.xulplanet.com/rdf/B"/>
  </hbox>
  <hbox id="http://www.xulplanet.com/rdf/C">
    <button label="http://www.xulplanet.com/rdf/A"/>
    <button label="http://www.xulplanet.com/rdf/C"/>
  </hbox>
  <hbox id="http://www.xulplanet.com/rdf/D">
    <button label="http://www.xulplanet.com/rdf/A"/>
    <button label="http://www.xulplanet.com/rdf/D"/>
  </hbox>
</vbox>

Pour l'itération suivante, le point d'insertion sera les trois éléments hbox. Toutefois, puisque C est le seul élément qui se termine en ayant encore du contenu supplémentaire, seul le second élément hbox se verra ajouté des fils.

Pour un item imbriqué, le constructeur traite les règles de la même manière que d'habitude, sauf qu'au lieu d'utiliser l'attribut ref comme graine de départ, il utilise le point d'arrivée ou le membre. Cela correspond à l'attribut id de l'élément approprié dans le contenu généré ci-avant. Pour commencer, B est évalué et rempli avec la valeur correcte :

(?start = http://www.xulplanet.com/rdf/B)

La condition triple est ensuite examinée, mais l'item B n'ayant pas d'arc relatedItem, le résultat est rejeté. Comme il n'y a pas de résultat potentiel, le constructeur ne génère aucun contenu. La même situation se produit avec D. Pour l'item C toutefois, le triplet trouve un item correspondant, donc les données sont ajoutées au résultat potentiel :

(?start = http://www.xulplanet.com/rdf/C, ?relateditem = http://www.xulplanet.com/rdf/D)
Capture d'écran

Une correspondance a été trouvée, donc le contenu à l'intérieur de la balise action sera créé et ajouté à l'intérieur de l'item C. Puisque la variable ?start pointe l'item C et que la variable ?relatedItem pointe D, les boutons seront créés avec ces libellés. Si vous regardez l'image de l'exemple, vous constaterez que les boutons ont ces libellés. Le contenu résultant pour la ligne C ressemblerait à ceci :

<hbox id="http://www.xulplanet.com/rdf/C">
  <button label="http://www.xulplanet.com/rdf/A"/>
  <button label="http://www.xulplanet.com/rdf/C"/>
  <hbox id="http://www.xulplanet.com/rdf/D">
    <button label="http://www.xulplanet.com/rdf/C"/>
    <button label="http://www.xulplanet.com/rdf/D"/>
  </hbox>
</hbox>

La nature récursive des gabarits permet de nombreuses applications utiles pour des menus et des arbres où des séries de contenu itératif peuvent être générées automatiquement. Nous verrons d'autres gabarits récursifs plus tard, mais la section suivante traitera d'un exemple plus pratique.


Mozilla® est une marque déposée de la fondation Mozilla.
Mozilla.org™, Firefox™, Thunderbird™, Mozilla Suite™ et XUL™ sont des marques de la fondation Mozilla.