File:  [mozdev] / books / www / docbook / ch09.xml
Revision 1.7: download - view: text, annotated - select for diffs - revision graph
Tue Jun 3 12:14:08 2003 UTC (16 years, 5 months ago) by brian
Branches: MAIN
CVS tags: HEAD
last correction cleared up by Eric

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

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