Warning: The content of this article may be out of date. See XUL:Template Guide for up to date documentation.
This document expands on the [template-primer.html XUL Template Primer] by introducing the
<bindings> element in the extended XUL template syntax.
<bindings> element is used to create additional, optional variable bindings, in addition to those that are specified in a rule's
<conditions>. This is different from the variables specified in the rule's conditions, where a value must be found for each variable for the rule to match. If a
<binding> can't be matched, the rule will still fire.
To illustrate how
<bindings> work, we'll examine this [/sample.xul XUL document], which builds a simple content model an RDF/XML file.
<?xml version="1.0"?> <?xml-stylesheet href="chrome://global/skin" type="text/css"?> <window xmlns:html="http://www.w3.org/1999/xhtml" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" align="vertical"> <vbox datasources="friends.rdf" ref="urn:root"> <template> <rule> <conditions> <content uri="?uri" /> <triple subject="?uri" predicate="http://home.netscape.com/NC-rdf#friends" object="?friends" /> <member container="?friends" child="?friend" /> <triple subject="?friend" predicate="http://home.netscape.com/NC-rdf#name" object="?name" /> </conditions> <bindings> <binding subject="?friend" predicate="http://home.netscape.com/NC-rdf#address" object="?addr" /> <binding subject="?addr" predicate="http://home.netscape.com/NC-rdf#street" object="?street" /> </bindings> <action> <hbox uri="?friend"> <label value="?name" /> <label value="?street" /> </hbox> </action> </rule> </template> </vbox> </window>
The XUL Template Primer covers the
<action> elements, so we won't discuss those here.
We'll use a the following data model to illustrate how bindings work. See the RDF/XML file
friends.rdf, below, a simple database with name and address information for some of my good friends.
<?xml version="1.0"?> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:nc="http://home.netscape.com/NC-rdf#"> <rdf:Description about="urn:root"> <nc:friends> <rdf:Seq> <rdf:li> <rdf:Description nc:name="Alison Appel"> <nc:address resource="#home" /> </rdf:Description> </rdf:li> <rdf:li> <rdf:Description nc:name="Jack"> <nc:address resource="#doghouse" /> </rdf:Description> </rdf:li> <rdf:li> <rdf:Description nc:name="Lumpy" /> </rdf:li> </rdf:Seq> </nc:friends> </rdf:Description> <rdf:Description ID="home" nc:street="437 Hoffman" /> <rdf:Description ID="doghouse" nc:street="435 Hoffman" /> </rdf:RDF>
The RDF model that this file creates can be represented with the following graph.
When displayed in Mozilla, something like this appears:
Note that even though poor Lumpy has no
nc:address property, he still appears in the content model! Unlike the
<conditions>, bindings do not affect whether or not a rule matches: they just "pull through" additional information if it is available.
The <bindings> element
<bindings> element is optional in a XUL template, but if present, must appear as a sibling of the
<action> elements in a rule.
The <binding> element
<bindings> element (plural) may contain any number of
<binding> (singular) elements.
<bindings> <binding subject="?friend" predicate="http://home.netscape.com/NC-rdf#address" object="?addr" /> <binding subject="?addr" predicate="http://home.netscape.com/NC-rdf#street" object="?street" /> </bindings>
The <tt><binding></tt> element is very much like the
<triple> [template-primer.html#conditions condition]: it must have a <tt>subject</tt>, <tt>predicate</tt>, and <tt>object</tt> attribute. These refer to the subject, predicate, and object of a statement in the RDF model.
At least one of the
<binding> elements must have a
subject variable that appears in the
<conditions>: this variable is the "hook" that is used to bootstrap the binding. In our example, the
?friend variable serves this purpose in the first
The subject may refer to any variable that has been computed in the
<conditions>, or it may refer to another
object variable. [#1 1] In our example, the second
subject does this: the value for the
?addr variable is computed by the first
predicate must name the URI of an RDF property, in this case,
object must name a variable. The value of the
object's variable will be computed by invoking the
GetTarget() method using the
object's value as the
aSource argument, and the
predicate's resource as the
aProperty argument. (See the
nsIRDFDataSource interface for more details.)
In our example, the
<rule> will be instantiated three times: once each for Alison, Jack, and Lumpy. However, in Lumpy's case, we won't be able to bind the
?addr variable because Lumpy has no home! (Well, there are no statements with Lumpy as the subject and a
nc:address as the predicate, anyway.) Nevertheless, the rule still matches.
In the content that's built for Lumpy's
<hbox>, the second
value attribute (which should contain the value of
?street) is just left blank.
- XUL Template Primer
- XUL template basics.
- XUL Template Primer - Multiple Rules
- Illustrates how to write templates with multiple
- XUL Template Primer - Nested Content
- Illustrates how a template can be used recursively to build nested content.
- XUL Template Primer - Outliner
- Illustrates how a template can be used as a view for a XUL outliner.
- XUL Template Reference
- Describes the simple XUL template syntax in detail.
1As of this writing, it is necessary to order
<binding> elements carefully. Specifically, if a binding depends on a variable in another binding, it must appear after the binding it depends on. For example, the sample in this document wouldn't work if the two
<binding> elements were reversed, because of the dependency on the
?addr variable. Fortunately, this is the natural way one would write bindings, so in practice this should not be a burden.
Original Document Information
- Author: Chris Waterson