You may recall that templates generate content recursively. After the data is generated, each result is used as the new reference point for a nested iteration of the template. This is usually used to generate content in a tree or menu. The inner iteration uses the same rules as the outer iteration. However, it is quite possible that you would like child or leaf nodes to appear differently than the parent nodes. Multiple rules are useful in this situation. In this case, one rule would be used to match the outer data and another rule would be used to match the inner data. The builder will apply all rules in both cases, however, if the rules are created correctly, there will only be matches for the rules that you want.
For instance, we might have a datasource which represents the houses in a neighbourhood. The top node contains several children, one for each street. Each street also contains children, one for each house. Naturally, you would want the streets to be displayed in a different manner to the houses. The recursive nature of templates can be used for this example. The outer pass will start at the top node and generate the content for each street. The next pass will use a street as the starting point and generate the content for each house. We could go further and generate data for each room in each house by adding more rules.
<hbox datasources="template-guide-streets.rdf" ref="http://www.xulplanet.com/rdf/myneighbourhood" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <template> <rule rdf:type="http://www.xulplanet.com/rdf/House"> <vbox uri="rdf:*" class="box-padded"> <label value="Address: rdf:http://www.xulplanet.com/rdf/address"/> <label value="Floors: rdf:http://www.xulplanet.com/rdf/floors"/> </vbox> </rule> <rule> <groupbox uri="rdf:*" class="box-padded"> <caption label="rdf:http://purl.org/dc/elements/1.1/title"/> </groupbox> </rule> </template> </hbox>
The first rule matches only those items that have an RDF type of "http://www.xulplanet.com/rdf/House". The second rule doesn't have any condition filter so will match any result. The starting point indicated by the ref attribute is "http://www.xulplanet.com/rdf/myneighbourhood". In the RDF data, this is an RDF Bag with two children. Since the simple rule syntax is used in both rules, the builder will iterate over the children to generate results. At this pass, both of the children of "http://www.xulplanet.com/rdf/myneighbourhood" are streets and not houses so neither child will match the first rule. However, both children will match the second rule. Thus, two matches will be created using the second rule. The second rule creates a <groupbox> with a <caption>. If you look at image of the example, you will note that two groupboxes have been created.
The builder then recurses, using the previous result as the new starting point. For the first street, this new starting point will be "http://www.xulplanet.com/rdf/marion". The builder reapplies the rules starting from this new location in the RDF graph. The new node is an RDF Seq with children so the simple rules can generate some results. However, these results are houses, so the first rule will match. The second rule, since it has no conditions, will also match, but since the first rule takes priority, these rules would never apply. The effect is that the content for the first rule would be used for each house. This content is inserted inside the outer content generated for the street. This means that the <vbox> and the two labels will be placed inside the <groupbox> generated from the previous pass.
We could be more specific and specify a type in the datasource for the streets as well. This wouldn't affect the output in this example, but it may be more optimal in more complex templates to be as specific as possible when creating conditions. If there were other types of buildings on a particular street, we might add an additional rule for this. For instance, we might add another rule after the first:
<rule rdf:type="http://www.xulplanet.com/rdf/Store"> <vbox uri="rdf:*" class="box-padded"> <label value="Address: rdf:http://www.xulplanet.com/rdf/address"/> <label value="Sells: rdf:http://www.xulplanet.com/rdf/sells"/> </vbox> </rule>
This rule is similar to the first rule, however is matches only those items that have an RDF type of "http://www.xulplanet.com/rdf/Store".