0
# Streaming Templates
1
2
The StreamingTemplateEngine provides closure-based template processing optimized for large templates (>64k characters). It offers equivalent functionality to SimpleTemplateEngine but with better scalability and enhanced error reporting.
3
4
## Capabilities
5
6
### Streaming Template Engine Class
7
8
Creates templates using closure-based approach with enhanced error handling and support for large templates.
9
10
```java { .api }
11
/**
12
* Closure-based template engine optimized for large templates and scalable performance.
13
* Handles templates larger than 64k characters and provides enhanced error reporting.
14
*/
15
public class StreamingTemplateEngine extends TemplateEngine {
16
/**
17
* Creates a new StreamingTemplateEngine with default class loader
18
*/
19
public StreamingTemplateEngine();
20
21
/**
22
* Creates a new StreamingTemplateEngine with custom class loader
23
* @param parentLoader ClassLoader used when parsing template code
24
*/
25
public StreamingTemplateEngine(ClassLoader parentLoader);
26
}
27
```
28
29
**Usage Examples:**
30
31
```java
32
import groovy.text.StreamingTemplateEngine;
33
import groovy.text.Template;
34
import java.util.Map;
35
import java.util.HashMap;
36
37
// Create streaming template engine
38
StreamingTemplateEngine engine = new StreamingTemplateEngine();
39
40
// Template with mixed JSP and GString syntax (same as SimpleTemplateEngine)
41
String templateText = """
42
Dear <% out.print firstname %> ${lastname},
43
44
We <% if (accepted) out.print 'are pleased' else out.print 'regret' %>
45
to inform you that your paper entitled
46
'$title' was ${ accepted ? 'accepted' : 'rejected' }.
47
48
The conference committee.
49
""";
50
51
Template template = engine.createTemplate(templateText);
52
53
Map<String, Object> binding = new HashMap<>();
54
binding.put("firstname", "Grace");
55
binding.put("lastname", "Hopper");
56
binding.put("accepted", true);
57
binding.put("title", "Groovy for COBOL programmers");
58
59
String result = template.make(binding).toString();
60
61
// Works with large templates (>64k characters)
62
StringBuilder largeTemplate = new StringBuilder();
63
for (int i = 0; i < 10000; i++) {
64
largeTemplate.append("Line ${i}: Hello $name!\\n");
65
}
66
67
Template bigTemplate = engine.createTemplate(largeTemplate.toString());
68
Map<String, Object> bigBinding = new HashMap<>();
69
bigBinding.put("name", "World");
70
71
String bigResult = bigTemplate.make(bigBinding).toString();
72
```
73
74
### Template Syntax Support
75
76
StreamingTemplateEngine supports the same syntax as SimpleTemplateEngine with some additional considerations:
77
78
#### JSP-Style Scriptlets
79
Use `<% %>` blocks for executing Groovy code. Note that `out.print` is required for output in scriptlets:
80
81
```java
82
String template = """
83
<%
84
def greeting = "Hello"
85
if (name) {
86
out.print greeting + " " + name
87
} else {
88
out.print greeting + " World"
89
}
90
%>
91
""";
92
```
93
94
#### JSP-Style Expressions
95
Use `<%= %>` blocks for outputting expression results:
96
97
```java
98
String template = """
99
Current time: <%= new Date() %>
100
User count: <%= users.size() %>
101
""";
102
```
103
104
#### GString Expressions
105
Use `${expression}` or `$variable` for variable substitution:
106
107
```java
108
String template = """
109
Welcome ${user.name}!
110
Your balance is $balance.
111
""";
112
```
113
114
#### Dollar Identifiers
115
Simple variable references without braces:
116
117
```java
118
String template = """
119
Hello $name!
120
Today is $date
121
""";
122
```
123
124
### Large Template Handling
125
126
StreamingTemplateEngine is specifically designed to handle large templates that would cause issues with other engines:
127
128
```java
129
// Example: Generate a large report template
130
StringBuilder reportTemplate = new StringBuilder();
131
reportTemplate.append("# Large Report\\n\\n");
132
133
// Add thousands of template sections
134
for (int section = 1; section <= 1000; section++) {
135
reportTemplate.append("## Section ").append(section).append("\\n");
136
reportTemplate.append("Content for section ${section}: $data_").append(section).append("\\n\\n");
137
}
138
139
StreamingTemplateEngine engine = new StreamingTemplateEngine();
140
Template template = engine.createTemplate(reportTemplate.toString());
141
142
// Bind data for all sections
143
Map<String, Object> binding = new HashMap<>();
144
for (int i = 1; i <= 1000; i++) {
145
binding.put("data_" + i, "Data for section " + i);
146
}
147
148
String report = template.make(binding).toString();
149
```
150
151
### Enhanced Error Reporting
152
153
StreamingTemplateEngine provides detailed error reporting with template source context:
154
155
```java
156
// Template with intentional error
157
String templateWithError = """
158
<% def greeting = "Hello" %>
159
Welcome ${greeting}!
160
<% invalid_variable.someMethod() %> // This will cause an error
161
Goodbye!
162
""";
163
164
try {
165
StreamingTemplateEngine engine = new StreamingTemplateEngine();
166
Template template = engine.createTemplate(templateWithError);
167
String result = template.make(new HashMap()).toString();
168
} catch (Exception e) {
169
// StreamingTemplateEngine provides detailed error context:
170
// "Template execution error at line 3:
171
// 2: Welcome ${greeting}!
172
// --> 3: <% invalid_variable.someMethod() %>
173
// 4: Goodbye!
174
System.err.println(e.getMessage());
175
}
176
```
177
178
### Web Integration
179
180
StreamingTemplateEngine can be used with servlet containers:
181
182
```xml
183
<servlet>
184
<servlet-name>StreamingTemplate</servlet-name>
185
<servlet-class>groovy.servlet.TemplateServlet</servlet-class>
186
<init-param>
187
<param-name>template.engine</param-name>
188
<param-value>groovy.text.StreamingTemplateEngine</param-value>
189
</init-param>
190
</servlet>
191
```
192
193
### Template Script Source Access
194
195
StreamingTemplateEngine allows access to the generated script source for debugging:
196
197
```java
198
StreamingTemplateEngine engine = new StreamingTemplateEngine();
199
Template template = engine.createTemplate("Hello ${name}!");
200
201
// Access the generated script source (implementation detail)
202
// This can be useful for debugging complex template issues
203
// Note: This is accessed through internal StreamingTemplate properties
204
```
205
206
### Performance Characteristics
207
208
StreamingTemplateEngine is optimized for:
209
210
- **Large templates**: Handles templates larger than 64k characters efficiently
211
- **Memory usage**: Uses closure-based approach to reduce memory overhead
212
- **Scalability**: Better performance with complex template hierarchies
213
- **Error handling**: Provides detailed error context with line numbers
214
215
### Error Types
216
217
StreamingTemplateEngine can throw several types of exceptions:
218
219
```java
220
try {
221
Template template = engine.createTemplate(templateText);
222
String result = template.make(binding).toString();
223
} catch (CompilationFailedException e) {
224
// Template compilation failed
225
} catch (ClassNotFoundException e) {
226
// Missing class dependencies
227
} catch (IOException e) {
228
// I/O error reading template source
229
} catch (TemplateExecutionException e) {
230
// Runtime error during template execution
231
int errorLine = e.getLineNumber();
232
System.err.println("Error at line " + errorLine + ": " + e.getMessage());
233
}
234
```