or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

ast-transforms.mdcli.mdcore-language.mdindex.mdjson.mdsql.mdswing.mdtemplates.mdxml.md

templates.mddocs/

0

# Template Processing

1

2

Groovy provides multiple template engines for generating dynamic content with variable substitution, embedded code execution, and flexible output formatting.

3

4

## Template Engines

5

6

### SimpleTemplateEngine

7

8

Basic template engine with GString-style variable substitution and embedded code support.

9

10

```groovy { .api }

11

class SimpleTemplateEngine extends TemplateEngine {

12

SimpleTemplateEngine()

13

SimpleTemplateEngine(ClassLoader parentLoader)

14

15

Template createTemplate(String templateText)

16

Template createTemplate(File templateFile)

17

Template createTemplate(URL templateURL)

18

Template createTemplate(Reader reader)

19

}

20

```

21

22

Usage examples:

23

```groovy

24

import groovy.text.SimpleTemplateEngine

25

26

def engine = new SimpleTemplateEngine()

27

28

// Simple variable substitution

29

def template = engine.createTemplate('Hello $name, you are $age years old.')

30

def binding = [name: 'John', age: 30]

31

def result = template.make(binding)

32

println result.toString() // "Hello John, you are 30 years old."

33

34

// Embedded expressions

35

def template2 = engine.createTemplate('''

36

Dear $name,

37

38

Your account balance is $${balance}.

39

${balance > 1000 ? 'You qualify for premium services.' : 'Consider upgrading your account.'}

40

41

Best regards,

42

The System

43

''')

44

45

def result2 = template2.make([name: 'Alice', balance: 1500])

46

println result2.toString()

47

48

// Embedded code blocks

49

def template3 = engine.createTemplate('''

50

<html>

51

<body>

52

<h1>User List</h1>

53

<ul>

54

<% users.each { user -> %>

55

<li>${user.name} (${user.email})</li>

56

<% } %>

57

</ul>

58

</body>

59

</html>

60

''')

61

62

def users = [

63

[name: 'John', email: 'john@example.com'],

64

[name: 'Jane', email: 'jane@example.com']

65

]

66

def html = template3.make([users: users])

67

println html.toString()

68

```

69

70

### GStringTemplateEngine

71

72

Template engine that treats the entire template as a GString for more flexible processing.

73

74

```groovy { .api }

75

class GStringTemplateEngine extends TemplateEngine {

76

GStringTemplateEngine()

77

GStringTemplateEngine(ClassLoader parentLoader)

78

79

Template createTemplate(String templateText)

80

Template createTemplate(File templateFile)

81

Template createTemplate(URL templateURL)

82

Template createTemplate(Reader reader)

83

}

84

```

85

86

Usage example:

87

```groovy

88

import groovy.text.GStringTemplateEngine

89

90

def engine = new GStringTemplateEngine()

91

92

def template = engine.createTemplate('''

93

Report for $title

94

Generated on ${new Date().format('yyyy-MM-dd')}

95

96

Summary:

97

- Total items: ${items.size()}

98

- Average value: ${items.sum { it.value } / items.size()}

99

- Maximum value: ${items.max { it.value }.value}

100

101

Details:

102

${items.collect { "- ${it.name}: ${it.value}" }.join('\\n')}

103

''')

104

105

def data = [

106

title: 'Monthly Sales',

107

items: [

108

[name: 'Product A', value: 100],

109

[name: 'Product B', value: 250],

110

[name: 'Product C', value: 175]

111

]

112

]

113

114

def report = template.make(data)

115

println report.toString()

116

```

117

118

### XmlTemplateEngine

119

120

Template engine specifically designed for XML generation with proper escaping.

121

122

```groovy { .api }

123

class XmlTemplateEngine extends TemplateEngine {

124

XmlTemplateEngine()

125

XmlTemplateEngine(ClassLoader parentLoader)

126

127

Template createTemplate(String templateText)

128

Template createTemplate(File templateFile)

129

Template createTemplate(URL templateURL)

130

Template createTemplate(Reader reader)

131

}

132

```

133

134

Usage example:

135

```groovy

136

import groovy.text.XmlTemplateEngine

137

138

def engine = new XmlTemplateEngine()

139

140

def template = engine.createTemplate('''

141

<catalog>

142

<title>$title</title>

143

<books>

144

<% books.each { book -> %>

145

<book id="$book.id">

146

<title>$book.title</title>

147

<author>$book.author</author>

148

<price currency="USD">$book.price</price>

149

<description>$book.description</description>

150

</book>

151

<% } %>

152

</books>

153

</catalog>

154

''')

155

156

def catalog = [

157

title: 'Programming Books',

158

books: [

159

[

160

id: 1,

161

title: 'Groovy in Action',

162

author: 'Dierk König',

163

price: 49.99,

164

description: 'Comprehensive guide to Groovy & dynamic languages'

165

],

166

[

167

id: 2,

168

title: 'Programming Groovy 2',

169

author: 'Venkat Subramaniam',

170

price: 44.99,

171

description: 'Practical guide with examples & best practices'

172

]

173

]

174

]

175

176

def xml = template.make(catalog)

177

println xml.toString()

178

```

179

180

### StreamingTemplateEngine

181

182

Memory-efficient template engine for generating large output using streaming.

183

184

```groovy { .api }

185

class StreamingTemplateEngine extends TemplateEngine {

186

StreamingTemplateEngine()

187

StreamingTemplateEngine(String staticText, String expressionText)

188

StreamingTemplateEngine(ClassLoader parentLoader)

189

190

Template createTemplate(String templateText)

191

Template createTemplate(File templateFile)

192

Template createTemplate(URL templateURL)

193

Template createTemplate(Reader reader)

194

}

195

```

196

197

Usage example:

198

```groovy

199

import groovy.text.StreamingTemplateEngine

200

201

def engine = new StreamingTemplateEngine()

202

203

def template = engine.createTemplate('''

204

<html>

205

<head><title>Large Report</title></head>

206

<body>

207

<h1>Data Report</h1>

208

<table>

209

<tr><th>ID</th><th>Name</th><th>Value</th></tr>

210

<% data.each { item -> %>

211

<tr><td>$item.id</td><td>$item.name</td><td>$item.value</td></tr>

212

<% } %>

213

</table>

214

</body>

215

</html>

216

''')

217

218

// Generate large dataset

219

def largeData = (1..10000).collect { i ->

220

[id: i, name: "Item $i", value: Math.random() * 1000]

221

}

222

223

// Stream output to file

224

new File('report.html').withWriter { writer ->

225

def result = template.make([data: largeData])

226

result.writeTo(writer)

227

}

228

```

229

230

## Template Interface

231

232

### Template

233

234

Base interface for all template implementations.

235

236

```groovy { .api }

237

interface Template {

238

Writable make()

239

Writable make(Map binding)

240

}

241

```

242

243

### Writable

244

245

Interface for objects that can write themselves to a Writer.

246

247

```groovy { .api }

248

interface Writable {

249

Writer writeTo(Writer out)

250

}

251

```

252

253

Usage example:

254

```groovy

255

def template = engine.createTemplate('Hello $name!')

256

def writable = template.make([name: 'World'])

257

258

// Write to different outputs

259

println writable.toString() // To string

260

writable.writeTo(System.out) // To console

261

new File('output.txt').withWriter { writer ->

262

writable.writeTo(writer) // To file

263

}

264

```

265

266

## Advanced Template Features

267

268

### Custom Delimiters

269

270

```groovy

271

import groovy.text.SimpleTemplateEngine

272

273

// Custom template with different delimiters

274

def engine = new SimpleTemplateEngine()

275

def customTemplate = '''

276

Report: <%=title%>

277

Date: <%=new Date().format('yyyy-MM-dd')%>

278

279

<% items.each { item -> %>

280

Item: <%=item.name%> - <%=item.value%>

281

<% } %>

282

'''

283

284

// Note: Use StreamingTemplateEngine for custom delimiters

285

def streamingEngine = new StreamingTemplateEngine('<%', '%>')

286

def template = streamingEngine.createTemplate(customTemplate)

287

def result = template.make([

288

title: 'Custom Report',

289

items: [[name: 'A', value: 100], [name: 'B', value: 200]]

290

])

291

println result.toString()

292

```

293

294

### Template Caching

295

296

```groovy

297

import groovy.text.SimpleTemplateEngine

298

299

class CachedTemplateEngine {

300

private final SimpleTemplateEngine engine = new SimpleTemplateEngine()

301

private final Map<String, Template> cache = [:]

302

303

Template getTemplate(String templateText) {

304

return cache.computeIfAbsent(templateText) { text ->

305

engine.createTemplate(text)

306

}

307

}

308

309

String process(String templateText, Map binding) {

310

return getTemplate(templateText).make(binding).toString()

311

}

312

}

313

314

def cachedEngine = new CachedTemplateEngine()

315

316

// Templates are cached for reuse

317

def template1 = 'Hello $name, today is ${new Date().format("yyyy-MM-dd")}'

318

println cachedEngine.process(template1, [name: 'Alice'])

319

println cachedEngine.process(template1, [name: 'Bob']) // Uses cached template

320

```

321

322

### Template Inheritance

323

324

```groovy

325

import groovy.text.SimpleTemplateEngine

326

327

// Base template

328

def baseTemplate = '''

329

<html>

330

<head>

331

<title>$title</title>

332

<style>

333

body { font-family: Arial, sans-serif; }

334

.content { margin: 20px; }

335

</style>

336

</head>

337

<body>

338

<div class="content">

339

$content

340

</div>

341

</body>

342

</html>

343

'''

344

345

// Content template

346

def contentTemplate = '''

347

<h1>$pageTitle</h1>

348

<p>$message</p>

349

<ul>

350

<% items.each { item -> %>

351

<li>$item</li>

352

<% } %>

353

</ul>

354

'''

355

356

def engine = new SimpleTemplateEngine()

357

358

// Generate content first

359

def content = engine.createTemplate(contentTemplate).make([

360

pageTitle: 'Welcome',

361

message: 'This is the main content.',

362

items: ['Feature 1', 'Feature 2', 'Feature 3']

363

]).toString()

364

365

// Apply to base template

366

def finalPage = engine.createTemplate(baseTemplate).make([

367

title: 'My Website',

368

content: content

369

]).toString()

370

371

println finalPage

372

```

373

374

### Template with Includes

375

376

```groovy

377

import groovy.text.SimpleTemplateEngine

378

379

class TemplateManager {

380

private final SimpleTemplateEngine engine = new SimpleTemplateEngine()

381

private final Map<String, String> templates = [:]

382

383

void defineTemplate(String name, String content) {

384

templates[name] = content

385

}

386

387

String include(String templateName, Map binding = [:]) {

388

def templateContent = templates[templateName]

389

if (!templateContent) {

390

throw new IllegalArgumentException("Template '$templateName' not found")

391

}

392

return engine.createTemplate(templateContent).make(binding).toString()

393

}

394

395

String process(String templateContent, Map binding) {

396

// Add include function to binding

397

binding.include = this.&include

398

return engine.createTemplate(templateContent).make(binding).toString()

399

}

400

}

401

402

def manager = new TemplateManager()

403

404

// Define reusable templates

405

manager.defineTemplate('header', '''

406

<header>

407

<h1>$title</h1>

408

<nav>

409

<a href="/home">Home</a>

410

<a href="/about">About</a>

411

</nav>

412

</header>

413

''')

414

415

manager.defineTemplate('footer', '''

416

<footer>

417

<p>&copy; $year $company. All rights reserved.</p>

418

</footer>

419

''')

420

421

// Main template using includes

422

def mainTemplate = '''

423

<html>

424

<body>

425

${include('header', [title: pageTitle])}

426

427

<main>

428

<h2>$contentTitle</h2>

429

<p>$content</p>

430

</main>

431

432

${include('footer', [year: year, company: company])}

433

</body>

434

</html>

435

'''

436

437

def result = manager.process(mainTemplate, [

438

pageTitle: 'My Website',

439

contentTitle: 'Welcome',

440

content: 'This is the main content of the page.',

441

year: 2023,

442

company: 'My Company'

443

])

444

445

println result

446

```

447

448

## Error Handling

449

450

### Template Compilation Errors

451

452

```groovy

453

import groovy.text.SimpleTemplateEngine

454

455

try {

456

def engine = new SimpleTemplateEngine()

457

// Invalid template syntax

458

def template = engine.createTemplate('Hello $name, <% invalid groovy code %>')

459

} catch (Exception e) {

460

println "Template compilation error: ${e.message}"

461

// Handle compilation errors

462

}

463

```

464

465

### Runtime Template Errors

466

467

```groovy

468

try {

469

def engine = new SimpleTemplateEngine()

470

def template = engine.createTemplate('Hello $name.toUpperCase()!')

471

472

// This will fail if name is null

473

def result = template.make([name: null])

474

println result.toString()

475

476

} catch (Exception e) {

477

println "Template execution error: ${e.message}"

478

// Provide default values or error handling

479

def safeTemplate = engine.createTemplate('Hello ${name?.toUpperCase() ?: "Guest"}!')

480

def safeResult = safeTemplate.make([name: null])

481

println safeResult.toString() // "Hello Guest!"

482

}

483

```

484

485

## Integration Patterns

486

487

### Web Template Integration

488

489

```groovy

490

import groovy.text.SimpleTemplateEngine

491

import groovy.servlet.TemplateServlet

492

493

// Example servlet integration

494

class MyTemplateServlet extends TemplateServlet {

495

496

@Override

497

protected void service(HttpServletRequest request, HttpServletResponse response) {

498

def engine = new SimpleTemplateEngine()

499

def template = engine.createTemplate(getTemplate('user-profile'))

500

501

def user = getUserFromSession(request)

502

def binding = [

503

user: user,

504

currentDate: new Date(),

505

contextPath: request.contextPath

506

]

507

508

response.contentType = 'text/html'

509

template.make(binding).writeTo(response.writer)

510

}

511

}

512

```

513

514

### File-based Template System

515

516

```groovy

517

import groovy.text.SimpleTemplateEngine

518

519

class FileTemplateSystem {

520

private final File templateDir

521

private final SimpleTemplateEngine engine = new SimpleTemplateEngine()

522

523

FileTemplateSystem(String templateDirectory) {

524

this.templateDir = new File(templateDirectory)

525

}

526

527

String render(String templateName, Map binding = [:]) {

528

def templateFile = new File(templateDir, "${templateName}.gtpl")

529

if (!templateFile.exists()) {

530

throw new FileNotFoundException("Template not found: $templateName")

531

}

532

533

def template = engine.createTemplate(templateFile)

534

return template.make(binding).toString()

535

}

536

537

void renderToFile(String templateName, String outputPath, Map binding = [:]) {

538

def content = render(templateName, binding)

539

new File(outputPath).text = content

540

}

541

}

542

543

// Usage

544

def templateSystem = new FileTemplateSystem('src/main/templates')

545

546

def emailContent = templateSystem.render('welcome-email', [

547

userName: 'John Doe',

548

activationLink: 'https://example.com/activate/123'

549

])

550

551

templateSystem.renderToFile('report', 'output/monthly-report.html', [

552

reportDate: new Date(),

553

data: getReportData()

554

])

555

```