or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli-interface.mdcollections-utilities.mdcore-runtime.mdindex.mdjson-processing.mdmeta-programming.mdscript-execution.mdsql-database.mdtemplate-processing.mdxml-processing.md

template-processing.mddocs/

0

# Template Processing

1

2

Template engines for code generation, text processing, and dynamic content creation with support for various template formats and streaming capabilities.

3

4

## Capabilities

5

6

### Simple Template Engine

7

8

Basic template engine for string substitution and simple expression evaluation.

9

10

```groovy { .api }

11

/**

12

* Simple template engine for string substitution

13

*/

14

class SimpleTemplateEngine {

15

/** Create simple template engine */

16

SimpleTemplateEngine()

17

18

/** Create template from string */

19

Template createTemplate(String text)

20

21

/** Create template from Reader */

22

Template createTemplate(Reader reader)

23

24

/** Create template from File */

25

Template createTemplate(File file)

26

27

/** Create template from URL */

28

Template createTemplate(URL url)

29

}

30

31

/**

32

* Template interface for rendering with bindings

33

*/

34

interface Template {

35

/** Render template with binding */

36

Writable make(Map binding)

37

38

/** Render template with empty binding */

39

Writable make()

40

}

41

```

42

43

**Usage Examples:**

44

45

```groovy

46

import groovy.text.SimpleTemplateEngine

47

48

// Basic template

49

def engine = new SimpleTemplateEngine()

50

def templateText = '''

51

Hello $name,

52

53

Welcome to $company! Your account has been created with the following details:

54

- Username: $username

55

- Email: $email

56

- Department: ${department.toUpperCase()}

57

58

Best regards,

59

The $company Team

60

'''

61

62

def template = engine.createTemplate(templateText)

63

64

def binding = [

65

name: "Alice Johnson",

66

company: "Acme Corp",

67

username: "ajohnson",

68

email: "alice@acme.com",

69

department: "engineering"

70

]

71

72

def result = template.make(binding)

73

println result.toString()

74

75

// Template with expressions

76

def reportTemplate = '''

77

Report Generated: ${new Date()}

78

Total Users: $userCount

79

80

${users.collect { "- $it.name ($it.email)" }.join('\\n')}

81

82

Average Age: ${users.sum { it.age } / users.size()}

83

'''

84

85

def template2 = engine.createTemplate(reportTemplate)

86

def binding2 = [

87

userCount: 3,

88

users: [

89

[name: "Alice", email: "alice@example.com", age: 30],

90

[name: "Bob", email: "bob@example.com", age: 25],

91

[name: "Charlie", email: "charlie@example.com", age: 35]

92

]

93

]

94

95

println template2.make(binding2)

96

97

// Template from file

98

def fileTemplate = engine.createTemplate(new File("email-template.txt"))

99

def email = fileTemplate.make([

100

recipient: "customer@example.com",

101

subject: "Order Confirmation",

102

orderNumber: "12345"

103

])

104

```

105

106

### Streaming Template Engine

107

108

Template engine optimized for large templates with streaming output.

109

110

```groovy { .api }

111

/**

112

* Streaming template engine for large templates

113

*/

114

class StreamingTemplateEngine {

115

/** Create streaming template engine */

116

StreamingTemplateEngine()

117

118

/** Create template from string */

119

Template createTemplate(String text)

120

121

/** Create template from Reader */

122

Template createTemplate(Reader reader)

123

124

/** Create template from File */

125

Template createTemplate(File file)

126

127

/** Create template from URL */

128

Template createTemplate(URL url)

129

}

130

```

131

132

**Usage Examples:**

133

134

```groovy

135

import groovy.text.StreamingTemplateEngine

136

137

// Large data template

138

def engine = new StreamingTemplateEngine()

139

def csvTemplate = '''

140

"Name","Email","Department","Salary"

141

<% users.each { user -> %>

142

"${user.name}","${user.email}","${user.department}","${user.salary}"

143

<% } %>

144

'''

145

146

def template = engine.createTemplate(csvTemplate)

147

148

// Stream to file for large datasets

149

new File("users.csv").withWriter { writer ->

150

def result = template.make([users: largeUserList])

151

writer << result

152

}

153

154

// Stream to HTTP response

155

response.contentType = "text/csv"

156

response.setHeader("Content-Disposition", "attachment; filename=users.csv")

157

response.writer << template.make([users: userList])

158

```

159

160

### XML Template Engine

161

162

Template engine specifically designed for XML-based templates.

163

164

```groovy { .api }

165

/**

166

* Template engine for XML-based templates

167

*/

168

class XmlTemplateEngine {

169

/** Create XML template engine */

170

XmlTemplateEngine()

171

172

/** Create template from string */

173

Template createTemplate(String text)

174

175

/** Create template from Reader */

176

Template createTemplate(Reader reader)

177

178

/** Create template from File */

179

Template createTemplate(File file)

180

181

/** Create template from URL */

182

Template createTemplate(URL url)

183

}

184

```

185

186

**Usage Examples:**

187

188

```groovy

189

import groovy.text.XmlTemplateEngine

190

191

def engine = new XmlTemplateEngine()

192

def xmlTemplate = '''

193

<?xml version="1.0" encoding="UTF-8"?>

194

<users>

195

<% users.each { user -> %>

196

<user id="${user.id}">

197

<name>${user.name}</name>

198

<email>${user.email}</email>

199

<% if (user.active) { %>

200

<status>active</status>

201

<% } else { %>

202

<status>inactive</status>

203

<% } %>

204

<departments>

205

<% user.departments.each { dept -> %>

206

<department>${dept}</department>

207

<% } %>

208

</departments>

209

</user>

210

<% } %>

211

</users>

212

'''

213

214

def template = engine.createTemplate(xmlTemplate)

215

def binding = [

216

users: [

217

[id: 1, name: "Alice", email: "alice@example.com", active: true, departments: ["Engineering", "Research"]],

218

[id: 2, name: "Bob", email: "bob@example.com", active: false, departments: ["Sales"]],

219

[id: 3, name: "Charlie", email: "charlie@example.com", active: true, departments: ["Marketing", "Support"]]

220

]

221

]

222

223

def xmlResult = template.make(binding)

224

println xmlResult.toString()

225

```

226

227

### Markup Template Engine

228

229

Advanced template engine for creating structured markup with type checking.

230

231

```groovy { .api }

232

/**

233

* Advanced markup template engine

234

*/

235

class MarkupTemplateEngine {

236

/** Create with default configuration */

237

MarkupTemplateEngine()

238

239

/** Create with custom configuration */

240

MarkupTemplateEngine(TemplateConfiguration config)

241

242

/** Create template from string */

243

Template createTemplate(String templateText)

244

245

/** Create template from Reader */

246

Template createTemplate(Reader templateReader)

247

248

/** Create template from File */

249

Template createTemplate(File templateFile)

250

251

/** Create template from URL */

252

Template createTemplate(URL templateURL)

253

254

/** Create typed template */

255

Template createTypeCheckedTemplate(String templateText, Map<String, String> modelTypes)

256

}

257

258

/**

259

* Configuration for markup template engine

260

*/

261

class TemplateConfiguration {

262

/** Set whether to auto-escape XML */

263

TemplateConfiguration autoEscape(boolean autoEscape)

264

265

/** Set whether to auto-format output */

266

TemplateConfiguration autoFormat(boolean autoFormat)

267

268

/** Set whether to auto-newline */

269

TemplateConfiguration autoNewLine(boolean autoNewLine)

270

271

/** Set whether to auto-indent */

272

TemplateConfiguration autoIndent(boolean autoIndent)

273

274

/** Set base template class */

275

TemplateConfiguration baseTemplateClass(Class<?> baseTemplateClass)

276

277

/** Set cache templates */

278

TemplateConfiguration cacheTemplates(boolean cacheTemplates)

279

}

280

```

281

282

**Usage Examples:**

283

284

```groovy

285

import groovy.text.markup.*

286

287

// Create configured engine

288

def config = new TemplateConfiguration()

289

.autoEscape(true)

290

.autoFormat(true)

291

.autoIndent(true)

292

293

def engine = new MarkupTemplateEngine(config)

294

295

// HTML template

296

def htmlTemplate = '''

297

html {

298

head {

299

title(pageTitle)

300

meta(charset: 'UTF-8')

301

}

302

body {

303

h1(pageTitle)

304

div(class: 'content') {

305

p("Welcome, $userName!")

306

307

if (showUserList) {

308

ul {

309

users.each { user ->

310

li {

311

a(href: "/user/$user.id", user.name)

312

span(" (${user.email})")

313

}

314

}

315

}

316

}

317

318

div(class: 'footer') {

319

p("Generated on ${new Date()}")

320

}

321

}

322

}

323

}

324

'''

325

326

def template = engine.createTemplate(htmlTemplate)

327

def binding = [

328

pageTitle: "User Dashboard",

329

userName: "Alice",

330

showUserList: true,

331

users: [

332

[id: 1, name: "Bob", email: "bob@example.com"],

333

[id: 2, name: "Charlie", email: "charlie@example.com"]

334

]

335

]

336

337

def html = template.make(binding)

338

println html.toString()

339

340

// Type-checked template

341

def typedTemplate = engine.createTypeCheckedTemplate('''

342

html {

343

body {

344

h1(title)

345

p("User count: $users.size()")

346

users.each { user ->

347

div {

348

yield "Name: $user.name, Age: $user.age"

349

}

350

}

351

}

352

}

353

''', [

354

title: 'String',

355

users: 'List<Map<String,Object>>'

356

])

357

```

358

359

### Template Exceptions

360

361

Exception classes for template processing errors.

362

363

```groovy { .api }

364

/**

365

* Exception thrown during template execution

366

*/

367

class TemplateExecutionException extends RuntimeException {

368

TemplateExecutionException(String message)

369

TemplateExecutionException(String message, Throwable cause)

370

371

/** Get line number where error occurred */

372

int getLineNumber()

373

374

/** Get column number where error occurred */

375

int getColumnNumber()

376

377

/** Get template source name */

378

String getSourceName()

379

}

380

381

/**

382

* Exception thrown during template parsing

383

*/

384

class TemplateParseException extends RuntimeException {

385

TemplateParseException(String message)

386

TemplateParseException(String message, Throwable cause)

387

388

/** Get line number where error occurred */

389

int getLineNumber()

390

391

/** Get column number where error occurred */

392

int getColumnNumber()

393

}

394

```

395

396

**Usage Examples:**

397

398

```groovy

399

import groovy.text.*

400

401

def engine = new SimpleTemplateEngine()

402

403

try {

404

// Template with syntax error

405

def template = engine.createTemplate('Hello ${ invalid syntax }')

406

def result = template.make([:])

407

} catch (TemplateParseException e) {

408

println "Parse error at line ${e.lineNumber}, column ${e.columnNumber}: ${e.message}"

409

}

410

411

try {

412

// Template with runtime error

413

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

414

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

415

println result.toString()

416

} catch (TemplateExecutionException e) {

417

println "Execution error: ${e.message}"

418

println "At line ${e.lineNumber} in ${e.sourceName}"

419

}

420

```

421

422

## Advanced Template Features

423

424

### Custom Template Base Classes

425

426

Create custom base classes for templates with additional functionality.

427

428

```groovy

429

// Custom base template class

430

abstract class CustomBaseTemplate extends Template {

431

// Helper methods available in all templates

432

String formatDate(Date date) {

433

return date.format('yyyy-MM-dd')

434

}

435

436

String formatCurrency(BigDecimal amount) {

437

return String.format('$%.2f', amount)

438

}

439

440

String truncate(String text, int length) {

441

return text.length() > length ? text[0..length-1] + '...' : text

442

}

443

}

444

445

// Use custom base class

446

def config = new TemplateConfiguration()

447

.baseTemplateClass(CustomBaseTemplate)

448

449

def engine = new MarkupTemplateEngine(config)

450

451

def template = engine.createTemplate('''

452

div {

453

p("Order Date: ${formatDate(order.date)}")

454

p("Total: ${formatCurrency(order.total)}")

455

p("Description: ${truncate(order.description, 50)}")

456

}

457

''')

458

```

459

460

### Template Includes and Layouts

461

462

```groovy

463

// Layout template

464

def layoutTemplate = '''

465

html {

466

head {

467

title(pageTitle)

468

meta(charset: 'UTF-8')

469

if (stylesheets) {

470

stylesheets.each { css ->

471

link(rel: 'stylesheet', href: css)

472

}

473

}

474

}

475

body {

476

header {

477

h1(pageTitle)

478

}

479

main {

480

yieldUnescaped content

481

}

482

footer {

483

p("© 2023 Company Name")

484

}

485

}

486

}

487

'''

488

489

// Content template

490

def contentTemplate = '''

491

div(class: 'user-profile') {

492

h2("User Profile")

493

p("Name: $user.name")

494

p("Email: $user.email")

495

496

if (user.projects) {

497

h3("Projects")

498

ul {

499

user.projects.each { project ->

500

li(project.name)

501

}

502

}

503

}

504

}

505

'''

506

507

// Render with layout

508

def layoutEngine = new MarkupTemplateEngine()

509

def layout = layoutEngine.createTemplate(layoutTemplate)

510

511

def contentEngine = new MarkupTemplateEngine()

512

def content = contentEngine.createTemplate(contentTemplate)

513

514

def contentResult = content.make([user: userData])

515

def finalResult = layout.make([

516

pageTitle: "User Profile",

517

stylesheets: ['/css/main.css', '/css/profile.css'],

518

content: contentResult.toString()

519

])

520

```