Output Filters
Version 2.0 introduced the notion of an StringTemplateWriter
/IStringTemplateWriter
. All text rendered from a template goes through one of these writers before being placed in the output buffer. Terence added this primarily for auto-indentation for code generation, but it also could be used to remove whitespace (as a compression) from HTML output. Most recently, in 2.3, Terence updated the interface to support automatic line wrapping. If you don't care about indentation, you can simply subclass AutoIndentWriter
and override write()
/Write()
:
Java |
public interface StringTemplateWriter {
public static final int NO_WRAP = -1;
void pushIndentation(String indent);
String popIndentation();
void pushAnchorPoint();
void popAnchorPoint();
void setLineWidth(int lineWidth);
/** Write the string and return how many actual chars were written.
* With autoindentation and wrapping, more chars than length(str)
* can be emitted. No wrapping is done.
*/
int write(String str) throws IOException;
/** Same as write, but wrap lines using the indicated string as the
* wrap character (such as "\n").
*/
int write(String str, String wrap) throws IOException;
/** Because we might need to wrap at a non-atomic string boundary
* (such as when we wrap in between template applications
* <data:{v|[<v>]}; wrap>) we need to expose the wrap string
* writing just like for the separator.
*/
public int writeWrapSeparator(String wrap) throws IOException;
/** Write a separator. Same as write() except that a \n cannot
* be inserted before emitting a separator.
*/
int writeSeparator(String str) throws IOException;
}
|
|
C# |
public interface IStringTemplateWriter
{
void PushIndentation(string indent);
string PopIndentation();
void Write(string str);
}
|
|
Python |
class StringTemplateWriter(object):
NO_WRAP = -1
def __init__(self):
pass
def pushIndentation(self, indent):
raise NotImplementedError
def popIndentation(self):
raise NotImplementedError
def pushAnchorPoint(self):
raise NotImplementedError
def popAnchorPoint(self):
raise NotImplementedError
def setLineWidth(self, lineWidth):
raise NotImplementedError
def write(self, str, wrap=None):
raise NotImplementedError
def writeWrapSeparator(self, wrap):
raise NotImplementedError
def writeSeparator(self, str):
raise NotImplementedError
|
|
Here is a "pass through" writer that is already defined:
Java |
/** Just pass through the text */
public class NoIndentWriter extends AutoIndentWriter {
public NoIndentWriter(Writer out) {
super(out);
}
public void write(String str) throws IOException {
out.write(str);
}
} |
|
C# |
/** Just pass through the text */
public class NoIndentWriter : AutoIndentWriter
{
public NoIndentWriter(TextWriter output) :base(output)
{
}
public void Write(string str)
{
output.Write(str);
}
}
|
|
Python |
class NoIndentWriter(stringtemplate3.AutoIndentWriter):
"""Just pass through the text"""
def __init__(self, out):
super(NoIndentWriter, self).__init__(out)
def write(self, str):
self.out.write(str)
return len(str)
|
|
Use it like this:
Java |
StringWriter out = new StringWriter();
StringTemplateGroup group =
new StringTemplateGroup("test");
group.defineTemplate("bold", "<b>$x$</b>");
StringTemplate nameST = new StringTemplate(group, "$name:bold(x=name)$");
nameST.setAttribute("name", "Terence");
// write to 'out' with no indentation
nameST.write(new NoIndentWriter(out));
System.out.println("output: "+out.toString());
|
|
C# |
StringWriter output = new StringWriter();
StringTemplateGroup group = new StringTemplateGroup("test");
group.DefineTemplate("bold", "<b>$x$</b>");
StringTemplate nameST = new StringTemplate(group, "$name:bold(x=name)$");
nameST.SetAttribute("name", "Terence");
// write to 'out' with no indentation
nameST.Write(new NoIndentWriter(output));
Console.Out.WriteLine("output: "+output.ToString());
|
|
Python |
out = StringIO()
group = stringtemplate3.StringTemplateGroup("test")
group.defineTemplate("bold", "<b>$x$</b>")
nameST = stringtemplate3.StringTemplate("$name:bold(x=name)$", group=group)
nameST["name"] = "Terence"
# write to 'out' with no indentation
nameST.write(NoIndentWriter(out))
print "output:", str(out)
|
|
Instead of using nameST.toString()
, which calls write
with a string write and returns its value, manually invoke write
with your writer.
If you want to always use a particular output filter, then use
Java |
StringTemplateGroup.setStringTemplateWriter(Class userSpecifiedWriterClass);
|
|
C# |
StringTemplateGroup.SetStringTemplateWriter(Type userSpecifiedWriterClass);
|
|
Python |
stringtemplate.StringTemplateGroup.setStringTemplateWriter(userSpecifiedWriterClass)
|
|
The StringTemplate.toString()
method is sensitive to the group's writer class.