The simple rule syntax supports two special conditional tests that are commonly used with multiple rules. The first of these tests can be used to test if an element is a container or not. To use this test, place an iscontainer attribute on a <rule>. The iscontainer attribute should be set to true if you only want to match containers, and false if you only want to match non-containers. A container is an RDF container such as a Seq.
The iscontainer attribute makes it easier to handle recursive content since you can have one rule for all containers and another rule for all non-containers. You don't need to match by type or some other predicate. This allows you to recurse down to larger levels without needing additional rules. It is commonly used with menus, and we can rewrite the previous example using the iscontainer attribute instead.
<button label="Houses in my Neighbourhood" type="menu" datasources="template-guide-streets.rdf" ref="http://www.xulplanet.com/rdf/myneighbourhood"> <template> <rule iscontainer="true"> <menupopup> <menu uri="rdf:*" label="rdf:http://purl.org/dc/elements/1.1/title"/> </menupopup> </rule> <rule> <menupopup> <menuitem uri="rdf:*" label="rdf:http://www.xulplanet.com/rdf/address"/> </menupopup> </rule> </template> </button>
The only difference in the code in this example is that the order of the rules has been switched around, the condition check for house has been removed and the iscontainer attribute has been added. Since the iscontainer attribute is set to true, the rule will match as long as the member value or child of the starting node is an RDF container. We could also have left the rules in the original order and set the iscontainer on the first rule to false. The only thing we need to make sure is that the rules are in the proper order, so that the right data will be matched by the right rule. Remember, the more specific rules should go before less specific rules.
Note that leaving out the iscontainer attribute is not the same as setting it to either true or false. If you don't use the iscontainer attribute, the rule will match regardless of whether the node is a container or not.
The iscontainer attribute will also match containers appropriately if you have used the containment attribute in the template to change the predicates that indicate containership. If the node has one of the predicates listed in the containment attribute pointing out of it, it will also be considered to be a container. For instance, we might add the following to the previous example:
<button label="Houses in my Neighbourhood" type="menu" datasources="template-guide-streets.rdf" containment="http://www.xulplanet.com/rdf/address" ref="http://www.xulplanet.com/rdf/myneighbourhood">
The houses do have a value for the "http://www.xulplanet.com/rdf/address" predicate, so they will also be considered to be containers as well, resulting in another level of menus. Of course, we will need to update the predicates and labels to retrieve the right data. But this example demonstrates that something different is indeed happening.
The second special condition attribute tests for empty containers. This invloves setting the isempty attribute on a rule to either true or false. Setting it to true will match all empty containers, that is, containers with no children. Setting it to false will match all containers that have at least one child. Leaving out the isempty attribute will match anything. This condition test is commonly used to display the generated content differently for empty and non-empty containers.
You will commonly use the two attributes iscontainer and isempty together in different combinations to create the effect you need. Typically, this will mean one rule for a container with children, a second rule for empty containers, and a third rule for non-containers. Considering the case of bookmarks, the first two rules would match folders, while the third rule would match bookmarks. Naturally, the emptiness test does not apply to nodes that are not containers.
Note that both the iscontainer and isempty attributes are only available for rules that use the simple syntax.