Multiple Rule Example

The most common use of multiple rules is to apply different action bodies to different results. Often this will be because a particular result has a property that others do not. For instance, in an earlier example, one of the photos had a description and the other photos did not. In this case, you might wish to display the photo with a description in a different manner. This is useful if you wish to hide any content that would be needed to display the description.

The next example shows how we can do this.

<vbox id="photosList" align="start" datasources="template-guide-photos5.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="?title"/>
        <triple subject="?photo"
                predicate="http://purl.org/dc/elements/1.1/description"
                object="?description"/>
        <triple subject="?photo"
                predicate="http://purl.org/dc/elements/1.1/date"
                object="?date"/>
      </conditions>
      <action>
        <hbox uri="?photo" class="box-padded">
          <vbox>
            <label value="?title"/>
            <image src="?photo"/>
          </vbox>
          <groupbox>
            <caption label="Photo Details"/>
            <label value="?description"/>
            <label value="Date: ?date"/>
          </groupbox>
        </hbox>
      </action>
    </rule>
    <rule>
      <conditions>
        <content uri="?start"/>
        <member container="?start" child="?photo"/>
        <triple subject="?photo"
                predicate="http://purl.org/dc/elements/1.1/title"
                object="?phototitle"/>
      </conditions>
      <action>
        <vbox uri="?photo" class="box-padded">
          <label value="?phototitle"/>
          <image src="?photo"/>
        </vbox>
      </action>
    </rule>
  </template>
</vbox>

In this example, the first rule matches only those photos with title, description, and date properties. The second rule matches those photos with a title. If a photo did not have a title, it would not match any rule. In the example data, only the first photo has been given all the properties to match the first rule. The second photo has a title and date but no description, while the third photo has only a title. The first photo will match both rules whereas the other two photos will match only the second rule. The resulting data will be:

(?start = http://www.xulplanet.com/rdf/myphotos,
 ?photo = http://www.xulplanet.com/ndeakin/images/t/palace.jpg,
 ?title = Palace from Above
 ?description = View from the top of the tower looking east of the Doges Palace,
 ?date = 2005-04-30T14:55:00+01.00)
(?start = http://www.xulplanet.com/rdf/myphotos,
 ?photo = http://www.xulplanet.com/ndeakin/images/t/palace.jpg,
 ?phototitle = Palace from Above)
(?start = http://www.xulplanet.com/rdf/myphotos,
 ?photo = http://www.xulplanet.com/ndeakin/images/t/canal.jpg,
 ?phototitle = Canal)
(?start = http://www.xulplanet.com/rdf/myphotos,
 ?photo = http://www.xulplanet.com/ndeakin/images/t/obelisk.jpg,
 ?phototitle = Obelisk)

The first result matches the first rule and contains variables for the two additional predicates that were examined in the conditions. Since the second rule doesn't refer to these variables, they will not be filled in. Although the canal photo has a date, the second rule doesn't use it, so you cannot refer to the ?date variable in this rule. But, you could use a <binding> to get the date without requiring it to match the conditions. Of course, the variable doesn't have to be ?date in the second rule.

You might notice that the ?title variable is used in the first rule whereas the ?phototitle variable is used for the second rule, despite that they both store the value of the title predicate. There is no reason for this -- it is only used in this example to show that there is no connection between the variables used in the two rules. You can use different variables if it makes sense in the context of the template or the data, although in this example it would seem more reasonable to use the same variable name.

The only exception to this is that the container and member variables (those that are referred to in the uri attributes), must be the same in all rules. In this example, the container variable is ?start and the member variable is ?photo. If different variables were used for these, the rules would not work properly. The reason for this is due to the manner in which the builder processes the data.

Looking back at the results listed above, the palace photo appears twice so the second one will be removed, leaving only three matches. Although the builder actually generates mutliple matches for one resource, in many cases it isn't necessary to be aware of this detail when creating templates. It is usually sufficient to assume that earlier rules are used to filter results much like an if-else construct in a programming language. If the last rule has no specific conditions (for example a simple rule with no attributes on the <rule> element), it could be considered to be the final else block that matches all data.

Since results generated by earlier rules override those of later results, you will want to ensure that the rules are placed in the right order. The rules should be ordered from most specific to least specific. If you reversed the order of the two rules in the example above, three photos would still be displayed, but the larger rule that displays the image details would be dropped as the other rule has a higher priority. The result would be that the palace photo would not show this information.