Defining Templates
Defining Templates
Creating Templates With Code
Here is a simple example that creates and uses a template on the fly:
Java |
StringTemplate query = new StringTemplate("SELECT $column$ FROM $table$;"); query.setAttribute("column", "name"); query.setAttribute("table", "User"); |
---|---|
C# |
StringTemplate query = new StringTemplate("SELECT $column$ FROM $table$;"); query.SetAttribute("column", "name"); query.SetAttribute("table", "User"); |
Python |
query = stringtemplate3.StringTemplate("SELECT $column$ FROM $table$;") query["column"] = "name" query["table"] = "User" |
where StringTemplate
considers anything in $...$
to be something it needs to pay attention to. By setting attributes, you are "pushing" values into the template for use when the template is printed out. The attribute values are set by referencing their names. Invoking toString()
on query
would yield
SELECT name FROM User;
You can set an attribute multiple times, which simply means that the attribute is multi-valued. For example, adding another value to the attribute named column
as shown below makes the attribute multi-valued:
Java |
StringTemplate query = new StringTemplate("SELECT $column$ FROM $table$;"); query.setAttribute("column", "name"); query.setAttribute("column", "email"); query.setAttribute("table", "User"); |
---|---|
C# |
StringTemplate query = new StringTemplate("SELECT $column$ FROM $table$;"); query.SetAttribute("column", "name"); query.SetAttribute("column", "email"); query.SetAttribute("table", "User"); |
Python |
query = stringtemplate3.StringTemplate("SELECT $column$ FROM $table$;") query["column"] = "name" query["column"] = "email" query["table"] = "User" |
Invoking toString()
on query
would now yield
SELECT nameemail FROM User;
Ooops...there is no separator between the multiple values. If you want a comma, say, between the column names, then change the template to record that formatting information:
Java |
StringTemplate query = new StringTemplate("SELECT $column; separator=\",\"$ FROM $table$;"); query.setAttribute("column", "name"); query.setAttribute("column", "email"); query.setAttribute("table", "User"); |
---|---|
C# |
StringTemplate query = new StringTemplate("SELECT $column; separator=\",\"$ FROM $table$;"); query.SetAttribute("column", "name"); query.SetAttribute("column", "email"); query.SetAttribute("table", "User"); |
Python |
query = stringtemplate3.StringTemplate("SELECT $column; separator=\",\"$ FROM $table$;") query["column"] = "name" query["column"] = "email" query["table"] = "User" |
Note that the right-hand-side of the separator specification in this case is a string literal; therefore, we have escaped the double-quotes as the template is specified in a string. In general, the right-hand-side can be any attribute expression. Invoking toString()
on query
would now yield
SELECT name,email FROM User;
Attributes can be any object at all. StringTemplate
calls toString()
on each object as it writes the template out. The separator is not used unless the attribute is multi-valued.
Loading Templates From Files
The rest of this article discusses StringTemplateGroups, but only covers the case of groups of individual template files. You may also be interested in string template group files (xxx.stg) which provide more functionality for many scenarios. See separate Group Files article.
To load a template from the disk you must use a StringTemplateGroup
that will manage all the templates you load, caching them so you do not waste time talking to the disk for each template fetch request (you can change it to not cache; see below). You may have multiple template groups. Here is a simple example that loads the previous SQL template from a file /tmp/theQuery.st
:
SELECT $column; separator=","$ FROM $table$;
The code below creates a StringTemplateGroup
called myGroup
rooted at /tmp
so that requests for template theQuery
forces a load of file /tmp/theQuery.st
.
Java |
StringTemplateGroup group = new StringTemplateGroup("myGroup", "/tmp"); StringTemplate query = group.getInstanceOf("theQuery"); query.setAttribute("column", "name"); query.setAttribute("column", "email"); query.setAttribute("table", "User"); |
---|---|
C# |
StringTemplateGroup group = new StringTemplateGroup("myGroup", "/tmp"); StringTemplate query = group.GetInstanceOf("theQuery"); query.SetAttribute("column", "name"); query.SetAttribute("column", "email"); query.SetAttribute("table", "User"); |
Python |
group = stringtemplate3.StringTemplateGroup("myGroup", "/tmp") query = group.getInstanceOf("theQuery") query["column"] = "name" query["column"] = "email" query["table"] = "User" |
If you have a directory hierarchy of templates such as file /tmp/jguru/bullet.st
, you would reference them relative to the root; in this case, you would ask for template jguru/bullet()
.
Note
StringTemplate strips whitespace from the front and back of all loaded template files. You can add, for example, <\n>
at the end of the file to get an extra carriage return.
Loading Templates relative to an implementation specific location
Java |
Loading Templates from CLASSPATH When deploying applications or providing a library for use by other programmers, you will not know where your templates files live specifically on the disk. You will, however, know relative to the classpath where your templates reside. For example, if your code is in package // Look for templates in CLASSPATH as resources StringTemplateGroup group = new StringTemplateGroup("mygroup"); StringTemplate st = group.getInstanceOf("com/mycompany/server/templates/page"); |
---|---|
C# |
Loading Templates relative to the Assembly's Location When deploying applications or providing a library for use by other programmers, you will not know in advance where your templates files will be located live in the file system. You will, however, often know the location of your templates relative to the where the application assembly is deployed. For example, if your code is in the an assembly named // Look for templates relative to assembly location StringTemplateGroup group = new StringTemplateGroup("mygroup", (string)null); StringTemplate st = group.GetInstanceOf("templates/page"); |
Python |
Loading Templates from sys.path FIXME: there was an implementation, test&document it! |
If page.st
references, say, searchbox
template, it must be fully qualified as:
<font size=2>SEARCH</font>: $com/mycompany/server/templates/page/searchbox()$
This is inconvenient and ST may add the invoking template's path prefix automatically in the future.
Caching
By default templates are loaded from disk just once. During development, however, it is convenient to turn caching off. Also, you may want to turn off caching so that you can quickly update a running site. You can set a simple refresh interval using StringTemplateGroup.setRefreshInterval(...)
. When the interval is reached, all templates are thrown out. Set interval to 0 to refresh constantly (no caching). Set the interval to a huge number like Integer.MAX_INT
or Int32.MaxValue
to have no refreshing at all.
Java |
StringTemplateGroup group = new StringTemplateGroup("myGroup", "/tmp"); group.setRefreshInterval(0); // no caching group.setRefreshInterval(Integer.MAX_INT); // no refreshing |
---|---|
C# |
The C# version of StringTemplate does not implement the StringGroup.setRefreshInterval() method. Template files that have been successfully opened are monitored using FileSystemWatcher. |
Python |
group = stringtemplate3.StringTemplateGroup("myGroup", "/tmp") group.refreshInterval = 0 # no caching group.refreshInterval = sys.maxint # no refreshing |