So far, attribute replacement in an action body has been used to replace an entire attribute with the value of a variable. However, you may also replace only part of attribute's value, or use multiple variables in one attribute. For instance, to include a prefix before a variable value, you can use:

<label value="My name is ?name"/>

The effect will be that the ?name part of the attribute will be replaced by the value of the variable ?name. For instance, if the value of ?name is 'Jake', then the attribute value will be 'My name is Jake'. You can include multiple variables in one attribute if desired:

<label value="My name is ?name and my age is ?age"/>

This technique will work for any variable replacement in the action body, except for the uri attribute since that wouldn't be meaningful. Note that variable names must have a space after them as this is how the end of the variable is determined. That is, '?name?age' is considered to be a single variable with that name, not two variables together. To use two variables, place a space between them. It is sometimes useful though, to concatenate two values together without a space. This can be done by putting two variables next to each other in an attribute value separated by a caret (^).

<label value="?name" class="?gender^?nationality"/>

The caret is considered a separator between variables, however it will not appear in the output. It can also be used to separate a variable with normal text:

<label value="?name" class="?gender^german"/>

These last two examples have been setting the class attribute on a label. The effect will be that a label will have either the 'malegerman' or 'femalegerman' class. In a stylesheet, you could set properties for each of these classes such that different values appear differently without having to use multiple rules.

Although not common, you may also wish to insert a question mark or a caret into an attribute value. To do this, just use two question marks or two carets in a row. For instance:

<label value="What is my name?? My name is ?name"/>

In this example, the label might be 'What is my name? My name is Jake'. Note that a caret only has a special meaning at the end of a variable, thus two in a row are only needed after a variable.

One last thing to point out is that since the only characters that can separate a variable are a caret, a space or the end of the attribute, this means that any other character is valid as a variable name. However, for readability, you should restrict variable names to letters, numbers and perhaps hyphens to separate words.

The description added in the last example might be a long string of text for some of the photos. It may be desirable to have the text wrap by placing it inside a <description> element. This means that we want to do variable replacement as text, not as an attribute value. A special tag is used for this purpose, the <textnode> tag. It has one attribute, the value attribute, which may use variable substitution like other attributes. However, the <textnode> element is not copied into the generated content, but instead a DOM text node is created with the value of the value attribute as its contents. For instance, if the template contained:

<description><textnode value="?description"/></description>

The resulting generated content might be:

<description>View from the top of the tower looking east of the Doges Palace</description>

Note that the <textnode> has been replaced with the substituted value attribute. Unfortunately, a bug can make this appear to not work at times. Recall that the template builder doesn't load the datasource before processing a template. As the datasource loads, the rules are examined with the new data as it arrives. This causes rules to create matches as the data loads. However, variables determined from a binding are evaluated using a much simpler process. The bug is that this code path for bindings doesn't handle the textnode element properly. Thus, if you use a variable set in a binding, you must ensure the datasource is loaded before the template is built, or just rebuild the template. Another possibilty is to rearrange the RDF such that the values, in this example, the descriptions, are specified before the containers. This may seem a bit confusing, but hopefully, this bug, if you do encounter it, should be fixed soon.