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.