4.1 - Interface du constructeur de gabarits

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.

Tout élément inséré dans un document XUL est vérifié pour voir s'il contient un attribut datasources. Si c'est le cas, un constructeur de gabarits sera créé pour cet élément et lui sera attaché. Si l'élément est un tree avec un attribut dont-build-content, un constructeur d'arbre sera créé. Autrement, c'est un constructeur de contenu qui sera créé. Ces deux types de constructeur partage sensiblement le même code sauf la méthode leur servant à l'affichage. Ils implémentent tous les deux l'interface nsIXULTemplateBuilder, mais le constructeur d'arbre implémente également l'interface nsIXULTreeBuilder.

Le constructeur associé à un élément est accessible via la propriété builder de l'élément aussi bien pour les constructeurs de contenu que pour les constructeurs d'arbre. Un élément qui n'est pas associé à un constructeur a cette propriété définie à null. Le processus de création de cette propriété builder pour un élément s'applique après que la fenêtre soit chargée lorsque un élément est créé, et lorsqu'un élément est inséré dynamiquement.

Les gabarits ne peuvent être utilisés que dans des documents XUL, toutefois rien n'oblige à ce qu'ils génèrent des éléments XUL. Ils pourraient également servir, par exemple, à générer des éléments HTML. Il ne s'agit cependant pas d'une pratique courante. Voici un exemple de cet usage :

<html:div id="photosList" datasources="template-guide-photos5.rdf"
          ref="http://www.xulplanet.com/rdf/myphotos"
          xmlns:html="http://www.w3.org/1999/xhtml">
  <html:h1>Mes Photos</html:h1>
  <template>
    <html:p uri="rdf:*"><textnode value="rdf:http://purl.org/dc/elements/1.1/title"/></html:p>
  </template>
</html:div>

Cet exemple génère trois paragraphes. Du contenu statique placé avant l'élément template affiche un en-tête <h1>. Puisque les gabarits ont été conçus pour la création de contenu XUL, des résultats inattendus peuvent se produire avec l'utilisation du HTML. Parfois, cela est dû à la gestion différente des espaces vides entre HTML et XUL, et qui explique pourquoi dans l'exemple ci-avant, le contenu généré se trouve sur une seule ligne. Si vous prévoyez de générer du contenu non-XUL avec un gabarit, pensez à ce problème.

Notez que les versions plus récentes de Mozilla ont corrigé ce problème particulier d'espaces vides.

Vous noterez que l'attribut datasources a été placé sur un élément non-XUL. Cela est également permis. Cependant, sachez que les éléments non-XUL n'auront pas leur contenu généré paresseusement et que par conséquence, tout le contenu sera généré immédiatement. Soyez prudent que la récursivité de vos gabarits ne soit pas trop profonde.

La propriété builder est une propriété de l'interface nsIDOMXULElement, donc tous les éléments XUL en disposeront, bien que comme mentionné juste avant, elle sera définie à null pour la plupart des éléments. Pour des éléments non-XUL, le constructeur de gabarits assignera une propriété builder à l'élément en utilisant une propriété JavaScript standard à la place.

Reconstruire et rafraîchir un gabarit

La raison principale d'accéder à la propriété builder d'un élément est de pouvoir appeler sa méthode "rebuild". Cette méthode supprime tout le contenu généré existant et efface toutes les données dans le réseau d'information des règles. Ensuite, la méthode recompile les règles et régénère le contenu. Plus précisément, la méthode rebuild informe le constructeur de supprimer toutes les informations existantes et de les reconstruire depuis le début. La seule différence est que les données sont les mêmes puisque la source de données est déjà chargée. Toutefois, cette méthode est souvent utilisée quand vous modifiez la source de données ou les règles.

La méthode refresh de la propriété builder va cependant recharger les sources de données. Il ne s'agit pas d'une reconstruction des gabarits, mais nous verrons dans une section ultérieure pourquoi ce n'est pas nécessaire. Pour résumer, la méthode refresh recharge les données tandis que la méthode rebuild reconstruit le contenu.

La propriété builder est accessible aux codes sans privilèges, donc les méthodes rebuild et refresh peuvent être appelées par du code distant.

Modification de la source de données

La source de données associée au gabarit peut être obtenue en utilisant la propriété database de l'élément. Elle implémente l'interface nsIRDFCompositeDataSource. Puisqu'il peut s'agir d'une source de données composite, elle peut contenir plus d'une source de données. Dans ce cas, ces sources seront listées dans l'attribut datasources et séparées par des espaces. Par exemple :

<vbox datasources="template-guide-photos5.rdf template-guide-streets.rdf">

Parfois, vous souhaitez calculer au préalable la source de données et l'attacher ensuite au gabarit. Vous pouvez réaliser cette opération en utilisant la méthode AddDataSource de la source de données composite. Vous pouvez ajouter autant de sources de données que vous le désirez, et vous pouvez en enlever grâce à la méthode RemoveDataSource. Une utilisation classique est la suivante :

var RDF = Components.classes["@mozilla.org/rdf/rdf-service;1"].
            getService(Components.interfaces.nsIRDFService);
var ds = RDF.GetDataSource("http://www.xulplanet.com/ndeakin/tests/xul/template-guide-streets.rdf");
var tree = document.getElementById("theTree");
tree.database.AddDataSource(ds);
tree.builder.rebuild();

Il s'agit d'une manière typique d'ajouter une source de données à un élément, dans ce cas l'arbre ayant un id theTree. La source de données est obtenue par la méthode GetDataSource du service RDF. Après l'ajout de la source de données, la méthode rebuild du constructeur d'arbre est invoquée pour reconstruire le gabarit avec les nouvelles données. Cette opération ne s'effectue pas automatiquement lorsque vous ajoutez la source de données, ce qui est utile si vous devez en ajouter ou enlever plusieurs à la fois.

L'accès à la source de données composite et sa manipulation nécessitent des privilèges, indépendamment de quelles sources elle contient. Heureusement dans cette situation, vous pouvez simplement définir l'attribut datasources (ou la propriété correspondante) avec les sources de données voulues. Par exemple :

var tree = document.getElementById("theTree");
tree.datasources = "template-guide-photos5.rdf template-guide-streets.rdf";

Ce code va également modifier les sources de données en cours d'utilisation. Dans ce cas, le gabarit va se reconstruire automatiquement car vous définissez d'un coup toutes les sources de données de cette manière. Vous n'avez donc pas à appeler la méthode rebuild. Vous pouvez procéder de la même façon avec l'attribut ref (ou la propriété ref) et le gabarit subira également une reconstruction automatique. Dans l'exemple ci-dessus, il y a deux sources de données attachées à l'arbre. Elles seront chargées toutes les deux et le gabarit sera reconstruit. Notez que si une des sources de données est déjà chargée, elle ne sera pas chargée de nouveau. C'est une manière pratique d'ajouter simplement une nouvelle source de données à un gabarit existant sans avoir à recharger les données existantes. Si vous souhaitez recharger les données, il vous suffit d'appeler la méthode refresh du constructeur :

tree.builder.refresh();

Ce code va recharger la source de données attachée au gabarit. S'il y a plus d'une source de données, comme dans l'exemple ci-dessus, elles seront toutes rechargées. À cause de la façon dont les gabarits sont mis à jour, vous n'avez normalement pas besoin de reconstruire un gabarit après l'appel de cette méthode refresh. Il existe toutefois des situations où cela est nécessaire.

Si vous prévoyez l'utilisation de sources de données dynamiques, il est fréquent de commencer avec une source de données vide grâce à l'URI spécial rdf:null.

<tree datasources="rdf:null" ref="http://www.xulplanet.com/rdf/myphotos">

Une source de données composite sera créée mais ne contiendra aucune source. Cette syntaxe est nécessaire car sinon vous ne pourrez pas définir une valeur pour l'attribut datasources et aucun constructeur de gabarit ne sera attaché à l'élément. Dans un contexte chrome, la source de données rdf:local-store est toujours inclue même si vous ne l'avez pas spécifié. Il faut en tenir compte si vous devez manipuler la source de données composite.

Un autre point : L'attribut datasources peut utiliser des URLs absolues ou relatives. Les URLs relatives le sont par rapport au document XUL contenant l'élément correspondant. La méthode GetDataSource du service RDF n'accepte toutefois que des URLs absolues. Vous devrez donc vous servir d'un chemin complet dans cette situation.


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.