Sometimes you want to simply generate one block of content at the top level and different content at the recurisive level. For example, the bookmarks toolbar in Firefox displays buttons at the first level, but menus and submenus for content below that. The entire bookmarks toolbar is generated by a XUL template.

Templates have a means of allowing a rule to match only if the generated content would be inserted inside an element with a particular tag name. For instance, if the container was a <vbox>, a rule could be created that would only match a <vbox> element. This is useful for recursive templates, since the inner iterations may use different content. It's most useful to distinguish between the outer and inner levels during template generation. For the bookmarks toolbar, the outer content is inserted into an <hbox>, but at lower levels, the content will be inserted into a <menu>

In case you aren't clear, the tag that must match for the outer iteration is the root element, the one with the datasources attribute on it. For inner iterations, it will be the element with the uri attribute from the previous iteration.

To do this kind of matching for the simple template syntax, you place a parent attribute on the rule, set to the tag to match. For instance, we might use the following:

<vbox datasources="template-guide-streets.rdf"
            ref="http://www.xulplanet.com/rdf/myneighbourhood">
  <template>
    <rule parent="vbox">
      <groupbox uri="rdf:*">
        <caption label="rdf:http://purl.org/dc/elements/1.1/title"/>
      </groupbox>
    </rule>
    <rule>
      <label uri="rdf:*" value="rdf:http://www.xulplanet.com/rdf/address"/>
    </rule>
  </template>
</vbox>

On the first pass, the container where generated content would be inserted is a <vbox>, so the first rule will match and a captioned <groupbox> will be created. On the next pass, the parent container will be the element with the uri attribute from the previous pass, in this case, the <groupbox> The first rule will not match in this case, but the second rule will match and a label will be created. The result can be seen in you try the example.

A tag test can also be used with the extended syntax, although the syntax for using it is different. Instead of placing a parent attribute on the <rule>, you place a tag attribute on the <content> tag in the conditions. For instance, the equivalent tag test using the extended syntax for the previous example is the following:

<content uri="?start" tag="vbox">

This example generates the same output content as when using the simple template syntax.

As we've seen in the past few examples, there are many different ways of structuring the two rules to match differently at different levels. General triple tests, tests on an RDF type, container tests and parent tag tests all provide a wide variety of ways to match in very specific ways. Of course, in the simple examples we've been using, the advantages of one kind of condition test over another are not obvious. In more complex examples however, you will see the benefit of one test over others depending on the structure of the data and the UI that you wish to create. By combining the different types of conditions together, more complex interfaces can be created just with templates.