Table of Contents
| Combined on this page | Individual topic pages |
|---|---|
Introduction
This series of "ST condensed" articles is aimed at providing a collection of information about StringTemplate that is substantially complete in its coverage of features, and coherent and current, while also being compact. "Current" means as of this writing, StringTemplate version 3.2, May 2009.
The hope is to have at least mentioned all important topics and how they fit together. These articles may then serve as an initial map of the whole territory, and also as a reference to many of the oft-needed details. However, for more extensive discussions of the whys and wherefores, please refer to the lengthier users' guide articles, starting here: StringTemplate 3 Documentation .
Note on Java
All the examples of application code (calling StringTemplate) are written in Java. Unlike the users' guide, I have not gone to the lengths of including examples in Python or C# as this series of articles is more focused on just bringing attention to features of StringTemplate, rather than covering every language.
The Basic Idea
The StringTemplate library eases the task of composing some possibly complex text from an application's data. The inputs to the process are some template text in which are embedded expressions understood by StringTemplate, plus some attribute values supplied by the program for a particular invocation of the template.

- Application creates a StringTemplate object, and provides the text of a template (from string or file).
- Application sets template attributes and their values.
- Application invokes StringTemplate's toString to get the result of merging the attributes into the template.
A special focus of StringTemplate is the maintaining of a strict separation of concerns between your application's (data) model and the view created via the StringTemplate apparatus. You can read the rationales behind StringTemplate's design and feature set in this paper: Enforcing Model-View Separation in Template Engines
Preview of The Details
The remainder of the story involves two main elaborations of the template idea:
- Features relating to use and management of a large number of possibly complicated and inter-related templates.
- Features of the template expression "language" which facilitate the insertion of data into the template in various ways.
The next article in the series, ST condensed -- Key topics, provides an overview of the features of the StringTemplate world. Subsequent articles detail the topics of managing templates, the template expression language, and then other subsidiary subjects.
Finally, there are annotated versions of the javadocs for two of the key classes: StringTemplate and StringTemplateGroup, drawing attention to and commenting upon the main methods of interest.
Comment
The information here is based on the author's reading of the existing documentation, and to a certain extent the javadocs and the source code. The author has not been involved in actual development of StringTemplate, and quite possibly has misinterpreted some feature or other or made actual mistakes! Feel free to update points that are incorrect, or add comments. Possibly at some point ideas from this document might be used to revisit the older StringTemplate user guide documents.
Next: ST condensed -- Key topics
Studying StringTemplate: Key topics of interests
The following bullet points touch on most of the main features of templates. The details for all these topics are to be found in subsequent articles of this series.
- Templates and Expressions
- A template has a Template text or body
- Template text = literal text (to be output verbatim) alternating with expressions (to be processed to generate text to insert)
- To distinguish expressions within the template text, they are marked off by expression delimiter characters.
- You can set the delimiters to be either $...$ or <...> depending on which is most distinct from the surrounding literal text. (Each StringTemplate or StringTemplateGroup constructor sets a particular default for expression delimiter, which can be overridden in various ways. See later details.)
- IMPORTANT: StringTemplate documentation examples may show either delimiter. Avoid mistakenly thinking that these mean different things. They are equivalent.
- StringTemplate class (and objects)
- Encapsulates preparation and processing of templates
- Your program provides template text to a StringTemplate object
- from a String, or...
- loaded from a stream or file (from a template file xxx.st, or from a template group file, see below).
- Your program provides values to the StringTemplate object by way of named attributes
- During processing of a StringTemplate, eg: myStringTemplate.toString():
- Literal text within the template text is copied verbatim to the result, interspersed with expression results.
- Expressions within the template text obtain their values by name from the StringTemplate's list of attributes (which your program provided), and produce string results to be inserted in the template's result text.
- Expressions can also refer to other templates:
- subtemplates defined on-the-spot in expressions in the current template
- named templates defined elsewhere and belonging to the same template group
- A template has a Template text or body
- Template Groups
- StringTemplateGroup class (and objects)
- Encapsulates preparation and processing of a group of named templates whose expressions can invoke by name other templates belonging to the group
- Though your program could invoke directly a StringTemplate from a group, instead usually your program would treat a template group like a library of templates:
- make an instance of a desired template from the template group, and provide that with the attributes (values) for this specific invocation.
- Can be created with settings to get templates from:
- A template group directory containing individual template files: xxx.st
- A Reader object, which reads
- A template group file: xxx.stg, or...
- A String containing text in the same sytax as an stg file.
- StringTemplateGroup class (and objects)
- Three slightly different modes of operation
- Different modes involve more or less features relating to managing multiple templates, and complex relationship between templates.
- Depending on mode, features include:
- Formal arguments: template definitions can include declaration of arguments. (stg files only)
- Template group inheritance and interface feature
- Inheritance: A StringTemplateGroup can have an inheritance relationship with another group ("Supergroup"). The subgroup acts as though it contains all the features of the supergroup, and can provide overrides only for features that need to be different.
- Interfaces: A StringTemplateGroup file can provide an interface definition which other StringTemplateGroups can commit to implement.
Look for an elaboration on all of these features in subsequent articles in this series.
Next: ST condensed -- Templates and groups
Contents
- Contents
- Overview
- Three modes of operation
- Single-template mode
- Template-group- directory mode: many *.st files
- Template-group- file mode: *.stg file(s)
- Mixing modes
- Preparation and Invocation in each mode
- Single-template mode
- Template-group- directory mode: *.st files
- Template-group- file mode: *.stg file(s)
- Examples: Single template mode
- Single template from string
- Use an alternative expression delimiter
- Single template from string, and use an instance
- Single template from file
- Simple template with multi-valued attribute
- Examples: Template-group- directory mode
- Insantiate and use a template from a group of files in a template group directory
- Adding a named template from a string
- Group directories with inheritance
- Examples: Template-group- file mode
Overview
The StringTemplate library can be usefully applied in a range of more or less elaborate ways. At the modest end of the spectrum, an application program might just use StringTemplate as part of a structured process to insert a few values into short templates, in turn producing short output strings. The template texts might be provided as strings in the program itself, with no template files involved. At a grander scale, an application defining famiies of related web pages might use dozens of lengthy templates, stored as a group of files in a directory. Alternatively a code generator application might employ template-group files that each define a set of templates, with separate group files for different target languages.
In support of this variety of use cases, StringTemplate has features aligned to three somewhat distinct modes of operation.
Three modes of operation
Objects of the StringTemplate and StringTemplateGroup classes can be used in three different modes of operation. Although most of StringTemplate's concepts are similar across all three modes, there is enough difference between them that it's important to be aware of the distinctions before plunging into the details. The features of the three modes are described below.
Single-template mode
In this mode you are free to define and use many templates from strings or single-template files, but each one operates independently of any others. In this mode, templates cannot refer to each other.
- Create template, supplying template text from file or string: Use one of the StringTemplate constructors
- Expression delimiters: Default is $...$. Switch to <...> by using the StringTemplate constructor that allows specifying a different lexer.
- Preparing to invoke a template
- Use the StringTemplate object returned by the constructor, OR use that template's getInstanceOf() method to make a separate copy.
- Set attributes
Template-group-directory mode: many *.st files
This mode introduces the idea of a template group, revolving around a StringTemplateGroup object. In template-group directory mode you can define many templates from a collection of single-template files housed in a distinct group directory. These templates can invoke each other to build up complex output. Other features of this mode:
- Single-template filename pattern: *.st
- Template name = name of file containing the template text (minus the ".st" extension)
- When your program explicitly calls for a particular template, StringTemplate automatically searches the group directory and loads any other templates your template references.
- Optional periodic automatic refresh of in-memory StringTemplate objects from any template files which have changed.
- Inheritance: The calling application can set up an inheritance relationship between groups, such that one group can inherit from another group, overriding the inherited templates in various ways.
- Maps: Your code can define a map, which template expressions can use to translate one set of strings to another.
Template-group-file mode: *.stg file(s)
In this mode, you can define many templates within a single template group file, and again these templates can refer to each other. (Single-template files are not involved.) Besides the convenience (for some scenarios) of defining many templates within one file, the stg file format introduces more syntax supporting more rigorous processing of templates, and more powerful relationship between template groups:
- String template group filename pattern: *.stg
- Group name: defined in initial group statement in stg file. Conventionally this would match the name of the group file (minus the .stg extension)
- Template name: Templates are named as part of the syntax in the STG file.
- No automatic refresh: If your application cares about the stg file changing on disk, then it must take explicit steps to reload the stg file when convenient.
- Template arguments: In stg files, templates are required to declare any attributes that they need to have passed to them. When a template is invoked, StringTemplate checks the template's expressions for invalid attempts to access attributes that were not declared.
- Aside: Because of "dynamic scope", expressions in templates called by other templates may also get attributes from the calling template as an alternative to arguments. See article Template and attribute lookup rules for details.
- Maps: Stg files can provide definitions for maps. Maps are useful for translating one list of strings to another.
- Inheritance: An stg file can declare that this StringTemplateGroup inherits from another StringTemplateGroup. The subgroup STG can add additional templates and maps, and can also override features inherited from the supergroup as follows:
- Override entire templates: The subgroup stg file can provide a replacement definition for a template that was defined in the supergroup.
- Override part of a template: Using the "region" feature, the supergroup can mark locations or sections of a template, and the subgroup can override just these sections
- Override a map
- Interfaces and implements: An stg file can declare itself to define an interface: A set of template definitions which provide only the template name and argument lists. Another stg file can declare itself to implement that interface, which is a commitment to provide complete templates for each of the ones defined in the interface stg.
Loading of supergroup file
In general, the calling program specifies an explicit path for the stg file to be loaded. If that stg file declares that it's based on some supergroup, then where does StringTemplate find that supergroup?
- Previously-loaded StringTemplateGroup: This means that the the calling program needs to be aware of which stg inherits from which other one, and load them in an appropriate order.
- Search and load automatically: The StringTemplate library defines an interface (StringTemplateGroupLoader) for a class that could load referenced string template group files, however no specific implementation is provided. (Is this correct? -- [GW])
Mixing modes
Though the modes were described above separately, there's some leeway to combine them. For example, it's possible to add new individual StringTemplates to a StringTemplateGroup in either of the two TemplateGroup modes, and to have that template's expressions invoke named templates that are members of the group.
Preparation and Invocation in each mode
While reading this section you may wish to consult the StringTemplate API javadocs, or the annotated version here: ST condensed -- API annotated which highlights the most-needed methods.
Single-template mode
In this mode you are free to define and use many templates from strings or single-template files, but each one operates independently of any others. Templates cannot refer to each other.
- Create StringTemplate, supplying template text from file or string: Use one of the StringTemplate constructors
- Expression delimiters: Default is $...$. Switch to <...> by using the StringTemplate constructor that allows specifying a different lexer.
- Preparing to invoke a StringTemplate
- Use the StringTemplate object returned by the constructor, OR if you want to use a template multiple times with different attributes, use StringTemplate.getInstanceOf() to get copies.
- Supply attributes (named values for the template's expressions), using StringTemplate.setAttribute
- setAttribute(attrname, value); Value can be an object of almost any class. A string, or something more complicated that has a toString method. Also it can be an aggregate object, and template expressions can read its properties.
- Multivalued attributes: Calls setAttribute multiple times for the same attrname gives the attribute a list of values. Template syntax can perform various operations on a list of values.
- Invocation: Usually using StringTemplate.toString()
Template-group-directory mode: *.st files
- Create StringTemplateGroup: Use one of the set of StringTemplateGroup constructors whose argument list starts with "name", supplying the directory path that contains the group of string-template files.
- There is also a constructor which causes the StringTemplateGroup to look for template files relative to the Java CLASSPATH.
- Expression delimiters: Default is $...$. Switch to <...> by using the StringTemplateGroup constructor that allows specifying a different lexer.
- Preparing to invoke a StringTemplate
- Usually you want to treat a StringTemplateGroup as a library of available StringTemplates, to be used possibly several times. Consequently you usually use StringTemplateGroup.getInstanceOf() to get copies of the templates for actual "filling in" with specific attributes/values.
- Supply attributes: as in Single-template mode, see above.
- Invocation: Usually using StringTemplate.toString()
Template-group-file mode: *.stg file(s)
- Create StringTemplateGroup: Use one of the set of StringTemplateGroup constructors whose argument list starts with "Reader r", supplying a FileReader object pointing to the stg file you want to load (Alternatively supply a StringReader with a String containing an stg-worth of text.)
- Caution: If inheritance or interface implementation is involved, also load the relevant supergroup and interface stg files .
- Expression delimiters: Default expression delimiter recognized by StringTemplate when reading from stg files is <...>. Switch to $...$ by using the StringTemplateGroup constructor that allows specifying a different lexer.
- Preparing to invoke a StringTemplate
- Basically, same as for the template-group-directory mode, except more-rigorous requirements on attributes.
- Usually you want to treat a StringTemplateGroup as a library of available StringTemplates, to be used possibly several times. Consequently you usually use StringTemplateGroup.getInstanceOf() to get copies of the templates for actual "filling in" with specific attributes/values.
- Supply attributes: as in Single-template mode, see above.
- Invocation: Usually using StringTemplate.toString()
Examples: Single template mode
Single template from string
| Code |
Result |
|---|---|
StringTemplate st = new StringTemplate("Hello, $name$");
st.setAttribute("name", "World");
String s = st.toString();
|
Hello, World |
- Default expression delimiter is $..$
Use an alternative expression delimiter
Single template from string, and use an instance
| Code |
Result |
|---|---|
StringTemplate st = new StringTemplate("Hello, $name$");
StringTemplate sti = st.getInstanceOf();
sti.setAttribute("name", "World");
String s = sti.toString();
|
Hello, World ... and st can be used to create more fresh instances |
Single template from file
Same as above, but use usual Java methods to load the template text from a file into a string.
Simple template with multi-valued attribute
| Code |
Result |
|---|---|
String tmpl = "Hello, $arg;separator=\", \"$";
StringTemplate st = new StringTemplate(tmpl);
st.setAttribute("arg", "One");
st.setAttribute("arg", "Two");
String s = st.toString();
|
Hello, One, Two |
Examples: Template-group-directory mode
Insantiate and use a template from a group of files in a template group directory
StringTemplateGroup stg = new StringTemplateGroup("mygroup", "/somepath/mygroupdir");
StringTemplate st = stg.getInstanceOf("mytemplate");
st.setAttribute("arg1","Value1");
String s = st.toString();
/somepath/mygroupdir/mytemplate.st:
Hello, $arg1$
Result: Hello, Value1
Note that the template file did not have to be loaded explicitly. The call to getInstanceOf finds it in the group directory if it hasn't been loaded previously.
Adding a named template from a string
...
tmptext = "Hello, $name$";
newst = stg.defineTemplate("mynewtmp", tmptext);
...
Note: There is also a StringTemplate constructor with a StringTemplateGroup argument. However, there is no provision for a template name in that case. The new template created that way can refer to other templates in the group, but cannot be referred to by them.
Group directories with inheritance
StringTemplateGroup mysuper = new StringTemplateGroup("mysupergrp", "/somepath/master");
StringTemplateGroup mysub = new StringTemplateGroup("mysubgrp" , "/somepath/sub");
mysub.setSuperGroup(mysuper);
....
* A group's supergroup can be set to be set to some other group dynamically, if need be.
- Contrast the method of setting supergroup shown here versus the inheritance syntax in stg files (below).
Examples: Template-group-file mode
Single stg file
StringTemplateGroup stg = new StringTemplateGroup( new FileReader("/somepath/mygroup.stg") );
StringTemplate st = stg.getInstanceOf("sometmp");
st.setAttribute("arg1","Value1");
String s = st.toString();
Notes:
- See the separate ST condensed - File syntax article for the format of an stg file.
- Can use a StringReader to supply stg-format text from a string.
- Default expression delimiters recognized by StringTemplateGroup are <...>. Can instead invoke StringTemplateGroup constructor with a lexer class argument, and use DefaultTemplateLexer.class.
With supergroup file
StringTemplateGroup stgsuper = new StringTemplateGroup( new FileReader("/somepath/mysuper.stg") );
StringTemplateGroup stg = new StringTemplateGroup( new FileReader("/somepath/mygroup.stg") );
StringTemplate st = stg.getInstanceOf("sometmp");
st.setAttribute("arg1","Value1");
String s = st.toString();
/somepath/mygroup.stg:
group mygroup: mysuper; // inherit from mysuper sometmp(arg1) ::= << Here is arg1: <arg1> >>
Notes:
- Inheritance connection is made by the group statement in the stg file of the sub-group. This provides the name of the super-group for StringTemplate to look for in the list of StringTemplateGroups currently loaded. (ie: there is no mechanism for automatically loading a mentioned super-group file (Is this correct? --GW), though there is an interface defined for this if you would like to implement one.)
- See the separate ST condensed - File syntax article for the format of an stg file.
Next: ST condensed -- Templates and expressions
Contents
- Contents
- Overview
- StringTemplate object, attributes, template text and expressions
- Expression delimiters: $...$ or <...>
- Where might you deal with template texts?
- Simple templates
- Templates defined in a string template group file
- Expressions Overview
- The basic idea
- Expressions containing no template section
- Expressions containing a template section
- Variations for each part of an expression
- Examples
- Template Expressions and Statements
- Documentation conventions
- Symbol guide
- Table of Template Expressions and Statements
- Expressions
- 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
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.
StringTemplate object, attributes, template text and expressions
As shown in the previous article, the StringTemplate object has the following features:
- Attributes: Values, or references to data items in the calling program, which will be supplied to expressions during the template rendering process.
- Template text: Consists of alternating:
- Literal text: Text which will be copied directly to the result text
- Expressions: which obtain values from the StringTemplate's attributes, and, with some processing, insert strings into the result text.
Expression delimiters: $...$ or <...>
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 <...>.
Example template text with $..$ expression delimiters:
Where might you deal 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 -- xxx.st You might provide templates in individual xxx.st files. The filename (minus ".st") provides the template name.
- In a template group file -- xxx.stg: 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 some 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
Expressions:
- make use of some input data, ultimately from attributes supplied to the StringTemplate object by the calling program
- perform some processing
- always return a string (or nothing)
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 each optional. By using or not using each part, expressions can serve various purposes. It is useful to distinguish two main varieties of expression:
- Expressions with no template section
- Expressions with a template section
The following sections give a general overview of these varieties of expressions. The syntax is spelled out in detail in a section "Table of Template Expressions and Statements" below.
Expressions containing no template section
This category covers the forms of expression like the following:
- <attribname>
- <attribname.propname>
- <attribname; options>
- ... and similar.
These are the forms of expression where an attribute is actually read from the calling program and turned into a string, as sketched in the following diagram.

Note that in StringTemplate there are no local variables, nor any calculations based on attribute values, except for map lookup. Consequently, all values come directly from attributes or maps, positioned in the flow of result text by these no-template expressions.
The options section controls formatting of the string result.
- If the attribute is already a string, it is returned as is (or as influenced by options) from this expression.
- If the attribute is some other simple type, like integer, then its AsString() method is called to obtain a string
- If the attribute refers to a list, then each of its items is individually turned into a string and concatenated to produce a result string. (An option can specify a separator to place between the items as they are concatenated).
- If attribname refers to an object, and propname is also specified, then StringTemplate looks for a property corresponding to propname on the object supplied.
- If attribname refers to a map object, then propname is used to "look up" that name in the map's key list, and return the corresponding value.
Expressions containing a template section
This category covers the forms of expression like the following:

Notes:
- Attributes and Late stringification
- The varieties of attributes/properties/maps which may be specified in the "select attrib(s)" section are as described above for the no-template expressions.
- Attributes are passed into, or available to, the inner template without turning them into strings.
- To make use of an attribute, ultimately, the inner template (or a template that it in turn invokes) has to have an expression of the no-template variety to convert the attribute to a string.
- Iteration
- If the attribute or property specifies a list, then the inner template is applied to each item in the list separately. That is to say, the inner template is invoked multiple times, each time supplying an item from the list. This will result in multiple returned strings from the inner template, which during render will be concatenated to form the outer template's result (possibly with a separator specified in options.)
Exact details of how attributes are passed to inner templates will be covered in sections below.
Variations for each part of an expression
The following table summarizes the variations available for each of the three sections of the expression. Remember that if the template part is present, the "specify attribute(s)" part supplies attributes to the template. If the template part is not present, the "specify attribute(s)" part selects attributes to be transformed and possibly concatenated into a single result string.
| Select attribute(s) part |
Template(s) part |
Options part |
|---|---|---|
|
|
Mostly controls formatting of the string result of the template
|
Examples
| Category | Select Attribute(s) |
(:)Template(s) | ; options | Examples |
|---|---|---|---|---|
| - | - | - | ||
| Convert attrib to string | X | - | - | <customer> |
| X | - | X | <customers; separator=", "> | |
| Invoke inner template | - | X | - | <disclaimer(yr="2009", co=coname)> |
| - | X | X | <hitcount()>; format="fancy"> | |
| X | X | - | <customer:salutation()> | |
| X | X | X | <customers:makebold(); separator=", "> |
Expressions Intro HTML Version: GW 2009-06-24
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. Do not surround with delimiters when expr appears directly within an expression (as opposed to within a template.) |
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.
Expressions
| Syntax | Description |
|---|---|
| Select 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. |
| <mapname.itemname> | Look up a value in a map. (Maps are name:value tables defined by the calling program or in an stg file.) Here mapname specifies the name of the map, and itemname provides the name of the item to look up. Result will be the value field of that item in the table. |
| <mapname.(expr)> | Same as <mapname.itemname>, except first evaluate expr to calculate itemname. |
| <[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. |
| Invoke template | |
| <tmpname()> | ( ) indicates that tmpname refers to a template to be invoked. In this case, invoke template named tmpname, without args (though the template can access attributes from the surrounding template's context). 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 within the called template's text.) -- expr can be any expression that makes sense in the context of the enclosing template. Note that an expression does not need to be delimited if it's inside an arg list. So: Correct: <mytemplate(somearg=someattr)> Incorrect: <mytemplate(somearg=<someattr>)> |
| <tmpname(...)> | Ellipses (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 prevent 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 "et cetera". |
| <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: args represents: argname=expr,argname2=expr2 (etc) | |
| <(expr)(args)> | Template invocation, but first evaluate expr to calculate tmpname template name |
| Inheritance-related syntax | |
| <super.tmpname()> | Invoke inherited template: For templates in a group that inherits from another
group, invoke the supergroup's version of the template using the super
keyword. Note: Using a fully-qualified template name, (with actual name of the supergroup in place of "super") does not work in this situation. |
| 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 overall 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. Ie: anywhere in this 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, alternating 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 the
attribute is
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>}...> |
| Other operators or functions | You might expect to find other operators or functions for manipulating strings, for example left/right padding, trunctation and so on. StringTemplate does not have these built in. Instead, see the FormatRenderer topic. |
| 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. |
| ______________________________________ | |
Statements
| Syntax | Description |
|---|---|
| Conditional statements | These constructs can be nested. |
| <if(attrname)> subtmptext1 <else> subtmptext2 <endif> |
Tests attribute attrname to determine whether to include text subtmptext1 or
subtmptext2. The attribute test evaluates to true if one of the following is true: -- attribute attrname is an object with a boolean value and is true -- attribute attrname does not have a boolean value, but does have a value (is not null). |
| <if(attrname1)> subtmptext1 <elseif(attrname2)> subtmptext2 <elseif(attrname3)> subtmptext3 <else> subtmptext4 <endif> |
Include the first subtemplate text for which the corresponding attribute is true (boolean true, or nonboolean and not null). |
| <if(!attrname)> subtmptext1 <endif> | Use exclamation point to indicate NOT. |
| Region markers | |
| <@regionname()> | In a template of a supergroup, mark a location in the template; note use of
brackets ( ),
and no <@end> marker.) See File formats article for the string-template group file syntax for specifying the text to insert/substitute at a region. |
| <@regionname> ...template text... <@end> |
In a template of a supergroup, mark begin and end of a region of template text; no brackets ( ), and do use <@end> marker. |
| _________________________________ |
Expressions and Statements HTML Version: GW 2009-06-10 02:36:56
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, insert this string in the result. |
| 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 provide formatting capabilites to the template world. This is done through the AttributeRenderer features. An application may attach AttributeRenderers to a StringTemplate which apply to specific attribute datatypes or classes of objects. When an object of such a type or 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 inner template results (which return a string). You can consider creating and attaching 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:
Next: ST condensed -- File syntax
File types
There are three file types in the StringTemplate world:
- xxx.st - File containing single StringTemplate text. Body only, no argument declarations.
- Could be just a single file, or could be located within a group directory and thus be involved in some group functionality such as referencing other named templates, or vice versa.
- Name of template is name of file (minus the ".st" extension)
- xxx.stg - StringTemplateGroup file. Contains definitions of multiple named templates, including formal argument declarations.
- xxx.sti - Defines an "interface" for StringTemplateGroups. A StringTemplateGroup can declare that that it implements a particular interface, in which case it must provide implementations (actual template definitions) for the templates declared in the interface file.
Template file format
Filename pattern: *.st
Just interleaved literal text and expressions. The contents of the file are just the body of the template text, no template name, no arguments.
Here, the template uses <...> as expression delimiters. This is the exact same format as your program could supply in a string when calling one of the StringTemplate constructors.
Template Group file format
Filename pattern: *.stg
This format is more elaborate. Example:
Template group file syntax
| Statement type |
Syntax |
Comment |
|---|---|---|
| group |
Place at beginning of string template group file to name the group, and also indicate inheritance or implements |
|
| |
Simple case. Conventionally, gname should match the name of the template group file (minus .stg extension). The actual StringTemplateGroup object's Name field adopts the name provided by this group statement, even if different from the filename. If other templates refer to this one (as in inheritance) then it's this gname that's valid. |
|
| |
Group gname inherits from supergroupname |
|
| |
Group gname implements the interface specified in intfname. Implements can also be placed after supergroupname. |
|
| template definition |
|
Basic form of template specification |
| |
Basic form of template specification using <<...>> to enclose multiple lines of template text |
|
| |
Declare formal arguments inside the parens. (<<...>> can be used instead of "...") |
|
| |
Optionally provide a default value for an argument (<<...>> can be used instead of "...") |
|
| |
Make newname an alternative name for the template oldname. Might also work for maps? |
|
| Inheritance |
Override an inherited template |
In the sub group file, just create a new definition of the template using the syntax above. |
| Region override |
|
Override a region just like overriding a template, except use the qualified name of the region in place of the template name. Although there are parens, there will never be formal arguments. (<<...>> can be used instead of "...") |
| map |
|
-- The last row can use default as the name (no quotes) to specify what to return when an expression invokes the map with a key that is not in the map. -- You can use the word key (no quotes) as a value to indicate that the map should just return the same value as was supplied. This is most useful in combination with the default name. |
| |
Template Group interface file format
Filename pattern: *.sti
This format is almost identical to the string-template group file (*.stg) format, but omits the bodies (texts) of templates.
Template group interface file syntax
| Statement type |
Syntax |
Comment |
|---|---|---|
| interface |
Place at beginning of string-template group interface file to name the interface |
|
| |
Simple case. Conventionally, gname should match the name of the template group file (minus .stg extension). The actual StringTemplateGroup object's Name field adopts the name provided by this group statement, even if different from the filename. If other templates refer to this one (as in inheritance) then it's this gname that's valid. |
|
| |
Specify a template that is required to be implemented. (Note the semicolon at the end.) |
|
| |
This form (with the keyword "optional") is used specify a template that can be implemented but is not required. |
Next: ST condensed -- API annotated
Note: Actual annotated API pages not included here, as they are lengthy. See individual pages instead.
Annotated API
Because documentation often lags behind the actual development of libraries, if you are trying to understand StringTemplate you will likely need to read the javadocs documentation of the API, and probably delve into the source code itself. That's a reasonable idea, but the source code and javadocs currently have two issues that make that tough going.
- Out-of-date: Some of the javadoc comments are particularly out-of-date, or are particularly narrow comments that misdirect away from more useful information.
- Ambiguously-broad API: The various classes leave a large number of methods with public access (rather than protected), even though many of these methods are not intended to be part of the API for application programs to call. This blizzard of methods gets in the way of a reader being able to identify and focus on just the most-relevant ones (and invites convoluted misuse of the library).
- Public vs Package scope: There's a possible point of confusion when reading the javadocs (and the excerpt that I've annotated). In the summary tables, the declarations apparently omit the "public" access specifier (though these are shown in the detail listing of each field and method below the summaries). Consequently, methods and fields whose summaries lack an access specifier do not have package scope (as would be the case in actual Java source code) but instead probably have public scope.
So, the attached pages are my quick attempt to identify and highlight what I believe to be the relevant methods of the core classes, StringTemplate and StringTemplateGroup, and to add some commentary (helpful I hope) where the javadocs are, in my view, problematic.
It is my hope that these suggestions will be incorporated back into the actual source code, making this kind of page unnecessary.
These pages are based on copies of the actual javadocs, captured 2009-05-25 (version 3.2). Though I rearranged the order of the sections and methods to highlight the most relevant methods, I have not deleted any, so you still see the full view. (I have, however, skipped the lengthy bottom section that normally provides a separate section for every method and field, with extended blurbs for some. You can view that in the original javadocs if need be.)
Wiki note: These annotated API pages are written in html as the wiki markup language is too convoluted for this kind of document. This makes these pages somewhat unmaintainable. Hopefully some of this material can get incorporated back into the source code before too long.