All of the examples shown so far have used only a single rule. The builder supports the use of multiple rules as well. This involves using additional <rule> elements after the first. There are three main reasons for using multiple rules. First, to generate different content when different criteria are met, second, to apply different content for child elements created during template recursion, and third, just to generate additional results that will be merged with the first rule. We'll see examples of each of these techniques. A multiple rule template looks like the following:
<hbox id="photosList" datasources="template-guide-photos3.rdf" ref="http://www.xulplanet.com/rdf/myphotos"> <template> <rule> <conditions> <content uri="?start"/> <member container="?start" child="?photo"/> <triple subject="?photo" predicate="http://purl.org/dc/elements/1.1/title" object="Canal"/> </conditions> <action> <button uri="?photo" image="?photo" label="View" orient="vertical"/> </action> </rule> <rule> <conditions> <content uri="?start"/> <member container="?start" child="?photo"/> </conditions> <action> <image uri="?photo" src="?photo"/> </action> </rule> </template> </hbox>
This template contains two rules, the first contains a <triple> which matches only the photo with a title of "Canal". The second rule doesn't contain such a triple and will match all three of the photos. It the first rule was used by itself, only one result would match. If the second rule was used by itself, three results would match. When used together in this example, the results are combined and only three results are shown. However, you will probably notice that the one photo that matches the first rule has appeared differently that the others. In fact, the content for this photo is that of the first rule with the button, whereas the content for the other photos is that of the second rule with the normal images.
This demonstrates the first style of using multiple rules, to generate different content under different circumstances. This is a very useful and commonly used technique since it allows for more complex content to be displayed. For instance, the Firefox bookmarks toolbar displays folders in a different manner than regular bookmarks. This is done by using multiple rules, one for folders and another for bookmarks. Actually, there are more than two rules used in bookmarks, since there are also separators, submenus, and livemarks to deal with.
We already know that a rule generates a set of results, possibly filtered based on the rule's conditions. There's no magic to the way in which the template builder processes multiple rules. It just takes the results generated from the first rule, adds the results for the second rule, adds the results for the third rule, and so on. Here are the results that would be generated by the first rule above, before any bindings are applied:
(?start = http://www.xulplanet.com/rdf/myphotos, ?photo = http://www.xulplanet.com/ndeakin/images/t/canal.jpg,
Then, the builder adds the three results generated from the second rule:
(?start = http://www.xulplanet.com/rdf/myphotos, ?photo = http://www.xulplanet.com/ndeakin/images/t/canal.jpg, (?start = http://www.xulplanet.com/rdf/myphotos, ?photo = http://www.xulplanet.com/ndeakin/images/t/palace.jpg) (?start = http://www.xulplanet.com/rdf/myphotos, ?photo = http://www.xulplanet.com/ndeakin/images/t/canal.jpg) (?start = http://www.xulplanet.com/rdf/myphotos, ?photo = http://www.xulplanet.com/ndeakin/images/t/obelisk.jpg)
So four possible results are available, one from the first rule and three from the second. However, the example shows that only content for three results are generated. What happened to the fourth result?
This is where the useful aspect of multiple rules comes in. Note that two of the results above are actually for the same photo (canal.jpg). The template builder removes any duplicate items before generating content. It does this by only allowing the match for the earliest rule. That is, the canal.jpg generated by the second rule is removed, since an earlier rule (the first rule) already generated a match for that result.
One important distinction is that the determination of duplicates is only based on the member variable, in this case the ?photo variable. It doesn't matter whether other variables are the same or not.
If you look at the example again, you might notice that the canal photo that matches the first rule has appeared in-between the other two photos, even though those photos are generated from the second rule. The builder hasn't put all the matches for the first rule before the matches for the second rule. In fact, the order is the same as the examples that only use one rule. Compare the multiple rule example with an earlier example that used only a single rule. The photos have appeared in the same order in both cases.
This is because the builder notices that the photos are in an RDF Seq in the datasource and arranges them in the order they appear in the Seq. This and other automated sorting done by the template builder is a fairly complicated process that will be discussed in more detail later.