or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

gstring-templates.mdindex.mdmarkup-templates.mdsimple-templates.mdstreaming-templates.mdxml-templates.md

streaming-templates.mddocs/

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

```