Introduction

A XUL template is a means of producing a block of content for each result from some query or query-like operation. A good analogy is to the results of a database query. For each result returned from the query, generate some content. The template syntax allows for different rules to generate different content based on particular criteria as well as set attribute values from returned results. Some other systems call this databinding. Effectively, XUL templates are the XUL way of doing databinding.

Each template retrieves its data from a datasource. Several types of datasources are supported by default, RDF, XML and SQLite databases, however, processors may be written to support other types of datasources. In XUL, the datasource is specified by placing the datasources attribute on an element. Typically, the value will be a URI that identifies the location of the data. For example, for an XML datasource, the URL of an XML file is specified. When the XUL parser sees an element with this attribute, it constructs a template builder for the element and attaches it to the element. It is expected that there will be a template inside the element. The template builder loads the datasource, performs a query on the datasource and generates content based on the results in combination with the template. The type of datasource is specified with the querytype attribute. The type affects how the datasource is used as well as the syntax for specifying queries.

Content generated by the template is inserted into the XUL just as if you had placed it there yourself. Here is an example:

<vbox datasources="http://www.xulplanet.com/ds/sample.rdf" querytype="rdf">

This example specifies the datasource 'http://www.xulplanet.com/ds/sample.rdf', using the datasource type rdf as indicated by the querytype attribute'.

We'll look at RDF datasources first. The template builder loads an RDF datasource using the RDF service in the same way as you would create a datasource through the RDF service directly. The datasource is loaded via its URL. Some RDF datasources are provided with Mozilla -- their URL's start with 'rdf:'. Otherwise, the datasource is loaded as any other URL is loaded. If the datasource is already loaded and cached, the template builder can begin work right away. Otherwise, there isn't anything to do until the data is loaded. Actually, this isn't quite true. The RDF service starts the loading of the datasource in the background, and the template builder goes through the process of building content anyway. Naturally, since there is no data yet, no results will be available, so the builder ends up building nothing.

Once some data starts arriving, the template builder scans its information to see if some results can be created. If so, some content can be generated. If not, nothing gets generated again. An interesting thing to note is that due to the nature of the RDF parsing process, the builder generates results and builds content incrementally while the data arrives. Of course, since the data arrives so quickly from the network, you really don't notice this. If the datasource is already loaded, the builder can construct content all in one step, although even this isn't completely true as we'll see later.

For XML datasources, use a querytype of xml. The datasources attribute should be the URL of an XML file, which can be either the location of a web site or a file on the local file system, using its file or chrome URL. This file will be loaded and the resulting XML document will be used as the datasource when the template builder generates results and creates content. For example:

<listbox datasources="http://www.xulplanet.com/ds/sample.xml" querytype="xml">
  <template>
    <listitem label="?name"/>
  </template>
</listbox>

This template uses an XML datasource to generate a listbox. Although we'll look at the details of this later, the simple result here is that a listitem will be generated for each child node in the XML data, setting the label to the name attribute for each XML node.

For SQLite datasources, the datasources attribute specifies the URI of a database file. Only local files are supported, so a file URL should be used.

If the datasource type supports it, the template builder can also use multiple datasources which are all combined into a single datasource as if they were all in one datasource to begin with. Only the built-in RDF type supports this mechanism; the XML and SQLite types do not. When multiple datasources are used, an nsIRDFCompositeDataSource is created to hold all of the datasources. You can get this composite datasource in a script by using an element's 'database' property if you want to add or remove datasources from it.

When multiple datasources are used, the RDF is combined as if it were one large datasource. That means that a template query can grab data from anywhere in all of the datasources. This combining of datasources is often termed 'aggregation'. This can be quite a useful feature and works regardless of the datasource. For instance, you might use the built-in bookmarks datasource which holds the user's browser bookmarks and use your own datasource to add custom data about those bookmarks.

<vbox datasources="rdf:bookmarks http://www.xulplanet.com/ds/sample.rdf">

In addition, when using the RDF type for chrome XUL (such as in extensions), the datasource rdf:local-store is always included in the composite. The local store is a datasource which is usually used to hold state information such as window sizes, which columns in a tree are showing, and which tree items are open. You can query for any data in the local store in a template though this is rarely done.

Sometimes, you will want to specify the datasource to be used later, possibly determined dynamically by a script. The special URI rdf:null is used to indicate that you intend no datasources, or an empty datasource. This special URI will also work even for non-RDF types, so feel free to use it when needed. It effectively means, use no datasource for this template, which will likely result in no output being generated.