File:  [mozdev] / books / www / chapters / ch09.html
Revision 1.16: download - view: text, annotated - select for diffs - revision graph
Fri Apr 4 16:27:40 2003 UTC (16 years, 8 months ago) by cdn
Branches: MAIN
CVS tags: HEAD
ahem

    1:     <link rel="prev" href="http://books.mozdev.org/chapters/ch08.html" />
    2:     <link rel="next" href="http://books.mozdev.org/chapters/ch10.html" />
    3: 
    4:     <style type="text/css">
    5:       div.c20 {text-align: center}
    6:     </style>
    7: 
    8:     <h2>Chapter 9</h2>
    9:     <h1><a name="77034"></a> XUL Templates</h1>
   10:     <p>XUL templates are dynamically <!--INDEX XUL templates --> 
   11:     <!--INDEX templates:XUL templates --> generated XUL elements
   12:     and groups of XUL elements. They are often used to render lists
   13:     and tables that display mutable, frequently updated data, such
   14:     as your Inbox, your list of bookmarks, and user profiles. A XUL
   15:     template can be used to create something as simple as a list of
   16:     menu items, as you will see here, but it can also be used in
   17:     much more exciting ways, as shown at the end of this chapter.
   18:     You should consider using a XUL template instead of XUL when
   19:     you want to create an interface that displays data, such as a
   20:     roster of names, when the set of data is very large, when the
   21:     data may change frequently, or when you create a display that
   22:     you want to use for different sets of data.</p>
   23:     <p>RDF, the format for data that goes into templates, is
   24:     described in detail in <a href="ch10.html#36341">Chapter
   25:     10</a>. The actual data used to build the template examples is
   26:     displayed in Examples <a href="ch10.html#77026">10-1</a> and <a
   27:     href="ch10.html#77032">10-4</a>. However, this chapter precedes
   28:     the RDF chapter because templates are much easier to understand
   29:     than RDF. Extending on the XUL programming done in Chapters <a
   30:     href="ch02.html#68959">2</a> and <a href=
   31:     "ch03.html#32764">3</a>, templates are a practical application
   32:     of RDF data. They can also help you understand the abstract
   33:     concepts introduced in <a href="ch10.html#77061">Chapter
   34:     10</a>.</p>
   35:     <h2><a name="77035"></a> Understanding XUL Templates</h2>
   36:     <p>By defining special rules and applying them 
   37:     <!--INDEX XUL templates:overview --> to data stored in RDF
   38:     files, XUL templates build user interfaces dynamically. A XUL
   39:     template consists of a set of special tags inside a XUL
   40:     element-often <tt>&lt;listbox&gt;</tt>, <tt>&lt;menu&gt;</tt>,
   41:     or <tt>&lt;tree&gt;</tt> elements that match data in an RDF
   42:     datasource. A XUL template is defined in a regular XUL file and
   43:     may appear anywhere regular XUL content can be placed.</p>
   44:     <p>The template defines rules for filling out the parent
   45:     elements with the associated RDF data. <a href="#77016">Example
   46:     9-1</a> shows how to get a <tt>&lt;listbox&gt;</tt> in XUL to
   47:     display RDF file contents. A template like this could display
   48:     data stored in a RDF file that, because it's so long, complex,
   49:     or ephemeral, shouldn't be hardcoded into XUL list elements.
   50:     The data that comes from RDF and goes into a template should be
   51:     anything that doesn't directly relate to the user
   52:     interface.</p>
   53:     <p><i>Example 9-1: <a name="77016"></a></i> <i>Simple XUL
   54:     template in a listbox element</i></p>
   55: <pre>
   56:  &lt;?xml version="1.0"?&gt;
   57:  &lt;?xml-stylesheet href="chrome://global/skin" type="text/css"?&gt;
   58:  &lt;window
   59:    xmlns="<a href=
   60: "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul</a>"&gt;
   61:    &lt;listbox datasources="10-1.rdf" ref="http://my.jar-of-flies.com" flex="1"&gt;
   62:      &lt;template&gt;
   63:        &lt;rule&gt;
   64:          &lt;conditions&gt;
   65:            &lt;content uri="?jar"/&gt;
   66:            &lt;triple subject="?jar"
   67:                    predicate="<a href=
   68: "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#types"
   69:                    object="?types"/&gt;
   70:            &lt;member container="?types" child="?type"/&gt;
   71:            &lt;triple subject="?type"
   72:                    predicate="<a href=
   73: "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#name"
   74:                    object="?name"/&gt;
   75:          &lt;/conditions&gt;
   76:          &lt;action&gt;
   77:            &lt;listitem uri="?type"&gt;
   78:              &lt;listcell label="?name"/&gt;
   79:            &lt;/listitem&gt;
   80:          &lt;/action&gt;
   81:        &lt;/rule&gt;
   82:      &lt;/template&gt;
   83:    &lt;/listbox&gt;
   84:  &lt;/window&gt;
   85: </pre>
   86: <p>Because the template is built to match the RDF data,
   87:     different parts of the template in <a href="#77016">Example
   88:     9-1</a> correspond to parts of the RDF file used as the
   89:     datasource. Obviously, you need to know about the data's
   90:     organization-the "graph" created by the data-to build effective
   91:     templates for it. However, once you create the rules, you can
   92:     apply them to very large sets of data, which is one of the
   93:     benefits of using templates in the interface.</p>
   94:     <p>As you can see in <a href="#77016">Example 9-1</a>, rules
   95:     typically comprise most of a template's definition. The next
   96:     several sections break down <a href="#77016">Example 9-1</a> to
   97:     help you understand the parts of a XUL template.</p>
   98:     <h4><a name="77036"></a> <a name="77037"></a> Basic template
   99:     structure</h4>
  100:     <p><a href="#77018">Example 9-2</a> shows the template's 
  101:     <!--INDEX XUL templates:structure --> basic structure. In this
  102:     case, the data that meets the conditions defined in the
  103:     <tt>conditions</tt> element is rendered by the XUL elements
  104:     defined in the <tt>actions</tt> element, allowing the
  105:     translation of RDF data into XUL elements.</p>
  106:     <p><i>Example 9-2: <a name="77018"></a></i> <i>Basic structure
  107:     of a XUL template</i></p>
  108: <pre>
  109:  &lt;listbox datasources="10-1.rdf" ref="urn:root"&gt;
  110:    &lt;template&gt;
  111:      &lt;rule&gt;
  112:        &lt;conditions&gt;
  113:           ...
  114:        &lt;/conditions&gt;
  115:        &lt;action&gt;
  116:           ...
  117:        &lt;/action&gt;
  118:      &lt;/rule&gt;
  119:    &lt;/template&gt;
  120:  &lt;/listbox&gt;
  121: </pre>
  122:     <p>In the first lines of the XUL template, a <tt>
  123:     <!--INDEX template element, XUL --> 
  124:     <!--INDEX XUL templates:template element -->
  125:     &lt;template&gt;</tt> is defined within a
  126:     <tt>&lt;listbox&gt;</tt> element, which is a simple container
  127:     for templates in XUL:</p>
  128: <pre>
  129: XUL:
  130: &lt;listbox datasources="10-1.rdf" ref="urn:root" flex="1"&gt;
  131: RDF:
  132: &lt;rdf:Description about="urn:root"&gt;
  133: </pre>
  134: <p>The &lt;listbox&gt; gains two special attributes when it contains a &lt;template&gt;. 
  135:   The <tt>datasources</tt> attribute specifies the RDF file's location. The <tt>ref</tt> 
  136:   attribute is the starting point in that RDF-based data for the template processing, 
  137:   which is equivalent to the <tt>about</tt> attribute of the root node in the 
  138:   actual RDF file. The <tt>ref</tt> attribute tells the template where to begin 
  139:   reading the data in the RDF file, and the <tt>about</tt> attribute in the RDF 
  140:   data file specifies where its own beginning is. In this case, the RDF and XUL 
  141:   starting point is the root of the data. Note that you do not need to define 
  142:   a template at the base of an RDF data file: an RDF file may have several avenues 
  143:   of information (e.g., different groups of bookmarks) and your template may render 
  144:   only one group or some portion of all of the RDF file data.</p>
  145:     <h4><a name="77038"></a> Template rule conditions</h4>
  146: <pre>
  147: XUL:
  148: &lt;template&gt;
  149: &lt;rule&gt;
  150: &lt;conditions&gt;
  151: RDF:
  152: &lt;!-- no equivalent --&gt;
  153: </pre>
  154:     <p>The <tt>&lt;template&gt;</tt> and <tt>&lt;rule&gt;</tt> tags
  155:     set up <!--INDEX XUL templates:rules;rules, XUL templates --> 
  156:     <!--INDEX rule element, XUL --> the template. The template's
  157:     rule element defines conditions that must be met for the
  158:     template to render the referenced data. A common condition in a
  159:     template, for example, is that an element be of a particular
  160:     type or have an attribute set to a certain value. The
  161:     conditions in <a href="#77018">Example 9-2</a> render this
  162:     content (<i>10-1.rdf</i>) if it defines a <tt>types</tt>
  163:     property and gives individual child elements as types.</p>
  164:     <p>Applying template rules to a datasource drives the dynamic
  165:     creation of the template-based UI. You can imagine a template
  166:     going through data and selecting only the bits of data that
  167:     match, based on matching rules, and then rendering that
  168:     selected data into XUL (again based on rules defined in the
  169:     template itself).</p>
  170:     <p>Generated values from the RDF are stored in variables that
  171:     can be used throughout the template. They are represented by
  172:     the values inside the attributes beginning with a <tt>?</tt>.
  173:     When you create variables in a template 
  174:     <!--INDEX XUL templates:variables --> 
  175:     <!--INDEX variables, XUL templates --> once, you can use them
  176:     wherever you need them in the template. In <a href=
  177:     "#77016">Example 9-1</a>, the <i>?type</i> variable is created
  178:     as a child of <tt>types</tt> in the conditions block, is used
  179:     again, and is then used a third time in the action block to
  180:     describe the element that should be rendered in the
  181:     template:</p>
  182: <pre>
  183: XUL:
  184: &lt;content uri="?jar"/&gt;
  185: &lt;triple subject="?jar"
  186: predicate="<a href=
  187: "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#types"
  188: object="?types"/&gt;
  189: RDF:
  190: ... about="urn:root" ...
  191: ... xmlns:fly="<a href=
  192: "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#" ...
  193: &lt;/fly:types&gt;
  194: </pre>
  195:     <p>The <tt>&lt;content&gt;</tt> tag signifies the root of the
  196:     template rule. The <tt>uri</tt> attribute value is
  197:     automatically filled with <tt>urn:root</tt> from the listbox
  198:     <tt>ref</tt> attribute, which originates from the RDF
  199:     <tt>about</tt> attribute on the first resource. This value is
  200:     now stored in the <i>?jar</i> variable. Assigning variables in
  201:     a template for use elsewhere in the template is an essential
  202:     part of template-building in XUL, as it is in programming
  203:     languages that work with data.</p>
  204:     <p>A <tt><!--INDEX triple element, XUL --> &lt;triple&gt;</tt>
  205:     is a test on a subject and predicate. When triples match the
  206:     subject and predicate in the RDF, their object value is
  207:     produced. In this case, the container is the object result
  208:     <tt>?types</tt>, which holds individual <tt>?type</tt> nodes.
  209:     Each one of these is drawn as a <tt>&lt;listitem&gt;</tt>.</p>
  210:     <p>The <tt><!--INDEX member element, XUL -->
  211:     &lt;member&gt;</tt> element initiates a loop-like effect. When
  212:     the template builds, this effect exposes the container so it
  213:     can read through all the objects and add them to the template.
  214:     In essence, <tt>?type</tt> holds three different values
  215:     throughout the template generation: <a name="b241"></a><a href=
  216:     "#241">[*]</a></p>
  217: <pre>
  218: XUL:
  219: &lt;member container="?types" child="?type"/&gt;
  220: RDF:
  221: &lt;fly:types&gt;
  222: &lt;rdf:Bag&gt;
  223: &lt;rdf:li&gt;
  224: &lt;rdf:Description ...
  225: </pre>
  226:     <p>To finish the template conditions, one more
  227:     <tt>&lt;triple&gt;</tt> correlates with the literal's
  228:     value.</p>
  229: <pre>
  230: XUL:
  231: &lt;triple subject="?type"
  232: predicate="<a href=
  233: "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#name"
  234: object="?name"/&gt;
  235: RDF:
  236: ... xmlns:fly="<a href=
  237: "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#" ...
  238: &lt;rdf:li&gt;
  239: &lt;rdf:Description fly:name="Horse"/&gt;
  240: </pre>
  241:     <p>Like <tt>?type</tt>, <tt>?name</tt> holds three different
  242:     values during its lifetime, and "Horse" will be the first value
  243:     generated from the RDF.</p>
  244:     <p>The <tt><!--INDEX conditions element, XUL -->
  245:     &lt;conditions&gt;</tt> part of the template extracts the data
  246:     from the RDF graph, as in our graphical examples. It makes the
  247:     data available in variable-like objects; those objects can be
  248:     used in the template's <tt>&lt;action&gt;</tt>, demonstrated in
  249:     the next section.</p>
  250:     <h4><a name="77039"></a> Template rule actions</h4>
  251:     <p>XUL elements <!--INDEX rules, XUL templates:actions --> 
  252:     <!--INDEX XUL templates:rules:actions --> 
  253:     <!--INDEX actions, XUL template rules --> that are used to
  254:     build content from data matched by the template conditions are
  255:     placed in the <tt>&lt;action&gt;</tt> element in a template
  256:     rule. The <tt>&lt;listbox&gt;</tt> is the most popular way to
  257:     display this data because all of its child elements fall neatly
  258:     into place inside the template. However, you can use any XUL
  259:     element that supports the type of tabular display required by
  260:     the data (e.g., <tt>&lt;tree&gt;</tt>,
  261:     <tt>&lt;groupbox&gt;</tt>, and <tt>&lt;menu&gt;</tt>).</p>
  262: <pre>
  263: &lt;action&gt;
  264: &lt;listitem uri="?type"&gt;
  265: &lt;listcell label="?name"/&gt;
  266: &lt;/listitem&gt;
  267: &lt;/action&gt;
  268: </pre>
  269:     <p>For the RDF content to be displayed, it needs a
  270:     parent/children team to define and fill in the values where
  271:     needed. The parent, <tt>?type</tt>, is used as a point of
  272:     reference three times during its lifetime by objects directly
  273:     in the container. The template generates <tt>?name</tt> into
  274:     the three literal children, as shown in <a href="#77012">Table
  275:     9-1</a>.</p>
  276:     <p><i>Table 9-1: <a name="77012"></a></i> <i>Output of each
  277:     template iteration</i></p>
  278:     <table width="100%" border="1">
  279:       <tr>
  280:         <td><b>Iteration</b></td>
  281:         <td><b>First child</b></td>
  282:         <td><b>Second child</b></td>
  283:         <td><b>Third child</b></td>
  284:       </tr>
  285:       <tr>
  286:         <td>?type</td>
  287:         <td>rdf:#$LtOki1</td>
  288:         <td>rdf:#$MtOki1</td>
  289:         <td>rdf:#$NtOki1</td>
  290:       </tr>
  291:       <tr>
  292:         <td>?name</td>
  293:         <td>"horse"</td>
  294:         <td>"house"</td>
  295:         <td>"fruit"</td>
  296:       </tr>
  297:     </table>
  298:     <p>Directly inside the <!--INDEX action element, XUL -->
  299:     &lt;<tt>action&gt;</tt> element is the first XUL element that
  300:     gets repeated, the <tt>&lt;listitem&gt;</tt>. This element must
  301:     have the <tt>uri</tt> attribute with the container's object
  302:     variable, which in <a href="#77018">Example 9-2</a> is
  303:     <i>?type</i>. This variable establishes the root of the
  304:     content-a point of reference in the template for any children
  305:     below that point.</p>
  306:     
  307: <p>Once the container elements are matched to the <tt>&lt;listitem&gt;</tt>, <tt>?name</tt> 
  308:   can be used in any attribute on any tag below it. In the previous example code, 
  309:   the <tt>&lt;listcell&gt; label</tt> shows the value of <tt>?name</tt>. Interesting 
  310:   implementations can result from the use of variables to hold values for attributes 
  311:   like <tt>class</tt>, which is often used to define style rules for elements. 
  312:   This implementation 
  313:   <!--INDEX XUL templates:hardcoded -->
  314:   <!--INDEX templates:generated, hardcoded XUL -->
  315:   is demonstrated in the section "<a href="#77042">Using Data for Style</a>", 
  316:   later in this chapter</p>
  317:     <p><a href="#77020">Example 9-3</a> shows what a generated
  318:     template looks like as hardcoded XUL.</p>
  319:     <p><i>Example 9-3: <a name="77020"></a></i> <i>Hardcoded
  320:     representation of generated XUL</i></p>
  321: <pre>
  322:  &lt;?xml version="1.0"?&gt;
  323:  &lt;?xml-stylesheet href="chrome://global/skin" type="text/css"?&gt;
  324:  &lt;window
  325:     xmlns="<a href=
  326: "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul</a>"&gt;
  327:    &lt;listbox datasources="10-1.rdf" ref="urn:root" flex="1"&gt;
  328:      &lt;listitem id="rdf:#$mPgLw2"&gt;
  329:        &lt;listcell label="Horse"/&gt;
  330:      &lt;/listitem&gt;
  331:      &lt;listitem id="rdf:#$nPgLw2"&gt;
  332:        &lt;listcell label="House"/&gt;
  333:      &lt;/listitem&gt;
  334:      &lt;listitem id="rdf:#$oPgLw2"&gt;
  335:        &lt;listcell label="Fruit"/&gt;
  336:      &lt;/listitem&gt;
  337:    &lt;/listbox&gt;
  338:  &lt;/window&gt;
  339: </pre>
  340:     <p>It's beneficial to see how this document is translated into
  341:     a DOM tree using Mozilla's DOM Inspector tool, with which the
  342:     structure is presented in a view that makes it easy to follow.
  343:     <a href="#77002">Figure 9-1</a> shows how the template tree
  344:     nodes are generated into an actual tree. To use this tool,
  345:     select "DOM Inspector" from the Tools &gt; Web Development menu
  346:     in Mozilla. If you have the template displayed in an open
  347:     browser window, you can load it in the DOM Inspector by
  348:     selecting File &gt; Inspect a Window and choosing it from the
  349:     list.</p>
  350:     <div class="c20">
  351:       <img src="foo.gif">
  352:     </div>
  353:     <p><i>Figure 9-1: <a name="77002"></a></i> <i>DOM
  354:     representation of XUL template generation</i></p>
  355:     <p>In <a href="#77002">Figure 9-1</a>, you can see how the
  356:     <tt>&lt;listitem&gt;</tt> was generated three times from the
  357:     template. Interestingly, the generated code doesn't replace the
  358:     original template, but is appended to the <tt>&lt;tree&gt;</tt>
  359:     as another tree row.</p>
  360:     <p>Finally, <a href="#77004">Figure 9-2</a> shows what the
  361:     actual XUL file looks like when loaded. If you save the
  362:     template in <a href="#77016">Example 9-1</a> to a file called
  363:     <i>9-1.xul</i>, save the RDF data in <a href=
  364:     "ch10.html#77026">Example 10-1</a> to a file called
  365:     <i>10-1.rdf</i> (which the template looks for by name in the
  366:     same directory), and then load the template into the browser,
  367:     you ought to see something very similar.</p>
  368:     <div class="c20">
  369:       <img src="foo.gif">
  370:     </div>
  371:     <p><i>Figure 9-2: <a name="77004"></a></i> <i>View of XUL tree
  372:     in Mozilla</i></p>
  373:     <h2><a name="77040"></a> Enhancing XUL Templates</h2>
  374:     <p>Creating simple XUL templates can help familiarize you with
  375:     the flexibility and complex design issues of a template. The
  376:     RDF file created in <a href="#77022">Example 9-4</a> introduces
  377:     the concept of nested content. A <tt>&lt;listbox&gt;</tt> can
  378:     generate nested content from multiple containers in the RDF
  379:     datasource. These multiple containers must have the same basic
  380:     design to work properly, so the design must be abstracted to
  381:     apply to all datasources. <a href="#77024">Example 9-5</a> uses
  382:     the <tt>&lt;fly:list&gt;</tt> design to accomplish this
  383:     task.</p>
  384:     <p>The advantage of having nested content in XUL templates is
  385:     that you can organize items visually, even when those things
  386:     come from different sources. Nested content allows you to form
  387:     subtrees and submenus rather than long monolithic lists.</p>
  388:     <h3><a name="77041"></a> Nested Content Sample</h3>
  389:     <p>The window in <a href="#77006">Figure 9-3</a> represents 
  390:     <!--INDEX XUL templates:nested content --> 
  391:     <!--INDEX nesting, template content (XUL) --> a template with
  392:     nested data and styled elements. Note that the top of the
  393:     content area has a standard <tt>&lt;listbox&gt;</tt> and a
  394:     color-styled <tt>&lt;tree&gt;</tt> is on the bottom. The next
  395:     several sections describe the creation of the XUL file in <a
  396:     href="#77006">Figure 9-3</a>.</p>
  397:     <div class="c20">
  398:       <img src="foo.gif">
  399:     </div>
  400:     <p><i>Figure 9-3: <a name="77006"></a></i> <i>Listbox and tree
  401:     template</i></p>
  402:     <p>In this example, both the <tt>
  403:     <!--INDEX tree element, XUL:nested content --> 
  404:     <!--INDEX trees:nested content --> &lt;tree&gt;</tt> and the
  405:     <tt><!--INDEX listbox element, XUL:nested content -->
  406:     &lt;listbox&gt;</tt> use the same data, but different template
  407:     formats. Only two columns appear in the
  408:     <tt>&lt;listbox&gt;</tt>, for example, and the rows were
  409:     created to display the color of the data's color attribute. You
  410:     could as easily have styled the <tt>&lt;tree&gt;</tt> this way
  411:     and left the <tt>&lt;listbox&gt;</tt> as a regular list. To
  412:     display large amounts of raw data, however,
  413:     <tt>&lt;tree&gt;</tt> is usually the best option because it's
  414:     faster with big datasets, offers built-in sorting, and looks
  415:     cleaner.</p>
  416:     <p>The <tt>&lt;listbox&gt;</tt> template can make the XUL seem
  417:     more complicated than the content would seem to require in <a
  418:     href="#77006">Figure 9-3</a>, but a template's basic design can
  419:     be similar for all types of data, which allows you to write
  420:     once and apply templates to different datasets. In this case,
  421:     you gain more efficiency because the RDF contributes more to
  422:     the template generation than does the XUL, making
  423:     template-based applications data-driven.</p>
  424:     <p><a href="#77022">Example 9-4</a> contains the XUL for
  425:     producing the tree shown in <a href="#77006">Figure 9-3</a>.
  426:     The difference between the code in Examples <a href=
  427:     "#77018">9-2</a> and <a href="#77032">9-9</a> is minimal, but
  428:     the latter produces a much more impressive visual result.
  429:     Remember that a XUL template and RDF produce the content you
  430:     see when loading these listbox examples. No stylesheets or
  431:     other enhancements are needed.</p>
  432:     <p><i>Example 9-4: <a name="77022"></a></i> <i>XUL tree
  433:     template in Figure 9-3</i></p>
  434: <pre>
  435:    &lt;listbox datasources="10-4.rdf" ref="urn:root" flex="1"
  436:          containment="<a href=
  437: "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#list"&gt;
  438:      &lt;template&gt;
  439:        &lt;rule&gt;
  440:          &lt;conditions&gt;
  441:            &lt;content uri="?uri"/&gt;
  442:            &lt;triple subject="?uri"
  443:                     predicate="<a href=
  444: "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#list"                      object="?list"/&gt;
  445:            &lt;member container="?list" child="?listitem"/&gt;
  446:            &lt;triple subject="?listitem"
  447:                     predicate="<a href=
  448: "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#label"                           object="?label"/&gt;
  449:          &lt;/conditions&gt;
  450:          &lt;bindings&gt;
  451:            &lt;binding subject="?listitem"
  452:                     predicate="<a href=
  453: "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#color"
  454:                      object="?color"/&gt;
  455:            &lt;binding subject="?listitem"
  456:                     predicate="fly-location#location"
  457:                     object="?location"/&gt;
  458:          &lt;/bindings&gt;
  459:          &lt;action&gt;
  460:            &lt;listitem uri="?listitem" class="?color"&gt;
  461:              &lt;listcell label="?label" class="treecell-indent"/&gt;
  462:              &lt;listcell label="?location" class="treecell-indent"/&gt;
  463:            &lt;/listitem&gt;
  464:          &lt;/action&gt;
  465:        &lt;/rule&gt;
  466:      &lt;/template&gt;
  467:      &lt;listcols&gt;
  468:        &lt;listcol flex="1"/&gt;
  469:        &lt;listcol flex="1"/&gt;
  470:      &lt;/listcols&gt;
  471:    &lt;/listbox&gt;
  472: </pre>
  473:     <p>The biggest difference between <a href="#77022">Example
  474:     9-4</a> and earlier examples is the <tt>&lt;bindings&gt;</tt>
  475:     section. All matching in a binding element is optional, unlike
  476:     the condition content. The elements in the bindings are simply
  477:     optional triples. Placing these triples in a binding affords
  478:     you some flexibility when data is missing from the RDF file or
  479:     when you are not certain about its contents-such as when you
  480:     create a roster but don't have all the people's addresses.</p>
  481:     <p>The <tt>containment</tt> attribute on the tree specifies the
  482:     URI of all the containers. In this case, the container is the
  483:     <tt>&lt;fly:list&gt;</tt> tag in the RDF. To see how such a
  484:     complex-looking <tt>&lt;listbox&gt;</tt> can be generated from
  485:     so little XUL, look at how the containers are set up in the
  486:     RDF. The RDF file appears (in a reformatted and somewhat
  487:     simplified form) in <a href="#77024">Example 9-5</a>. This
  488:     simplified form can help you see the structure underlying the
  489:     data and how it is reused to order the data efficiently.</p>
  490:     <p><i>Example 9-5: <a name="77024"></a></i> <i>Simplified
  491:     version of 10-4 RDF data</i></p>
  492: <pre>
  493:    &lt;rdf:Description about="urn:root"&gt;
  494:      &lt;fly:list&lt;/td&gt;&gt;
  495:        &lt;rdf:Seq&gt;
  496:          &lt;rdf:li&gt;
  497:            &lt;rdf:Description ID="House"&gt;
  498:              &lt;fly:label&lt;/td&gt;&gt;House&lt;/fly:label&gt;
  499:            &lt;/rdf:Description&gt;
  500:            &lt;fly:list&lt;/td&gt;
  501:              &lt;rdf:Seq&gt;
  502:                &lt;rdf:li&gt;
  503:                 &lt;rdf:Description about="musca_autumnalis"
  504:                                  fly:label&lt;/td&gt;="Face Fly"/&gt;
  505:                &lt;/rdf:li&gt;
  506:              &lt;rdf:Seq&gt;
  507:            &lt;/fly:list&gt;
  508:          &lt;/rdf:li&gt;
  509:        &lt;/rdf:Seq&gt;
  510:      &lt;/fly:list&gt;
  511:    &lt;/rdf:Description&gt;
  512: </pre>
  513:     <p>The RDF data in <a href="#77024">Example 9-5</a>
  514:     demonstrates a two-level pattern of recursion:
  515:     <tt>fly:list/fly:label</tt> are both reused at different levels
  516:     in the RDF data. The template in <a href="#77022">Example
  517:     9-4</a> generates the data into a tree showing two levels, as
  518:     shown in <a href="#77006">Figure 9-3</a>.</p>
  519:     <p><a href="#77024">Example 9-5</a> clearly shows that only
  520:     <tt>fly:list</tt> and <tt>fly:label</tt> are needed to generate
  521:     the template. The other data, such as color, are not mandatory
  522:     because they are defined in a <tt>&lt;binding&gt;</tt> rather
  523:     than a <tt>&lt;triple&gt;</tt>.</p>
  524:     <h3><a name="77042"></a> Using Data for Style</h3>
  525:     <p>RDF data are used for more than 
  526:     <!--INDEX XUL templates:styles --> 
  527:     <!--INDEX styles:XUL templates --> 
  528:     <!--INDEX RDF data, styles and --> 
  529:     <!--INDEX styles:RDF data and --> containers and labels. It's
  530:     possible to use RDF to define CSS classes, XUL attributes, and
  531:     other arbitrary bits of XUL content. In <a href=
  532:     "#77022">Example 9-4</a>, the <tt>&lt;listitem&gt;</tt> has a
  533:     <tt>class</tt> attribute that is filled by <tt>?color</tt>:</p>
  534: <pre>
  535: &lt;listitem uri="?listitem" class="?color"&gt;
  536: &lt;treecell label="?label"/&gt;
  537: &lt;treecell label="?location"/&gt;
  538: &lt;/listitem&gt;
  539: </pre>
  540:     <p>If a stylesheet has class definitions for the same values
  541:     located in the RDF, then every generated row can have its own
  542:     style. Here is a simple class showing style rules defined for
  543:     items of the "green" class.</p>
  544: <pre>
  545: .green
  546: {
  547: background-color: green;
  548: }
  549: </pre>
  550:     <p>As shown in the earlier examples of this chapter, using
  551:     <tt>&lt;listbox&gt;</tt> with templates generally yields
  552:     flexible and simpler implementations. Trees, covered next, are
  553:     not as flexible, but they can be better for raw data display,
  554:     as when you have spreadsheet-like information, many columns, or
  555:     other data that can be sorted.</p>
  556:     <h3><a name="77043"></a> Tree Template</h3>
  557:     <p><tt>&lt;tree&gt;</tt> is the best choice for 
  558:     <!--INDEX tree template, XUL --> 
  559:     <!--INDEX XUL templates:tree --> displaying simple data with
  560:     better visual speed, automatic sorting, and column selection
  561:     capabilities. In contrast to listboxes, trees do not create a
  562:     full DOM representation data when the template generates.
  563:     Instead, a tree keeps data in its own database and updates its
  564:     display more quickly than a listbox when the user scrolls or
  565:     sorts.</p>
  566:     <p>The XUL tree in <a href="#77026">Example 9-6</a> can be
  567:     compared to the <tt>listbox</tt> XUL in <a href=
  568:     "#77022">Example 9-4</a>. The template design is almost exactly
  569:     the same in both examples, but the elements surrounding the
  570:     template in the tree-<tt>treebody</tt>, <tt>treecol</tt>, and
  571:     <tt>treecells-</tt>are more complex and allow a precise layout
  572:     by giving you more granular control over the parts of the
  573:     layout. These parts include the header, the columns, and the
  574:     parent-child relationships. XUL's parent element affects the
  575:     presentation of the template-based data.</p>
  576:     <p><i>Example 9-6: <a name="77026"></a></i> <i>Tree template
  577:     code of Figure 9-3</i></p>
  578: <pre>
  579:    &lt;tree datasources="10-4.rdf" flex="1" ref="urn:root"
  580:          containment="<a href=
  581: "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#list"&gt;
  582:      &lt;treecols&gt;
  583:        &lt;treecol id="LabelCol" flex="1" sort="rdf:<a href=
  584: "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#label"<br>                class=&quot;sortDirectionIndicator&quot; primary="true" label="Name"/&gt;
  585:        &lt;treecol id="LoCol" flex="1" sort="rdf:<a href=
  586: "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#location"
  587:                 label="Location"/&gt;
  588:        &lt;treecol id="ColCol" flex="1" sort="rdf:<a href=
  589: "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#color"
  590:                 label="Color"/&gt;
  591:      &lt;/treecols&gt;&lt;template&gt;
  592:        &lt;rule&gt;
  593:          &lt;conditions&gt;
  594:            &lt;content uri="?uri"/&gt;
  595:            &lt;triple subject="?uri"
  596:                    predicate="<a href=
  597: "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#list"
  598:                    object="?list"/&gt;
  599:            &lt;member container="?list" child="?listitem"/&gt;
  600:            &lt;triple subject="?listitem"
  601:                    predicate="<a href=
  602: "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#label"
  603:                    object="?label"/&gt;
  604:          &lt;/conditions&gt;
  605:          &lt;bindings&gt;
  606:            &lt;binding subject="?listitem"
  607:                     predicate="<a href=
  608: "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#color"
  609:                     object="?color"/&gt;
  610:            &lt;binding subject="?listitem"
  611:                     predicate=" <a href=
  612: "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#location"
  613:                     object="?location"/&gt;
  614:          &lt;/bindings&gt;
  615:          &lt;action&gt;
  616:            &lt;treechildren&gt;
  617:              &lt;treeitem uri="?listitem"&gt;
  618:                &lt;treerow&gt;
  619:                  &lt;treecell ref="LabelCol"  label="?label"/&gt;
  620:                  &lt;treecell ref="LoCol" label="?location"/&gt;
  621:                  &lt;treecell ref="ColCol" label="?color"/&gt;
  622:                &lt;/treerow&gt;
  623:              &lt;/treeitem&gt;
  624:            &lt;/treechildren&gt;
  625:          &lt;/action&gt;
  626:        &lt;/rule&gt;
  627:      &lt;/template&gt;
  628:    &lt;/tree&gt;
  629: </pre>
  630: <p>One major difference between this example and earlier ones
  631:     is that <a href="#77026">Example 9-6</a> has three columns. The
  632:     color data cannot be used for style in this tree scenario
  633:     because trees do not support CSS data styling.</p>
  634:     <p>All generated data can be sorted automatically by clicking
  635:     on the column headers. Besides the tree parent element in the
  636:     XUL, the other main difference between this template and the
  637:     one used with a listbox in <a href="#77022">Example 9-4</a> is
  638:     the structure directly beneath <tt>&lt;conditions&gt;</tt>,
  639:     where <tt>&lt;content&gt;</tt> is replaced by
  640:     <tt>&lt;treerow&gt;</tt>.</p>
  641:     <h3><a name="77044"></a> Multiple Rules Tree</h3>
  642:     <p>In <a href="#77026">Example 9-6</a>, empty cells 
  643:     <!--INDEX tree template, XUL:rules --> were 
  644:     <!--INDEX rules, XUL templates:tree template --> left blank.
  645:     Sometimes situations demand that missing data be represented by
  646:     something other than whitespace, such as a special character or
  647:     marker. Fortunately, <!--INDEX trees:multiple rules -->
  648:     multiple <tt>&lt;rule&gt;</tt> tags can exist in a template, as
  649:     shown in <a href="#77028">Example 9-7</a>. Alternate rule tags
  650:     allow the display of missing data with other, more general
  651:     rules. Using alternate tags, you can set up templates that look
  652:     like conditional blocks; if the first rule is not satisfied,
  653:     then the second rule is tried, followed by the third, and so
  654:     on. <a href="#77028">Example 9-7</a> shows this structure of
  655:     multiple rules.</p>
  656:     <p><i>Example 9-7: <a name="77028"></a></i> <i>Tree template
  657:     with rules</i></p>
  658: <pre>
  659:    &lt;tree datasources="10-4.rdf" flex="1" ref="urn:root"
  660:          containment="<a href=
  661: "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#list"&gt;
  662:      &lt;treecols&gt;
  663:        &lt;treecol id="LabelCol" flex="1" sort="rdf:<a href=
  664: "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#label"<br>                class=&quot;sortDirectionIndicator&quot; primary="true" label="Name"/&gt;
  665:        &lt;treecol id="LoCol" flex="1" sort="rdf:<a href=
  666: "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#location"
  667:                 label="Location"/&gt;
  668:        &lt;treecol id="ColCol" flex="1" sort="rdf:<a href=
  669: "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#color"
  670:                 label="Color"/&gt;
  671:      &lt;/treecols&gt;
  672:      &lt;template&gt;
  673:        &lt;!-- RULE 1: Row contains both a color and location. --&gt;
  674:        &lt;rule&gt;
  675:          &lt;conditions&gt;
  676:            &lt;content uri="?uri"/&gt;
  677:            &lt;triple subject="?uri"
  678:                    predicate="<a href=
  679: "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#list"
  680:                    object="?list"/&gt;
  681:            &lt;member container="?list" child="?listitem"/&gt;
  682:            &lt;triple subject="?listitem"
  683:                    predicate="<a href=
  684: "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#label"
  685:                    object="?label"/&gt;
  686:            &lt;triple subject="?listitem"
  687:                    predicate="<a href=
  688: "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#color"
  689:                    object="?color"/&gt;
  690:            &lt;triple subject="?listitem"
  691:                    predicate=" <a href=
  692: "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#location"
  693:                    object="?location"/&gt;
  694:          &lt;/conditions&gt;
  695:          &lt;action&gt;
  696:            &lt;treechildren&gt;
  697:              &lt;treeitem uri="?listitem"&gt;
  698:                &lt;treerow&gt;
  699:                  &lt;treecell ref="LabelCol" label="?label"/&gt;
  700:                  &lt;treecell ref="LoCol" label="?location"/&gt;
  701:                  &lt;treecell ref="ColCol" label="?color"/&gt;
  702:                &lt;/treerow&gt;
  703:              &lt;/treeitem&gt;
  704:            &lt;/treechildren&gt;
  705:          &lt;/action&gt;
  706:        &lt;/rule&gt;
  707:        &lt;!-- RULE 2: Row contains a color and no location. --&gt;
  708:        &lt;rule&gt;
  709:          &lt;conditions&gt;
  710:            &lt;content uri="?uri"/&gt;
  711:            &lt;triple subject="?uri"
  712:                    predicate="<a href=
  713: "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#list"
  714:                    object="?list"/&gt;
  715:            &lt;member container="?list" child="?listitem"/&gt;
  716:            &lt;triple subject="?listitem"
  717:                    predicate="<a href=
  718: "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#label"
  719:                    object="?label"/&gt;
  720:            &lt;triple subject="?listitem"
  721:                    predicate="<a href=
  722: "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#color"
  723:                    object="?color"/&gt;
  724:          &lt;/conditions&gt;
  725:          &lt;action&gt;
  726:            &lt;treechildren&gt;
  727:              &lt;treeitem uri="?listitem"&gt;
  728:                &lt;treerow&gt;
  729:                  &lt;treecell ref="LabelCol" label="?label"/&gt;
  730:                  &lt;treecell ref="LoCol" label="-"/&gt;
  731:                  &lt;treecell ref="ColCol" label="?color"/&gt;
  732:                &lt;/treerow&gt;
  733:              &lt;/treeitem&gt;
  734:            &lt;/treechildren&gt;
  735:          &lt;/action&gt;
  736:        &lt;/rule&gt;
  737:        &lt;!-- RULE 3: Row contains neither a color or location. --&gt;
  738:        &lt;rule&gt;
  739:          &lt;conditions&gt;
  740:            &lt;content uri="?uri"/&gt;
  741:            &lt;triple subject="?uri"
  742:                    predicate="<a href=
  743: "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#list"
  744:                    object="?list"/&gt;
  745:            &lt;member container="?list" child="?listitem"/&gt;
  746:            &lt;triple subject="?listitem"
  747:                    predicate="<a href=
  748: "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#label"
  749:                    object="?label"/&gt;
  750:          &lt;/conditions&gt;
  751:          &lt;action&gt;
  752:            &lt;treechildren&gt;
  753:              &lt;treeitem uri="?listitem"&gt;
  754:                &lt;treerow&gt;
  755:                  &lt;treecell ref="LabelCol" label="?label"/&gt;
  756:                  &lt;treecell ref="LoCol" label=" "/&gt;
  757:                  &lt;treecell ref="ColCol" label=" "/&gt;
  758:                &lt;/treerow&gt;
  759:              &lt;/treeitem&gt;
  760:            &lt;/treechildren&gt;
  761:          &lt;/action&gt;
  762:        &lt;/rule&gt;
  763:      &lt;/template&gt;
  764:    &lt;/tree&gt;
  765: </pre>
  766:     <p>In contrast to <a href="#77026">Example 9-6</a>, <a href=
  767:     "#77028">Example 9-7</a> moves <tt>?location</tt> from
  768:     <tt>&lt;bindings&gt;</tt> to <tt>&lt;conditions&gt;</tt> in the
  769:     first <tt>&lt;rule&gt;</tt> in the template, making it a
  770:     required match. To avoid breaking the template-because not all
  771:     objects in the RDF file have a <tt>?location</tt> value-you
  772:     need to make a backup plan for generating this template when it
  773:     encounters an object without a <tt>?location</tt>. This backup
  774:     can be a second set of more broadly defined conditions, so that
  775:     objects that "fall out" of the first condition are picked up by
  776:     the next. See the next section for an example of using
  777:     different sets of rules.</p>
  778:     
  779: <p>The most important inclusions to <a href="#77028">Example 9-7</a> are the <tt>container="?uri"</tt> 
  780:   <tt>member="?listitem"</tt> attributes on the <tt>&lt;template&gt;</tt>. These 
  781:   attributes specify which container you should apply multiple rules to, and the 
  782:   <tt>member</tt> is for the objects in a container that must be checked. Adding 
  783:   these attributes keeps the template from dying when the data doesn't meet the 
  784:   first rule. The second rule, which doesn't have a <tt>&lt;triple&gt;</tt> or 
  785:   <tt>&lt;binding&gt;</tt> to identify it, is used only when a <tt>?location</tt> 
  786:   isn't present. Instead, it automatically fills in that cell with a hyphen (<a href="#77008">Figure 
  787:   9-4</a>).</p>
  788:     <div class="c20">
  789:       <img src="foo.gif">
  790:     </div>
  791:     <p><i>Figure 9-4: <a name="77008"></a></i> <i>Tree template
  792:     with hyphen rule</i></p>
  793:     <p>As you can see at the top of <a href="#77028">Example
  794:     9-7</a>, the template datasource is a file called
  795:     <i>10-4.rdf</i>, which contains all the data listed in <a href=
  796:     "ch10.html#77032">Example 10-4</a> (in the next chapter). If
  797:     you save the template listed in <a href="#77028">Example
  798:     9-7</a> and the RDF listed in <a href="ch10.html#77032">Example
  799:     10-4</a>, you can display the tree shown in <a href=
  800:     "#77008">Figure 9-4</a>.</p>
  801:     <h3><a name="77045"></a> Multiple Rules Menubar</h3>
  802:     <p><a href="#77028">Example 9-7</a> is a <tt>
  803:     <!--INDEX tree template, XUL:rules:menubar --> 
  804:     <!--INDEX rules, XUL templates:tree template:menubar -->
  805:     &lt;tree&gt;</tt> <!--INDEX menu bar:tree template (XUL) -->
  806:     template that contains three rules. In <a href="#77030">Example
  807:     9-8</a>, where a <tt>&lt;menubar&gt;</tt> is shown with three
  808:     rules, all possible menu scenarios must be covered. <a href=
  809:     "#77014">Table 9-2</a> provides a list of these scenarios. Use
  810:     scenarios like this to make sure you have content that can be
  811:     created for all the data you need represented.</p>
  812:     <p><i>Table 9-2: <a name="77014"></a></i> <i>Scenarios used for
  813:     building template rules</i></p>
  814:     <tt>&lt;menu&gt;</tt>has a <tt>label</tt>and contains a
  815:     <tt>&lt;menupopup&gt;</tt>. Inside it are two
  816:     <tt>&lt;menuitem&gt;</tt>s: <tt>?location</tt>and
  817:     <tt>?color</tt>.<tt>&lt;menu&gt;</tt>has a <tt>label</tt>and
  818:     contains a <tt>&lt;menupopup&gt;</tt>. Inside it is one
  819:     <tt>&lt;menuitem&gt;</tt>:
  820:     <tt>?color</tt>.<tt>&lt;menu&gt;</tt>has a <tt>label</tt>and
  821:     contains a <tt>&lt;menupopup&gt;</tt>. Inside there is no
  822:     <tt>&lt;menuitem&gt;</tt>(only <tt>&lt;menus&gt;</tt>).
  823:     <table width="100%" border="1">
  824:       <tr>
  825:         <td><b>Scenario</b></td>
  826:         <td><b>Description</b></td>
  827:       </tr>
  828:       <tr>
  829:         <td>Scenario 1</td>
  830:         <td>A</td>
  831:       </tr>
  832:       <tr>
  833:         <td>The Horn Fly, Carrion Fly, and Office Fly fall into
  834:         this category.</td>
  835:       </tr>
  836:       <tr>
  837:         <td>Scenario 2</td>
  838:         <td>A</td>
  839:       </tr>
  840:       <tr>
  841:         <td>The Common House Fly, Stable Fly, and Face Fly fall
  842:         into this category.</td>
  843:       </tr>
  844:       <tr>
  845:         <td>Scenario 3</td>
  846:         <td>A</td>
  847:       </tr>
  848:       <tr>
  849:         <td>Horse and House fall into this category.</td>
  850:       </tr>
  851:     </table>
  852:     <p>The scenarios in <a href="#77014">Table 9-2</a> can be
  853:     translated directly into three template rules. Scenario 1 would
  854:     be the first rule because it uses the most content. Scenario 2
  855:     would be the second rule because it's missing only the
  856:     location. Scenario 3 will be the final rule because it doesn't
  857:     have a location or color.</p>
  858:     <p><i>Example 9-8: <a name="77030"></a></i> <i>Menubar template
  859:     with three rules</i></p>
  860: <pre>
  861:      &lt;menubar datasources="10-4.rdf" ref="urn:root"
  862:          containment="<a href=
  863: "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#list"&gt;
  864:      &lt;template&gt;
  865:        &lt;!-- RULE 1: Menu contains both a color and location menuitem. --&gt;
  866:        &lt;rule&gt;
  867:          &lt;conditions&gt;
  868:            &lt;content uri="?uri"/&gt;
  869:            &lt;triple subject="?uri"
  870:                    predicate="<a href=
  871: "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#list"
  872:                    object="?list"/&gt;
  873:            &lt;member container="?list" child="?listitem"/&gt;
  874:            &lt;triple subject="?listitem"
  875:                    predicate="<a href=
  876: "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#label"
  877:                    object="?label"/&gt;
  878:            &lt;triple subject="?listitem"
  879:                    predicate="<a href=
  880: "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#color"
  881:                    object="?color"/&gt;
  882:            &lt;triple subject="?listitem"
  883:                    predicate="fly-location#location"
  884:                    object="?location"/&gt;
  885:          &lt;/conditions&gt;
  886:          &lt;action&gt;
  887:            &lt;menu label="?label" uri="?listitem"&gt;
  888:              &lt;menupopup uri="?listitem"&gt;
  889:                &lt;menuitem label="?color"/&gt;
  890:                &lt;menuitem label="?location"/&gt;
  891:              &lt;/menupopup&gt;
  892:            &lt;/menu&gt;
  893:          &lt;/action&gt;
  894:        &lt;/rule&gt;
  895:        &lt;!-- RULE 2: Menu contains only a color menuitem. --&gt;
  896:        &lt;rule&gt;
  897:          &lt;conditions&gt;
  898:            &lt;content uri="?uri"/&gt;
  899:            &lt;triple subject="?uri"
  900:                    predicate="<a href=
  901: "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#list"
  902:                    object="?list"/&gt;
  903:            &lt;member container="?list" child="?listitem"/&gt;
  904:            &lt;triple subject="?listitem"
  905:                    predicate="<a href=
  906: "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#label"
  907:                    object="?label"/&gt;
  908:            &lt;triple subject="?listitem"
  909:                    predicate="<a href=
  910: "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#color"
  911:                    object="?color"/&gt;
  912:          &lt;/conditions&gt;
  913:          &lt;action&gt;
  914:            &lt;menu label="?label" uri="?listitem"&gt;
  915:              &lt;menupopup uri="?listitem"&gt;
  916:                &lt;menuitem label="?color"/&gt;
  917:              &lt;/menupopup&gt;
  918:            &lt;/menu&gt;
  919:          &lt;/action&gt;
  920:        &lt;/rule&gt;
  921:        &lt;!-- RULE 3: Menu contains no color or location menuitems. --&gt;
  922:        &lt;!-- This applies to the main menus, shown on the menubar. --&gt;
  923:        &lt;rule&gt;
  924:          &lt;conditions&gt;
  925:            &lt;content uri="?uri"/&gt;
  926:            &lt;triple subject="?uri"
  927:                    predicate="<a href=
  928: "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#list"
  929:                    object="?list"/&gt;
  930:            &lt;member container="?list" child="?listitem"/&gt;
  931:            &lt;triple subject="?listitem"
  932:                    predicate="<a href=
  933: "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#label"
  934:                    object="?label"/&gt;
  935:          &lt;/conditions&gt;
  936:          &lt;action&gt;
  937:            &lt;!-- Create the menus across the menubar --&gt;
  938:            &lt;menu label="?label" uri="?listitem"&gt;
  939:              &lt;!-- Give the menu the ability to popup content --&gt;
  940:              &lt;menupopup uri="?listitem"/&gt;
  941:            &lt;/menu&gt;
  942:          &lt;/action&gt;
  943:        &lt;/rule&gt;
  944:      &lt;/template&gt;
  945:    &lt;/menubar&gt;
  946: </pre>
  947:     <p>As you can see, <a href="#77030">Example 9-8</a> is a long
  948:     XUL section. When you create the first rule, it becomes easier,
  949:     though, because the subsequent rules are just versions of the
  950:     rules above them. <a href="#77010">Figure 9-5</a> shows how
  951:     this <tt>&lt;menubar&gt;</tt> template draws the data in the
  952:     <i>9-5.rdf</i> datasource.</p>
  953:     <div class="c20">
  954:       <img src="foo.gif">
  955:     </div>
  956:     <p><i>Figure 9-5: <a name="77010"></a></i> <i>Menubar template
  957:     with menus</i></p>
  958:     <h2><a name="77046"></a> Using Other XUL Tags for
  959:     Templates</h2>
  960:     <p>Almost any XUL element that 
  961:     <!--INDEX XUL (XML-based User-interface Language):tags:templates -->
  962:     <!--INDEX XUL templates:tags --> 
  963:     <!--INDEX tags, XUL:templates --> can be used as a container
  964:     can use a template to define its inner content. <a href=
  965:     "#77032">Example 9-9</a> shows a <tt>&lt;box&gt;</tt> used as
  966:     the start for a XUL template. Templates like this can create
  967:     content that doesn't look as tabular or ordered.</p>
  968:     <p><i>Example 9-9: <a name="77032"></a></i> <i>Template
  969:     implemented in a box with buttons as content</i></p>
  970: <pre>
  971:    &lt;box datasources="10-4.rdf" ref="urn:root"         containment="<a
  972:  href=
  973: "http://xfly.mozdev.org/">http://xfly.mozdev.org/</a>       fly-rdf#list"&gt;
  974:      &lt;template&gt;
  975:        &lt;rule&gt;
  976:          &lt;conditions&gt;
  977:            &lt;content uri="?uri"/&gt;
  978:            &lt;triple subject="?uri"
  979:                     predicate="<a href=
  980: "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#list"                          object="?list"/&gt;
  981:            &lt;member container="?list" child="?listitem"/&gt;
  982:            &lt;triple subject="?listitem"
  983:                     predicate="<a href=
  984: "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#label"                           object="?label"/&gt;
  985:          &lt;/conditions&gt;
  986:          &lt;bindings&gt;
  987:            &lt;binding subject="?listitem"
  988:                      predicate="<a href=
  989: "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#color"                         object="?color"/&gt;
  990:            &lt;binding subject="?listitem"
  991:                      predicate="fly-location#location"                            object="?location"/&gt;
  992:          &lt;/bindings&gt;
  993:          &lt;action&gt;
  994:              &lt;vbox uri="?listitem"&gt;
  995:                &lt;button label="?label"/&gt;
  996:                &lt;button label="?location"/&gt;
  997:                &lt;button label="?color"/&gt;
  998:                &lt;splitter/&gt;
  999:              &lt;/vbox&gt;
 1000:          &lt;/action&gt;
 1001:        &lt;/rule&gt;
 1002:      &lt;/template&gt;
 1003:    &lt;/box&gt;
 1004: </pre>
 1005:     <p>The content generated in <a href="#77032">Example 9-9</a>
 1006:     includes three <tt>&lt;button&gt;</tt>s and a
 1007:     <tt>&lt;splitter&gt;</tt> inside a vertical
 1008:     <tt>&lt;box&gt;</tt>. The template building process is repeated
 1009:     for every object in the RDF graph, and some buttons are left
 1010:     blank. The result is a window full of buttons for each piece of
 1011:     data, which may get you started making heads-up displays or
 1012:     panel-like applications for templates, such as flight
 1013:     simulators.</p>
 1014:     <p>Once you understand the basics of templates, it is fun to
 1015:     see what kind of XUL you can generate from it, such as games
 1016:     that need to render content on the fly, spreadsheets, database
 1017:     front ends, or other data-driven application user
 1018:     interfaces.</p>
 1019:     <hr>
 1020:     <hr>
 1021:     <a name="241"></a><a href="#b241">[Back]</a> <a name=
 1022:     "77033"></a> An <tt>rdf:Bag</tt> is a type of RDF container,
 1023:     but when you use the <tt>&lt;member\&gt;</tt> tag, you do not
 1024:     have to specify whether the container is of the type Alt, Bag,
 1025:     or Sequence (see "nsIRDFContainer" in Chapter 10 for more
 1026:     details on working with containers in RDF). A template can only
 1027:     build the values sequentially out of a container, no matter
 1028:     what type it is. Thus, using an <tt>rdf:Seq</tt> or
 1029:     <tt>rdf:Alt</tt> element produces the same visual output in
 1030:     these Mozilla templates. 
 1031:     <hr>
 1032:     <br>
 1033:     <br>
 1034:     File a <a href=
 1035:     "http://mozdev.org/bugs/enter_bug.cgi?product=books">Bug</a>
 1036:     for chapter 9. 
 1037:     <?php $hide_text_control=1; $post_to_list=NO; $author='reviewers@mozdev.org'; // require(NOTES); ?>
 1038: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>