Chapter 9. XUL Templates- P1
XUL templates are dynamically generated XUL elements and groups of
XUL elements. They are often used to render lists and tables that display
mutable, frequently updated data, such as your Inbox, your list of
bookmarks, and user profiles. A XUL template can be used to create
something as simple as a list of menu items, as you will see here, but it can
also be used in much more exciting ways, as shown at the end of this
chapter. You should consider using a XUL template instead of XUL when
you want to create an interface that displays data, such as a roster of names,
when the set of data is very large, when the data may change frequently, or
when you create a display that you want to use for different sets of data.
RDF, the format for data that goes into templates, is described in detail in
Chapter 10. The actual data used to build the template examples is displayed
in Examples Example 10-1 and Example 10-4. However, this chapter
precedes the RDF chapter because templates are much easier to understand
than RDF. Extending on the XUL programming done in Chapters Chapter 2
and Chapter 3, templates are a practical application of RDF data. They can
also help you understand the abstract concepts introduced in Chapter 10.
9.1. Understanding XUL Templates
By defining special rules and applying them to data stored in RDF files,
XUL templates build user interfaces dynamically. A XUL template consists
of a set of special tags inside a XUL element -- often ,
, or elements that match data in an RDF datasource. A
XUL template is defined in a regular XUL file and may appear anywhere
regular XUL content can be placed.

The template defines rules for filling out the parent elements with the
associated RDF data. Example 9-1 shows how to get a in XUL
to display RDF file contents. A template like this could display data stored
in a RDF file that, because it's so long, complex, or ephemeral, shouldn't be
hardcoded into XUL list elements. The data that comes from RDF and goes
into a template should be anything that doesn't directly relate to the user
interface.
Example 9-1. Simple XUL template in a listbox element

object="?types"/>
Because the template is built to match the RDF data, different parts of the
template in Example 9-1 correspond to parts of the RDF file used as the
datasource. Obviously, you need to know about the data's organization -- the
"graph" created by the data -- to build effective templates for it. However,
once you create the rules, you can apply them to very large sets of data,
which is one of the benefits of using templates in the interface.

As you can see in Example 9-1, rules typically comprise most of a template's
definition. The next several sections break down Example 9-1 to help you
understand the parts of a XUL template.
9.1.1. Basic template structure
Example 9-2 shows the template's basic structure. In this case, the data that
meets the conditions defined in the conditions element is rendered by
the XUL elements defined in the actions element, allowing the
translation of RDF data into XUL elements.
Example 9-2. Basic structure of a XUL template
...
...
In the first lines of the XUL template, a is defined within a
element, which is a simple container for templates in XUL:

XUL:
RDF:
The gains two special attributes when it contains a
. The datasources attribute specifies the RDF file's
location. The ref attribute is the starting point in that RDF-based data for
the template processing, which is equivalent to the about attribute of the
root node in the actual RDF file. The ref attribute tells the template where
to begin reading the data in the RDF file, and the about attribute in the
RDF data file specifies where its own beginning is. In this case, the RDF and
XUL starting point is the root of the data. Note that you do not need to
define a template at the base of an RDF data file: an RDF file may have
several avenues of information (e.g., different groups of bookmarks) and
your template may render only one group or some portion of all of the RDF
file data.
9.1.1.1. Template rule conditions
XUL:
RDF:

The and tags set up the template. The template's
rule element defines conditions that must be met for the template to render
the referenced data. A common condition in a template, for example, is that
an element be of a particular type or have an attribute set to a certain value.
The conditions in Example 9-2 render this content (10-1.rdf) if it defines
a types property and gives individual child elements as types.
Applying template rules to a datasource drives the dynamic creation of the
template-based UI. You can imagine a template going through data and
selecting only the bits of data that match, based on matching rules, and then
rendering that selected data into XUL (again based on rules defined in the
template itself).
Generated values from the RDF are stored in variables that can be used
throughout the template. They are represented by the values inside the
attributes beginning with a ?. When you create variables in a template once,
you can use them wherever you need them in the template. In Example 9-1,
the ?type variable is created as a child of types in the conditions block, is
used again, and is then used a third time in the action block to describe the
element that should be rendered in the template:
XUL:
RDF:

... about="urn:root" ...
... xmlns:fly="http://xfly.mozdev.org/fly-rdf#"
...
The tag signifies the root of the template rule. The uri
attribute value is automatically filled with urn:root from the listbox ref
attribute, which originates from the RDF about attribute on the first
resource. This value is now stored in the ?jar variable. Assigning variables
in a template for use elsewhere in the template is an essential part of
template-building in XUL, as it is in programming languages that work with
data.
A is a test on a subject and predicate. When triples match the
subject and predicate in the RDF, their object value is produced. In this case,
the container is the object result ?types, which holds individual ?type
nodes. Each one of these is drawn as a .
The element initiates a loop-like effect. When the template
builds, this effect exposes the container so it can read through all the objects
and add them to the template. In essence, ?type holds three different
values throughout the template generation: [1]
XUL:
RDF:

The is the most popular way to display this data because all of
its child elements fall neatly into place inside the template. However, you
can use any XUL element that supports the type of tabular display required
by the data (e.g., , , and ).
For the RDF content to be displayed, it needs a parent/children team to
define and fill in the values where needed. The parent, ?type, is used as a
point of reference three times during its lifetime by objects directly in the
container. The template generates ?name into the three literal children, as
shown in Table 9-1.
Table 9-1. Output of each template iteration
Iteration First child Second child Third child
?type rdf:#$LtOki1 rdf:#$MtOki1 rdf:#$NtOki1
?name "horse" "house" "fruit"
Directly inside the element is the first XUL element that gets
repeated, the . This element must have the uri attribute with
the container's object variable, which in Example 9-2 is ?type. This variable

establishes the root of the content -- a point of reference in the template for
any children below that point.
Once the container elements are matched to the , ?name can
be used in any attribute on any tag below it. In the previous example code,
the label shows the value of ?name. Interesting
implementations can result from the use of variables to hold values for
attributes like class, which is often used to define style rules for elements.
This implementation is demonstrated in the section Section 9.2.2, later in
this chapter
Example 9-3 shows what a generated template looks like as hardcoded XUL.
Example 9-3. Hardcoded representation of generated XUL

It's beneficial to see how this document is translated into a DOM tree using
Mozilla's DOM Inspector tool, with which the structure is presented in a
view that makes it easy to follow. Figure 9-1 shows how the template tree
nodes are generated into an actual tree. To use this tool, select "DOM
Inspector" from the Tools > Web Development menu in Mozilla. If you have
the template displayed in an open browser window, you can load it in the
DOM Inspector by selecting File > Inspect a Window and choosing it from
the list.
Figure 9-1. DOM representation of XUL template generation

In Figure 9-1, you can see how the was generated three times
from the template. Interestingly, the generated code doesn't replace the
original template, but is appended to the as another tree row.
Finally, Figure 9-2 shows what the actual XUL file looks like when loaded.
If you save the template in Example 9-1 to a file called 9-1.xul, save the
RDF data in Example 10-1 to a file called 10-1.rdf (which the template looks

for by name in the same directory), and then load the template into the
browser, you ought to see something very similar.
Figure 9-2. View of XUL tree in Mozilla
Notes
[1] An rdf:Bag is a type of RDF container, but when you use the
tag, you do not have to specify whether the container is of
the type Alt, Bag, or Sequence (see "nsIRDFContainer" in Chapter 10
for more details on working with containers in RDF). A template can
only build the values sequentially out of a container, no matter what type
it is. Thus, using an rdf:Seq or rdf:Alt element produces the same
visual output in these Mozilla templates.
9.2. Enhancing XUL Templates
Creating simple XUL templates can help familiarize you with the flexibility
and complex design issues of a template. The RDF file created in Example
9-4 introduces the concept of nested content. A can generate
nested content from multiple containers in the RDF datasource. These

multiple containers must have the same basic design to work properly, so the
design must be abstracted to apply to all datasources. Example 9-5 uses the
design to accomplish this task.
The advantage of having nested content in XUL templates is that you can
organize items visually, even when those things come from different
sources. Nested content allows you to form subtrees and submenus rather
than long monolithic lists.
9.2.1. Nested Content Sample
The window in Figure 9-3 represents a template with nested data and styled
elements. Note that the top of the content area has a standard
and a color-styled is on the bottom. The next several sections
describe the creation of the XUL file in Figure 9-3.
Figure 9-3. Listbox and tree template

In this example, both the and the use the same data,
but different template formats. Only two columns appear in the
, for example, and the rows were created to display the color of
the data's color attribute. You could as easily have styled the this
way and left the as a regular list. To display large amounts of
raw data, however, is usually the best option because it's faster
with big datasets, offers built-in sorting, and looks cleaner.
The template can make the XUL seem more complicated than
the content would seem to require in Figure 9-3, but a template's basic
design can be similar for all types of data, which allows you to write once
and apply templates to different datasets. In this case, you gain more
efficiency because the RDF contributes more to the template generation than
does the XUL, making template-based applications data-driven.

Example 9-4 contains the XUL for producing the tree shown in Figure 9-3.
The difference between the code in Examples Example 9-2 and Example 9-9
is minimal, but the latter produces a much more impressive visual result.
Remember that a XUL template and RDF produce the content you see when
loading these listbox examples. No stylesheets or other enhancements are
needed.
Example 9-4. XUL tree template in Figure 9-3

object="?label"/>

The biggest difference between Example 9-4 and earlier examples is the
section. All matching in a binding element is optional, unlike
the condition content. The elements in the bindings are simply optional
triples. Placing these triples in a binding affords you some flexibility when
data is missing from the RDF file or when you are not certain about its
contents -- such as when you create a roster but don't have all the people's
addresses.
The containment attribute on the tree specifies the URI of all the
containers. In this case, the container is the tag in the RDF.
To see how such a complex-looking can be generated from so
little XUL, look at how the containers are set up in the RDF. The RDF file
appears (in a reformatted and somewhat simplified form) in Example 9-5.
This simplified form can help you see the structure underlying the data and
how it is reused to order the data efficiently.
Example 9-5. Simplified version of 10-4 RDF data

House
The RDF data in Example 9-5 demonstrates a two-level pattern of recursion:
fly:list/fly:label are both reused at different levels in the RDF
data. The template in Example 9-4 generates the data into a tree showing
two levels, as shown in Figure 9-3.
Example 9-5 clearly shows that only fly:list and fly:label are
needed to generate the template. The other data, such as color, are not

mandatory because they are defined in a rather than a
.
9.2.2. Using Data for Style
RDF data are used for more than containers and labels. It's possible to use
RDF to define CSS classes, XUL attributes, and other arbitrary bits of XUL
content. In Example 9-4, the has a class attribute that is
filled by ?color:
If a stylesheet has class definitions for the same values located in the RDF,
then every generated row can have its own style. Here is a simple class
showing style rules defined for items of the "green" class.
.green
{
background-color: green;
}
As shown in the earlier examples of this chapter, using with
templates generally yields flexible and simpler implementations. Trees,
covered next, are not as flexible, but they can be better for raw data display,
as when you have spreadsheet-like information, many columns, or other data
that can be sorted.