Contents
- Contents
- Overview
- Template text = literal text with expressions embedded
- Warning about expression delimiters
- Examples
- Where might you be dealing with template texts?
- Simple templates
- Templates defined in a string template group file
- Expressions Overview
- Template Expressions and Statements
- Documentation conventions
- Symbol guide
- Table of Template Expressions and Statements
- Summary of expression options
- More template details
- Supplying attributes, revisited
- Simple String value
- Simple non-String value
- List of strings
- Aggregate type
- Aggregate built by addAttribute()
- Map
- Remaining murky areas
Overview
This article attempts to cover and update (2009-06) all the material in the users guide Expressions article and the current Cheat-Sheet's Expressions section.
Template text = literal text with expressions embedded
Template text is a string of literal text, with expressions embedded in it.
Warning about expression delimiters
StringTemplate can recognize a choice of different delimiters around expressions, with $...$ and <...> being the two built-in alternatives. (The choice must be set by the calling program before invoking a template.)
Be aware that documentation might show examples with either expression delimiter, $...$ or <...>.
Examples
Example template text with $..$ expression delimiters:
Example template text with <..> expression delimiters:
Where might you be dealing with template texts?
The same template text might come into play in several different places in an application that uses the StringTemplate library:
- As a String in the calling language: Your application might create the template text as a string, and pass it to one of the StringTemplate constructors or StringTemplateGroup methods that create a StringTemplate.
- *In a template file:* You might provide templates in individual xxx.st files. The filename (minus ".st") provides the template name.
- *In a template group file:* You might provide one or more xxx.stg files, which can define several templates. The template definitions in stg files use the same syntax for the template text per se, but add additional surrounding syntax to provide the template a name, and to declare formal arguments.
- Within a template expression: The expression syntax includes the capability to define and invoke a (usually small) template on-the-spot within an expression. Once again the same syntax is used within the template text itself, but there is additional expression syntax around it, including the ability to specify arguments.
Simple templates
The following example illustrates a couple of simple templates. Note use of alternative expression delimiters.
| Example: Apply html bold-italic to a string |
Example Format personal info |
|
|---|---|---|
| Template text: |
|
|
| Attributes supplied: |
sometext = "Hello" |
personname = "Fred Smith" addr = "123 First St." phonenum = "123-4567" |
| Result from toString() |
<b><i>Hello</i><b> | Name: Fred Smith Address: 123 First St. Phone: 123-4567 |
The template texts shown here could be provided as a string when creating a StringTemplate calling a StringTemplate constructor. Alternatively, the template text could be provided from a file, perhaps bold-italic.st, or personalinfo.st, for the examples here.
Templates defined in a string template group file
This example shows a snippet from a string template group file (xxx.stg). It's the definition of a template called personalinfo(), which has the same template text as the preceding example, but declares three formal arguments.
Expressions Overview
The basic idea
It is possible to create very elaborate expressions, but at heart an expression has the following basic structure.

There are three basic parts, and they are all optional. This next figure details the inputs and outputs of each or the three parts of the expression.
!stc_tmpexprn_02.gif!In broad terms, the parts do the following:
- Prep value(s): If present, this section provides various ways to specify how to select or assemble a string, list of strings, or multiple parallel lists of strings.
- Template(s): If present, this section is where you specify one or more templates. If there was a Prep values section, then the template(s) will be applied to the values marshalled there. The template(s) can also refer directly to attributes available in the surrounding template context.
- Options: The result of a template is always a string. After the processing of the Prep values and templates sections, the outcome should be a string or list of strings. The final stage is to "render" that into a final string. If the template output is a list of strings, then these must be catenated, for example. In the options section you can list various treatments that should be applied during the preparation of that final string, such as a separator string to use during catenation.
The following section summarizes the variations available for each of the three sections of the expression.
Variations for each part of an expression
Before giving the actual syntax in detail, it's helpful to have a preview of what can be accomplished with each part of the expression.
| Prep value(s) part |
Template(s) part |
Options part |
|---|---|---|
|
|
Mostly controls formatting of the final rendering of the template to produce a String.
|
Examples
[include html]
Template Expressions and Statements
Documentation conventions
One of the significant challenges in describing syntax is to clearly distinguish between the following:
- Parts of the syntax you type in verbatim. These are in typewriter font, non-italic ("upright").
- Parts that are to be replaced by your own attribute names and so on. These are in italic typewriter font.
- Almost no symbolsthat are not part of the syntax. (Some authors might use square brackets to indicate optional syntax, for example). The only such syntax on this page is the elipsis "...", used to indicate "fill in the usual stuff here". (Except where the elipsis is actually part of expression syntax, which is clearly noted.)
Symbol guide
| Symbol |
Meaning |
Symbol |
Meaning |
|
|---|---|---|---|---|
| attrname | Attribute name |
tmpname |
Name of a template to be called from this one (defined elsewhere in the current template's group) |
|
| expr |
An expression |
argname |
Name of an argument of a template to be called from this one |
|
| propname |
Name of a property of an attribute |
args |
Shorthand for argname=expr, argname2=expr2 |
|
| mapname |
Name of a map |
tmptext |
Text of a template defined within an expression "on-the-spot" ("Anonymous" template.) |
|
| itemname |
Name of an item in a map |
Table of Template Expressions and Statements
Wiki note: The following table is included from a separate html file as the many collisions between StringTemplate expression syntax and wiki markup syntax make editing in the wiki impractical.
| Syntax | Description |
|---|---|
| Attributes | |
| <attrname> | Insert the string value of the attribute named attrname |
| <attrname> | If attrname is an attribute with multiple values, then insert the
concatenation of these strings. |
| <attrname; separator=expr> | (Semicolon: delimiter before specifying options.) If attrname is an attribute with multiple values, then insert the concatenation of these strings separated by separator. |
| <attrname; format=expr> | When invoking a StringTemplate equipped with a FormatRenderer, the tempate
expression can pass a string argument to it (here expr), using the options part of the overall
expression. Multiple options can be provide, separated by comma, example: <attrname; format="toUpper",separator=" and "> |
| <attrname.propname> |
Dot = select property of attribute Tells StringTemplate to look for property called propname on the variable that was supplied for attrname, and insert its string value here. |
| <attrname.(expr)> | (expr) = indirection Same as <attrname.propname>, except first evaluate expr to calculate propname. |
| <[attrname1,attrname2]> | Square brackets: Make a list that combines the single or multiple values of attributes attrname1 and attrname2. Such a list can be used wherever a multi-valued attrname can be used, in the syntax below. |
| Invoke template | |
| <tmpname()> | ( ) means this is a template. Invoke template named tmpname, without args. Insert resulting string. |
| <tmpname(argname=expr, argname=expr)> | Invoke template named tmpname, with arguments. Insert resulting string.
-- argname refers to an argument of the called template (which in turn should match some attrname in an expression in the called template's text. -- expr can be any expression that makes sense in the context of the enclosing (ie: current) template. Note that an expression does not need to be delimited if it's inside an expression. So: Correct: <mytemplate(somearg=someattr)> Incorrect: <mytemplate(somearg=<someattr>)> |
| <tmpname(...)> | Elipses (three periods). The "..." syntax in the argument list says that template tmpname should obtain all argument values from the same-named values in the current template. (This overcomes the normal behavior of <tmpname()>, where any declared arguments of tmpname block tmpname's expressions from seeing the same-named values in the calling template.) Note: This is the only place in StringTemplate expressions that "..." is used as actual syntax. Elsewhere in this documentation, "..." stands for additional items that you fill in as you wish. |
| <tmpname(argname1=expr,...)> | Similar to preceding, but here a value for argument argname1 is provided explicitly, and the remaining arguments are "passed through". |
| In the following: Use args to represent argname=expr,argname2=expr2... (optionally empty) | |
| <(expr)(args)> | Template invocation, but first evaluate expr to calculate tmpname template name |
| Invoke template and apply it to an attribute | In the following expressions, a template is applied to an attribute. Where the attribute has multiple values, the template is invoked multiple times, each time with the next value from attribute. The final result is the list of output strings catenated together into a single string. |
| <i>, <i0> and <it> | Each time the template is applied, the value of the attribute for this iteration is made available in the invoked template through the built-in expression <it>. The invoked template can see the number of the iteration in the built-in expressions <i> (counting from 1) and <i0> (counting from zero). |
| <attrname:tmpname(args)> |
Colon: apply template to attribute. If the attribute has multiple values, invoke template tmpname once for each value. Within template tempname, the value of attrname
can be obtained using <it>. Special shorthand case: If template tmpname declares exactly one formal argument, and that template is invoked without arguments like this: <attrname:tmpname()> then StringTemplate will assign the attribute value to both <it> and that single argument. |
| <attrname:(expr)(args)> | Same as preceding, but first evaluate (expr) to calculate name of template. Eg: This could obtain template name from an attribute. |
| <attrname:tmpname(args); null="xxx"> | Semicolon: delimiter beginning one or more options. Here the option is the null option which provides a string (or expression) to return if attribute attrname is null. (Default result would be null string.) |
| <attrname:tmp1name(args):tmp2name(args)... | Colon. Apply each template in sequence left to right. In the leftmost template, the value of the attribute can be accessed using <it>. Each successive template can use <it> to access the result so far. If the attribute has multiple values, then each template passes a multi-value result to the next template, and finally to the result of this expression where it is catenated into a single string. |
| Define a subtemplate on-the-spot in an expression ("anonymous" template) and possibly apply it to an attribute | |
| <...{tmptext}...> | Braces: define template, returning a string. In general, an on-the-spot ("anonymous") template can be placed anywhere that an expression can appear: in this article, substituting for (expr). |
| <attrname:{tmptext}> | Invoke the "anonymous" template defined by tmptext to attribute attrname. If the attribute is multivalued, then invoke tmptext once for each value. Within tmptext, use <i>, <i0> and <it> as described above. |
| <{attrname:{argname | tmptext}> | Invoke anonymous template (defined by tmptext) for each value of multi-valued attribute attrname. On each invocation, the value of attribute attrname is given to argname. Expressions within tmptext can refer to that value either using <argname> or <it>. |
| <attrname,attrname2:{argname,argname2 | tmptext} > | "Parallel list iteration". Similar to the preceding, except two (or more)
attributes are used for input, whose values on each iteration are given to the corresponding
arguments: attrname-->argname, attrname2-->argname2, and so on. This syntax can be extended to three or more attributes and
arguments. Having multiple arguments, this syntax does not define an <it> attribute. (However, if the surrounding context has an <it> attribute then it can be accessed within tmptext). |
| <attrname:tmp1name(),tmp2name()...etc | Comma: Apply only one template from the list of templates, alternatingly for the multi values of attrname. First iteration invokes template tmp1name, second iteration invokes template temp2name and so on, wrapping around as many times as needed. |
| Operators | |
| <first(attrname)> | Returns the first (or only) element in this multi-valued attribute |
| <last(attrname)> | Returns the last (or only) element in this multi-valued attribute |
| <rest(attrname)> | All but the first element of attribute attrname. Returns nothing if <attr> a
single valued. You can combine operations to say things like: first(rest(names)) to get second element. |
| <trunc(attrname)> | All but the last element of attribute attrname. |
| <strip(attrname)> | Returns all elements that are non-null in attribute attrname. |
| <length(attrname)> | Returns count of of elements in attribute attrname. Use length(strip(list)) to
get count on non-null elements. (Note: this length function does NOT return the character-count length of a string.) |
| <...expr1+expr2...> | Plus: catenate two strings. Terence says he prefers the alternative of using a
subtemplate: <...{<expr1><expr2>}...> |
| Escapes | |
| \$ or \< | Whichever delimiter the template is using, if the template needs to use that character literally it can be escaped to avoid incorrect parsing. |
| <\ >, <\n>, <\t>, <\r> | These expressions can be used for space, newline, tab and carriage-return. More than one of these can appear in a single <...> expression. |
| <\uXXXX> | This expression can place a specific unicode character into the template. Example: <\u1234>. More than one of these can appear in a single <...> expression. |
| Comment | |
| <! lorem !> or $! lorem !$ | Comments, ignored by StringTemplate. |
| ______________________________________ | |
Summary of expression options
The following table summarizes options that may be placed in an expression, following a semicolon:
<blahblah;option1,option2>. Example: <SomeAttrib;separator=", ", null="blank">
| Option |
Description |
|---|---|
| separator="sep" | If multi-values are emitted from this expression, catenate them with separator between |
| format="formatstr" | String to pass to an AttributeRenderer as an argument specifying format details. (Specific formatstr strings are determined by whatever is recognized by the particular renderer.) |
| null="somestr" | For each null element in the input attribute, emit this string for output. |
| wrap | Tell StringTemplate to wrap the output string if it exceeds the wrap length set in StringTemplate.toString(wraplen);. (Note, no "=true", just the keyword wrap by itself.) |
| anchor="true" | If wrapping, then cause wrapped lines to indent so that they align with beginning of the first line of this template's output. |
More template details
Template calling behavior
The syntax for defining a template in a string template group file might suggest that when one template invokes another, data is passed only via the arguments, like calling a function in other languages such as Java. However this is misleading.
In actuality, when one template invokes another, StringTemplate passes the context of the caller to the called template. That is to say, not only does the called template get its arguments "filled in", but also the called template's expressions can see and refer to the attributes or arguments that are in the scope of the caller template. This behavior is much more like C macros, or like closures in some other languages.
User guide article Template and attribute lookup rules has the details, but in summary, StringTemplate follows the order below in resolving attribute names in expressions:
- Look in this template's attribute table (applies if template is invoked directly by program code).
- Look in this template's arguments (applies if template is invoked by another template.)
- Look recursively up the chain of this template's calling templates for arguments/attributes that match
- Look recursively up the chain of this template's group / supergroup inheritance chain for a map
A further wrinkle is that a template's argument list normally "hides" any attribute or argument of the same name in the caller template's scope. For variations on how to subvert this, see the "..." expression syntax, and also StringTemplate.setPassThroughAttributes().
String Formatting
StringTemplate provides no built-in string formatting functions per se, such as string truncate, or left/right pad, or number formatting. Instead, the application must provide data to an attribute as an already-formatted string, or the calling program can attach AttributeRenderer objects to
to determine what formatting capabilites to offer to the template world. This is done through the AttributeRenderer features. An application may attach AttributeRenderers to a StringTemplate which apply to specific classes of objects. When such an object of such a class is supplied as an attribute to a StringTemplate, the related AttributeRenderer will be invoked when the template gets rendered.
AttributeRenderers may be designed to accept arguments from the template expression: The template expression provides these through the format option. (See Expression sytax table).
The AttributeRenderer for the String type is special: This will be invoked not just for String attributes, but also for expressions that result in a string. As a consequence, you can create and attach an AttributeRenderer which provides generally-useful string functions. (Someone should write a how-to on this. There's an example in John Snyder's STST.)
Supplying attributes, revisited
When a template is prepared by an application, part of the process involves supplying Attributes (named values) using the StringTemplate.setAttribute() method (or related). There are several variants on that procedure, detailed here.
Simple String value
Example
Simple non-String value
Example
List of strings
Example
Aggregate type
An object with multiple fields (properties) can be passed as an attribute.
Aggregate built by addAttribute()
If you want to present data to setAttribute in a structure, but don't already have a suitable aggregate data type, then you can create one in the call to setAttribute, like the following example. This shows how to set multiple properties at once. The values supplied here are string constants, but variables can be supplied too.
Map
Another type of attribute value your program can supply is an object that implements the Map interface. Example:
Remaining murky areas
Distinction/Overlap between Attribute and Argument
"Attribute" seems to refer primarily to named objects passed to a template via StringTemplate.setAttribute(attribname, object-from-program), which an expression can either reference as a named value, or as an object from which to get the value of a property. When used with a template defined in an stg file, the attribute gets passed through declared formal arguments (only), and attribname must match the argname declared by the template.
But then when a template invokes another template it provides an expression or literal string as an argument. Relative to the called template, is that rightly called an attribute or an argument? Is there some important distinction here?