When inserting an element into a XUL document, the element is checked to see if it has a datasources attribute. If so, a template builder will be created for the element and attached to the element. If the element is a <tree> element and has the flags attribute set to "dont-build-content", a tree builder will be created. Otherwise, a content builder will be created. Both types of builder share much of the same code except for how they generate output to be displayed. Both types of builders implement the nsIXULTemplateBuilder interface, while the tree builder also implements the nsIXULTreeBuilder interface.
The builder associated with an element is accessible via the element's "builder" property both for content builders and for tree builders. An element that does not have a builder will have this property set to null. The processes of creating a builder for an element applies both when an element is created when the window is loaded and when an element is inserted dynamically.
Templates can only be used in XUL documents, however, there is no requirement that the templates generate XUL elements. They could also be used, for example, to generate HTML elements. This isn't a very common technique, however, here is an example of how this can be used:
<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>My Photos</html:h1> <template> <html:p uri="rdf:*"><textnode value="rdf:http://purl.org/dc/elements/1.1/title"/></html:p> </template> </html:div>
This example generates three paragraphs. Some static content before the <template> element displays a <h1> header. Since templates were designed for creating XUL content, sometimes there can be unusual results when using HTML. Sometimes this is due to different whitespace handling for HTML and XUL, which is why the content to generate in the above example is all on one line. If you do plan on generating non-XUL content with a template, just watch out for issues like this. Note that this particular whitespace issue has been fixed in later Mozilla builds.
Note also that the datasources attribute has been placed on a non-HTML element. This is also allowed. However, one thing to watch out for is that non-XUL elements do not have their content generated lazily so all of the content will be generated at once. Be careful that your templates do not recurse to deep levels.
The main purpose of accessing the builder for an element is to call its "rebuild" method. This method removes any existing generated content and deletes all data in the rule network. Then, the method recompiles the rules and regenerates the content. Essentially, the rebuild method instructs the builder to remove any existing information and reconstruct it from the beginning. The only difference is that the datasource has already loaded so the data will be the same. However, this is often used if you modify the datasource or modify the rules.
The builder's refresh method, however, will reload the datasources. It will not rebuild the template, but we'll see in a later section why this is not usually necessary. To summarize, the refresh method reloads the data, whereas the rebuild method reconstructs the content.
The builder is accessible to unprivileged code, so the rebuild and refresh methods may be called by remote code.
We'll see some examples of rebuilding templates next.