« PreviousNext »

The content to generate in a template is specified using the <xul:action> element which should either be the next sibling of the <xul:query> element (if no rules need be specified) or be a direct child of a <xul:rule> element. The content to generate goes directly inside the action element. This content will be copied for each matching result (though see below for an exception) and inserted into the document. Let's look at a simple example first.

<vbox datasources="http://www.xulplanet.com/ds/sample.rdf"
         ref="http://www.xulplanet.com/rdf/A">
  <template>
    <query>
      <content uri="?start"/>
      <triple subject="?start"
              predicate="http://www.xulplanet.com/rdf/relatedItem"
              object="?relateditem"/>
    </query>
    <action>
      <button uri="?relateditem" label="?relateditem"/>
    </action>
  </template>
</vbox>

In this example, we omit the <xul:rule> element around the <xul:action> as it is optional when we want to generate content unconditionally. Instead, the action element is placed directly inside the <xul:template> element after the query is defined. This action contains only one element, but you can put as many or as few elements as you need. In this case, a button will be created for each result. There are three results, so three buttons will be created. Here is the [example], and an image of what it looks like:

Image:template-guide-p8.png

The template builder iterates through the three results, processing the body of the action for each one in turn. The uri attribute on the button is used to specify the ending or member variable. In this example, there's only one variable to use, ?relateditem, since ?start is the starting point and the start and end points cannot be the same. There are a number of things that will happen for each result. Let's look at the results again:

(?start = http://www.xulplanet.com/rdf/A, ?relateditem = http://www.xulplanet.com/rdf/B)
(?start = http://www.xulplanet.com/rdf/A, ?relateditem = http://www.xulplanet.com/rdf/C)
(?start = http://www.xulplanet.com/rdf/A, ?relateditem = http://www.xulplanet.com/rdf/D)

The builder will start with the first result. The button element will be copied and inserted into the document after the template. The id attribute of the new element will be set to the same value of the member variable, ?relateditem. You could think of this as changing the uri attribute to the id attribute, and replacing the variable. Since the first result has a value of 'http://www.xulplanet.com/rdf/B' for the ?relateditem variable, the id will be set to this value.

Then, the remaining attributes on the element are examined and any variables are replaced in place. That is, the text ?relateditem in the label attribute will be replaced with the string 'http://www.xulplanet.com/rdf/B' for the first result. In the image, you can see that the label for the first button does indeed have this value. Processing is now complete for the first result, so the builder moves on to the next result. For result B, the builder would have generated the following content:

<button id="http://www.xulplanet.com/rdf/B" label="http://www.xulplanet.com/rdf/B"/>

Naturally, you wouldn't use an id attribute inside a template action since the id would be replaced anyway. In fact, any ids you put inside a template action will be ignored. However, you may use ids on the other parts of the template, such as within the query statements, if you wish to change the statements and rebuild the template. You can use getElementById to get at particular results, for instance document.getElementById("http://www.xulplanet.com/rdf/C") would retrieve the second generated button.

After all the results have been examined, the DOM tree will look like the following:

<vbox datasources="http://www.xulplanet.com/ds/sample.rdf"
         ref="http://www.xulplanet.com/rdf/A">
  <template>
    <query>
      <content uri="?start"/>
      <triple subject="?start"
              predicate="http://www.xulplanet.com/rdf/relatedItem"
              object="?relateditem"/>
    </query>
    <action>
      <button uri="?relateditem" label="?relateditem"/>
    </action>
  </template>
  <button id="http://www.xulplanet.com/rdf/B" label="http://www.xulplanet.com/rdf/B"/>
  <button id="http://www.xulplanet.com/rdf/C" label="http://www.xulplanet.com/rdf/C"/>
  <button id="http://www.xulplanet.com/rdf/D" label="http://www.xulplanet.com/rdf/D"/>
</vbox>

Since the template tag is hidden, the effect will be like in the image, three buttons with the labels of the data in the datasource.

Additional Content

The previous example generated only a set of buttons, but the action body may contain additional content. For instance, you might want to add a label to each item.

<action>
  <hbox uri="?relateditem">
    <label value="Related Item:"/>
    <button label="?relateditem"/>
  </hbox>
</action>

In this example, the hbox will be generated for each result, assigned an id of the value of the ?relateditem, and the label and button will be added inside it. The button's label will be the value of the ?relateditem variable. You would only use the uri attribute on a single element since only one of the generated elements should be given a particular id.

Although the uri attribute should only be on one element, it does not have to be the outermost element in the action body. You can place other elements outside this to serve as containers for all the results. One difference is that this content is only generated once, not for every result. Only the content at the element with the uri attribute and below is copied for each result. For example, if the example were modified to the following:

<action>
  <toolbar>
    <button uri="?relateditem" label="?relateditem"/>
  </toolbar>
</action>

Here, only the button would be repeated for each result; the toolbar will only be generated once. The toolbar is created just before the content for the first result is generated. The effect will be a toolbar with a set of three buttons inside it. Of course, in this simple example you could really just make the toolbar the outer element with the datasources attribute rather than placing it inside the action.

So far we have only been using the ?relateditem variable since that is really the only useful variable that is available. We could also use the ?start variable. Recall the results:

(?start = http://www.xulplanet.com/rdf/A, ?relateditem = http://www.xulplanet.com/rdf/B)
(?start = http://www.xulplanet.com/rdf/A, ?relateditem = http://www.xulplanet.com/rdf/C)
(?start = http://www.xulplanet.com/rdf/A, ?relateditem = http://www.xulplanet.com/rdf/D)

We could display the value of the ?start variable in the results if desired:

<action>
  <hbox uri="?relateditem">
    <button label="?start"/>
    <button label="?relateditem"/>
  </hbox>
</action>

For the first button, the value of the variable ?start will be looked up in the result data while the second button will use the ?relateditem variable. Since all three results have the same value for the ?start variable, the result will be that the first buttons in each row will all have the same label. Here is an image of [this example]

Image:template-guide-p9.png

(Note: see the next section for an explanation of why there are extra buttons here.)

« PreviousNext »