Reference - Template Tags
Here you find the descriptions of all XML tags you can use in a template file. Most of the tag and attribute names are taken from XSLT, but I hope the XML dialect for apertoGenerator templates is easier to learn and to use - there are only 10 tags:
<templates>
This is the root tag for a template file, because one template file can contain multiple templates.
-
Valid child elements:
- <template>
<template>
Defines a template. There are two types of templates: match templates and named templates. For a match template the syntax is:
<template match="..." file="..." [mode="stub"]>
...
</template>
The match
attribute contains a select expression.
For each node in the model, which is selected by this expression,
the template will be expanded and the result will be written
into the file specified by the string expression
in the file
attribute. This expression must evaluate to a path,
which is relative to the destDir
of the apertoGenerator Ant task.
Normally - if the file to be generated already exists - the apertoGenerator reads all
insertCodeHere sections, expands the template, and writes
the result back into the file. (Actually, the file is not written but skipped, if there
are no changes.) Unfortunately the insertCodeHere tag
does currently only work for Java, JSP and XML files. If you want to generate other files types
(*.txt, *.html, *.xml, ...) you don't have the comfort of insertCodeHere
sections, but must choose between (1) always generate the entire file, which is done by default,
or (2) stub mode, which is used when you specify the attribute mode="stub"
. In stub
mode the apertoGenerator checks, if the file to be generated already exists. If not,
the template is expanded and the file is created. But if it already exists, the file
is not touched at all.
If the template is expanded, the node for which the template is expanded (one of the
nodes selected by the expression in the match
attribute) is the so called
current node, when an expression in the
template body is evaluated.
You can also define a named template like this:
<template name="...">
...
</template>
A named template is somewhat like a function in a program. It can be called from different locations.
-
Valid child elements:
- Text with expressions
- <expand>
- <var>
- <foreach>
- <if>
- <insertCodeHere>
- <error>
<expand>
With the expand
tag you can expand a named template like this:
<expand name="..." />
This is somewhat like to call a function in a program. The value of the name attribute is of course the name of the template you want to expand.
Valid child elements: none.
<var>
The var
tag is used to define variables like this:
<var name="..." value="..." [scope="global"] />
The value of the name
attribute is the name of the
variable. The value of the value
attribute is an
arbitrary expression.
After you have definied the variable, you can refer to it in an expression by its name.
The default scope of a variable is local to the current
template including all nested template tags. But if you define
the attribute scope="global"
, the variable becomes
globally visible.
Unlike XSLT, you can change the value of an existing variable.
Valid child elements: none.
<foreach>
The foreach
tag is used to loop through a set
of nodes of your model and can be either used like this:
<foreach select="..." expand="..." />
or like this:
<foreach select="...">
...
</foreach>
The select
attribute must always contain a
select expression, which
selects the node set to loop over.
If also the expand
attribute is given, the
template with the specified name is expanded for each
selected node. If no expand
attribute is given,
the body of the foreach
is interpreted as a
template, which is expanded for each selected node.
Note, that the foreach
tag is the only template
tag, which changes the current node for expression evaluation.
Valid child elements: none, if the expand
attribute
is used, otherwise the same as for the template tag.
<if>, <elseif>, <else>
With these tags you can expand a template based in a condition. The Syntax is like follows:
<if test="..." expand="..." />
<elseif test="..."> ... </elseif>
<else> ... </else>
The test
attribute must always contain a
boolean expression.
There can be as many elseif
tags as you like. All three
tags can either have an expand
attribute, which must
be the name of the template to expand. If no expand
attribute is given, the body of the tag is interpreted as the
template to expand.
Valid child elements: none, if the expand
attribute
is used, otherwise the same as for the template tag.
<insertCodeHere>
The Syntax of the insertCodeHere
tag is as follows:
<insertCodeHere [id="..."] />
The insertCodeHere
tags acts as a place holder and inserts
a so called insert code section in the generated file, which
looks like this:
// -------- You can insert code here: --------
...
// -------- End of insert code section --------
(If you scroll the generated file in your editor far enough to the right,
you will also see an id to identify the insert code section.) This tag
does currently only work when generating *.java files. Normally you
don't have to specify the id
attribute in your templates, but
sometimes this leads to ambigous insert code section ids like in the
following example:
void ${setterName()}(String value) {
boolean isValueValid = true;
<insertCodeHere>
// Add validity checks here.
</insertCodeHere>
if (isValueValid) {
_${varName()} = value;
<insertCodeHere>
// Add additional actions here.
</insertCodeHere>
} else {
...
}
}
Here the two insert code sections can neither be differentiated by their
position in the XML template structure, nor by the current node. To eliminate
the ambiguity, you need to add at least one id
attribute to one
of the insertCodeHere
tags:
void ${setterName()}(String value) {
boolean isValueValid = true;
<insertCodeHere id="validity checks">
// Add validity checks here.
</insertCodeHere>
if (isValueValid) {
_${varName()} = value;
<insertCodeHere>
// Add additional actions here.
</insertCodeHere>
} else {
...
}
}
If the generated file does not yet exist and is therefore created
by the apertoGenerator, the body of the insertCodeHere
tag
is interpreted as a template and expanded. But if the generated file
already exists, all insert code sections are first read, then the
match template to generate the file is expanded, whereby for all
encountered insertCodeHere
tags the insert code sections
previously read are inserted into the expanded text.
If insert code sections were read, which have not been reinserted during template expansion, the apertoGenerator exists with an error message, so no code is lost. If you experience this behaviour, you probably have changed a template. Just make a backup copy of the file, let the apertoGenerator generate the fiel anew, and then merge your insert code sections into this file again.
Valid child elements: the same as for the template tag.
<error>
If the apertoGenerator encounters an error
tag during the
expansion of a template, it exists with an error. Here is an example:
<if test="type == 'int'> ... </if>
<elseif test="type == 'String'> ... </elseif>
<else>
<error message="Unsupported type ${type}." />
</else>
Valid child elements: none.