CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-codehaus-groovy--groovy-all

Apache Groovy - A powerful multi-faceted programming language for the JVM platform with comprehensive module support

Pending
Overview
Eval results
Files

templates.mddocs/

Template Processing

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

Template Engines

SimpleTemplateEngine

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

class SimpleTemplateEngine extends TemplateEngine {
    SimpleTemplateEngine()
    SimpleTemplateEngine(ClassLoader parentLoader)
    
    Template createTemplate(String templateText)
    Template createTemplate(File templateFile)
    Template createTemplate(URL templateURL)
    Template createTemplate(Reader reader)
}

Usage examples:

import groovy.text.SimpleTemplateEngine

def engine = new SimpleTemplateEngine()

// Simple variable substitution
def template = engine.createTemplate('Hello $name, you are $age years old.')
def binding = [name: 'John', age: 30]
def result = template.make(binding)
println result.toString()  // "Hello John, you are 30 years old."

// Embedded expressions
def template2 = engine.createTemplate('''
Dear $name,

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

Best regards,
The System
''')

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

// Embedded code blocks
def template3 = engine.createTemplate('''
<html>
<body>
<h1>User List</h1>
<ul>
<% users.each { user -> %>
  <li>${user.name} (${user.email})</li>
<% } %>
</ul>
</body>
</html>
''')

def users = [
    [name: 'John', email: 'john@example.com'],
    [name: 'Jane', email: 'jane@example.com']
]
def html = template3.make([users: users])
println html.toString()

GStringTemplateEngine

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

class GStringTemplateEngine extends TemplateEngine {
    GStringTemplateEngine()
    GStringTemplateEngine(ClassLoader parentLoader)
    
    Template createTemplate(String templateText)
    Template createTemplate(File templateFile)
    Template createTemplate(URL templateURL)
    Template createTemplate(Reader reader)
}

Usage example:

import groovy.text.GStringTemplateEngine

def engine = new GStringTemplateEngine()

def template = engine.createTemplate('''
Report for $title
Generated on ${new Date().format('yyyy-MM-dd')}

Summary:
- Total items: ${items.size()}
- Average value: ${items.sum { it.value } / items.size()}
- Maximum value: ${items.max { it.value }.value}

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

def data = [
    title: 'Monthly Sales',
    items: [
        [name: 'Product A', value: 100],
        [name: 'Product B', value: 250],
        [name: 'Product C', value: 175]
    ]
]

def report = template.make(data)
println report.toString()

XmlTemplateEngine

Template engine specifically designed for XML generation with proper escaping.

class XmlTemplateEngine extends TemplateEngine {
    XmlTemplateEngine()
    XmlTemplateEngine(ClassLoader parentLoader)
    
    Template createTemplate(String templateText)
    Template createTemplate(File templateFile)
    Template createTemplate(URL templateURL)
    Template createTemplate(Reader reader)
}

Usage example:

import groovy.text.XmlTemplateEngine

def engine = new XmlTemplateEngine()

def template = engine.createTemplate('''
<catalog>
  <title>$title</title>
  <books>
    <% books.each { book -> %>
    <book id="$book.id">
      <title>$book.title</title>
      <author>$book.author</author>
      <price currency="USD">$book.price</price>
      <description>$book.description</description>
    </book>
    <% } %>
  </books>
</catalog>
''')

def catalog = [
    title: 'Programming Books',
    books: [
        [
            id: 1,
            title: 'Groovy in Action',
            author: 'Dierk König',
            price: 49.99,
            description: 'Comprehensive guide to Groovy & dynamic languages'
        ],
        [
            id: 2, 
            title: 'Programming Groovy 2',
            author: 'Venkat Subramaniam',
            price: 44.99,
            description: 'Practical guide with examples & best practices'
        ]
    ]
]

def xml = template.make(catalog)
println xml.toString()

StreamingTemplateEngine

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

class StreamingTemplateEngine extends TemplateEngine {
    StreamingTemplateEngine()
    StreamingTemplateEngine(String staticText, String expressionText)
    StreamingTemplateEngine(ClassLoader parentLoader)
    
    Template createTemplate(String templateText)
    Template createTemplate(File templateFile)
    Template createTemplate(URL templateURL)
    Template createTemplate(Reader reader)
}

Usage example:

import groovy.text.StreamingTemplateEngine

def engine = new StreamingTemplateEngine()

def template = engine.createTemplate('''
<html>
<head><title>Large Report</title></head>
<body>
<h1>Data Report</h1>
<table>
<tr><th>ID</th><th>Name</th><th>Value</th></tr>
<% data.each { item -> %>
<tr><td>$item.id</td><td>$item.name</td><td>$item.value</td></tr>
<% } %>
</table>
</body>
</html>
''')

// Generate large dataset
def largeData = (1..10000).collect { i ->
    [id: i, name: "Item $i", value: Math.random() * 1000]
}

// Stream output to file
new File('report.html').withWriter { writer ->
    def result = template.make([data: largeData])
    result.writeTo(writer)
}

Template Interface

Template

Base interface for all template implementations.

interface Template {
    Writable make()
    Writable make(Map binding)
}

Writable

Interface for objects that can write themselves to a Writer.

interface Writable {
    Writer writeTo(Writer out)
}

Usage example:

def template = engine.createTemplate('Hello $name!')
def writable = template.make([name: 'World'])

// Write to different outputs
println writable.toString()                    // To string
writable.writeTo(System.out)                   // To console
new File('output.txt').withWriter { writer ->
    writable.writeTo(writer)                   // To file
}

Advanced Template Features

Custom Delimiters

import groovy.text.SimpleTemplateEngine

// Custom template with different delimiters
def engine = new SimpleTemplateEngine()
def customTemplate = '''
Report: <%=title%>
Date: <%=new Date().format('yyyy-MM-dd')%>

<% items.each { item -> %>
Item: <%=item.name%> - <%=item.value%>
<% } %>
'''

// Note: Use StreamingTemplateEngine for custom delimiters
def streamingEngine = new StreamingTemplateEngine('<%', '%>')
def template = streamingEngine.createTemplate(customTemplate)
def result = template.make([
    title: 'Custom Report',
    items: [[name: 'A', value: 100], [name: 'B', value: 200]]
])
println result.toString()

Template Caching

import groovy.text.SimpleTemplateEngine

class CachedTemplateEngine {
    private final SimpleTemplateEngine engine = new SimpleTemplateEngine()
    private final Map<String, Template> cache = [:]
    
    Template getTemplate(String templateText) {
        return cache.computeIfAbsent(templateText) { text ->
            engine.createTemplate(text)
        }
    }
    
    String process(String templateText, Map binding) {
        return getTemplate(templateText).make(binding).toString()
    }
}

def cachedEngine = new CachedTemplateEngine()

// Templates are cached for reuse
def template1 = 'Hello $name, today is ${new Date().format("yyyy-MM-dd")}'
println cachedEngine.process(template1, [name: 'Alice'])
println cachedEngine.process(template1, [name: 'Bob'])  // Uses cached template

Template Inheritance

import groovy.text.SimpleTemplateEngine

// Base template
def baseTemplate = '''
<html>
<head>
    <title>$title</title>
    <style>
        body { font-family: Arial, sans-serif; }
        .content { margin: 20px; }
    </style>
</head>
<body>
    <div class="content">
        $content
    </div>
</body>
</html>
'''

// Content template
def contentTemplate = '''
<h1>$pageTitle</h1>
<p>$message</p>
<ul>
<% items.each { item -> %>
    <li>$item</li>
<% } %>
</ul>
'''

def engine = new SimpleTemplateEngine()

// Generate content first
def content = engine.createTemplate(contentTemplate).make([
    pageTitle: 'Welcome',
    message: 'This is the main content.',
    items: ['Feature 1', 'Feature 2', 'Feature 3']
]).toString()

// Apply to base template
def finalPage = engine.createTemplate(baseTemplate).make([
    title: 'My Website',
    content: content
]).toString()

println finalPage

Template with Includes

import groovy.text.SimpleTemplateEngine

class TemplateManager {
    private final SimpleTemplateEngine engine = new SimpleTemplateEngine()
    private final Map<String, String> templates = [:]
    
    void defineTemplate(String name, String content) {
        templates[name] = content
    }
    
    String include(String templateName, Map binding = [:]) {
        def templateContent = templates[templateName]
        if (!templateContent) {
            throw new IllegalArgumentException("Template '$templateName' not found")
        }
        return engine.createTemplate(templateContent).make(binding).toString()
    }
    
    String process(String templateContent, Map binding) {
        // Add include function to binding
        binding.include = this.&include
        return engine.createTemplate(templateContent).make(binding).toString()
    }
}

def manager = new TemplateManager()

// Define reusable templates
manager.defineTemplate('header', '''
<header>
    <h1>$title</h1>
    <nav>
        <a href="/home">Home</a>
        <a href="/about">About</a>
    </nav>
</header>
''')

manager.defineTemplate('footer', '''
<footer>
    <p>&copy; $year $company. All rights reserved.</p>
</footer>
''')

// Main template using includes
def mainTemplate = '''
<html>
<body>
    ${include('header', [title: pageTitle])}
    
    <main>
        <h2>$contentTitle</h2>
        <p>$content</p>
    </main>
    
    ${include('footer', [year: year, company: company])}
</body>
</html>
'''

def result = manager.process(mainTemplate, [
    pageTitle: 'My Website',
    contentTitle: 'Welcome',
    content: 'This is the main content of the page.',
    year: 2023,
    company: 'My Company'
])

println result

Error Handling

Template Compilation Errors

import groovy.text.SimpleTemplateEngine

try {
    def engine = new SimpleTemplateEngine()
    // Invalid template syntax
    def template = engine.createTemplate('Hello $name, <% invalid groovy code %>')
} catch (Exception e) {
    println "Template compilation error: ${e.message}"
    // Handle compilation errors
}

Runtime Template Errors

try {
    def engine = new SimpleTemplateEngine()
    def template = engine.createTemplate('Hello $name.toUpperCase()!')
    
    // This will fail if name is null
    def result = template.make([name: null])
    println result.toString()
    
} catch (Exception e) {
    println "Template execution error: ${e.message}"
    // Provide default values or error handling
    def safeTemplate = engine.createTemplate('Hello ${name?.toUpperCase() ?: "Guest"}!')
    def safeResult = safeTemplate.make([name: null])
    println safeResult.toString()  // "Hello Guest!"
}

Integration Patterns

Web Template Integration

import groovy.text.SimpleTemplateEngine
import groovy.servlet.TemplateServlet

// Example servlet integration
class MyTemplateServlet extends TemplateServlet {
    
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) {
        def engine = new SimpleTemplateEngine()
        def template = engine.createTemplate(getTemplate('user-profile'))
        
        def user = getUserFromSession(request)
        def binding = [
            user: user,
            currentDate: new Date(),
            contextPath: request.contextPath
        ]
        
        response.contentType = 'text/html'
        template.make(binding).writeTo(response.writer)
    }
}

File-based Template System

import groovy.text.SimpleTemplateEngine

class FileTemplateSystem {
    private final File templateDir
    private final SimpleTemplateEngine engine = new SimpleTemplateEngine()
    
    FileTemplateSystem(String templateDirectory) {
        this.templateDir = new File(templateDirectory)
    }
    
    String render(String templateName, Map binding = [:]) {
        def templateFile = new File(templateDir, "${templateName}.gtpl")
        if (!templateFile.exists()) {
            throw new FileNotFoundException("Template not found: $templateName")
        }
        
        def template = engine.createTemplate(templateFile)
        return template.make(binding).toString()
    }
    
    void renderToFile(String templateName, String outputPath, Map binding = [:]) {
        def content = render(templateName, binding)
        new File(outputPath).text = content
    }
}

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

def emailContent = templateSystem.render('welcome-email', [
    userName: 'John Doe',
    activationLink: 'https://example.com/activate/123'
])

templateSystem.renderToFile('report', 'output/monthly-report.html', [
    reportDate: new Date(),
    data: getReportData()
])

Install with Tessl CLI

npx tessl i tessl/maven-org-codehaus-groovy--groovy-all

docs

ast-transforms.md

cli.md

core-language.md

index.md

json.md

sql.md

swing.md

templates.md

xml.md

tile.json