CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-codehaus-groovy--groovy-templates

Groovy templating engines providing JSP-style scripting, GString expressions, markup builders, and streaming template capabilities for generating dynamic content from templates with variable substitution and control flow

Pending
Overview
Eval results
Files

xml-template-engine.mddocs/

XML Template Engine

The XmlTemplateEngine is designed for scenarios where both the template source and expected output are XML. It provides special GSP (Groovy Server Pages) tags for embedding code and expressions while maintaining well-formed XML structure.

API

class XmlTemplateEngine extends TemplateEngine {
    XmlTemplateEngine() throws SAXException, ParserConfigurationException;
    XmlTemplateEngine(String indentation, boolean validating) throws SAXException, ParserConfigurationException;
    XmlTemplateEngine(XmlParser xmlParser, ClassLoader parentLoader);
    XmlTemplateEngine(XmlParser xmlParser, GroovyShell groovyShell);
    
    Template createTemplate(Reader reader) throws CompilationFailedException, ClassNotFoundException, IOException;
    void setIndentation(String indentation);
    String getIndentation();
    void setConfigurePrinter(Closure configurePrinter);
    
    // Constants
    static final String DEFAULT_INDENTATION = "  ";
}

Template Syntax

GSP Tags

  • <gsp:scriptlet>...</gsp:scriptlet> - Execute Groovy code fragments
  • <gsp:expression>...</gsp:expression> - Output expression results
  • GString expressions: ${...} and $variable - Variable interpolation within text content

XML Processing Features

  • Comments and processing instructions removed during processing
  • Special XML characters (<, >, ", ') are automatically escaped
  • Output is automatically indented using standard XML pretty printing
  • Namespace definitions for gsp: tags are removed from output
  • Other namespace definitions are preserved but may change position

Usage Examples

Basic XML Template

import groovy.text.XmlTemplateEngine;
import groovy.text.Template;
import java.util.HashMap;
import java.util.Map;

XmlTemplateEngine engine = new XmlTemplateEngine();

String templateText = """
<?xml version="1.0" encoding="UTF-8"?>
<document xmlns:gsp='http://groovy.codehaus.org/2005/gsp' xmlns:foo='baz' type='letter'>
  <gsp:scriptlet>def greeting = "${salutation}est"</gsp:scriptlet>
  <gsp:expression>greeting</gsp:expression>
  <foo:to>$firstname "$nickname" $lastname</foo:to>
  How are you today?
</document>
""";

Template template = engine.createTemplate(templateText);

Map<String, Object> binding = new HashMap<>();
binding.put("firstname", "Jochen");
binding.put("lastname", "Theodorou");
binding.put("nickname", "blackdrag");
binding.put("salutation", "Dear");

String result = template.make(binding).toString();

Output:

<document type='letter'>
Dearest
<foo:to xmlns:foo='baz'>
  Jochen "blackdrag" Theodorou
</foo:to>
How are you today?
</document>

Custom Indentation

// Custom indentation (4 spaces instead of default 2)
XmlTemplateEngine engine = new XmlTemplateEngine("    ", false);

// Or set indentation after creation
engine.setIndentation("\t"); // Use tabs

Validating Parser

// Enable XML validation during parsing
XmlTemplateEngine engine = new XmlTemplateEngine("  ", true);

Custom XML Parser and Class Loader

import groovy.xml.XmlParser;

XmlParser customParser = new XmlParser();
customParser.setTrimWhitespace(false); // Preserve whitespace
ClassLoader customLoader = MyClass.class.getClassLoader();

XmlTemplateEngine engine = new XmlTemplateEngine(customParser, customLoader);

Custom Printer Configuration

XmlTemplateEngine engine = new XmlTemplateEngine();

// Configure the XML printer
engine.setConfigurePrinter(new Closure<Void>(this) {
    public void doCall(Object printer) {
        // printer is a GspPrinter instance
        ((groovy.text.XmlTemplateEngine.GspPrinter) printer).setPreserveWhitespace(true);
    }
});

Complex Template with Conditional Logic

String templateText = """
<?xml version="1.0" encoding="UTF-8"?>
<report xmlns:gsp='http://groovy.codehaus.org/2005/gsp'>
  <header>
    <title>$reportTitle</title>
    <date><gsp:expression>new Date().format('yyyy-MM-dd')</gsp:expression></date>
  </header>
  <body>
    <gsp:scriptlet>
      def totalAmount = items.sum { it.price * it.quantity }
    </gsp:scriptlet>
    
    <items>
      <gsp:scriptlet>
        items.each { item ->
          out.println("<item>")
          out.println("  <name>${item.name}</name>")
          out.println("  <price>${item.price}</price>")
          out.println("  <quantity>${item.quantity}</quantity>")
          out.println("</item>")
        }
      </gsp:scriptlet>
    </items>
    
    <summary>
      <total>$totalAmount</total>
      <gsp:scriptlet>
        if (totalAmount > 1000) {
          out.println("<discount>10%</discount>")
        }
      </gsp:scriptlet>
    </summary>
  </body>
</report>
""";

Map<String, Object> binding = new HashMap<>();
binding.put("reportTitle", "Sales Report");
binding.put("items", Arrays.asList(
    Map.of("name", "Widget A", "price", 25.50, "quantity", 10),
    Map.of("name", "Widget B", "price", 15.75, "quantity", 5)
));

Error Handling

import org.xml.sax.SAXException;
import javax.xml.parsers.ParserConfigurationException;

try {
    XmlTemplateEngine engine = new XmlTemplateEngine();
    Template template = engine.createTemplate(xmlTemplateSource);
    String result = template.make(binding).toString();
} catch (SAXException e) {
    // XML parsing error
    System.err.println("XML parsing failed: " + e.getMessage());
} catch (ParserConfigurationException e) {
    // XML parser configuration error
    System.err.println("XML parser configuration error: " + e.getMessage());
} catch (RuntimeException e) {
    // Unsupported GSP tag or other runtime error
    if (e.getMessage().contains("Unsupported 'gsp:' tag")) {
        System.err.println("Invalid GSP tag: " + e.getMessage());
    } else {
        throw e;
    }
}

Servlet Integration

The XmlTemplateEngine can be used with TemplateServlet for web applications:

<!-- web.xml -->
<servlet>
  <servlet-name>XmlTemplate</servlet-name>
  <servlet-class>groovy.servlet.TemplateServlet</servlet-class>
  <init-param>
    <param-name>template.engine</param-name>
    <param-value>groovy.text.XmlTemplateEngine</param-value>
  </init-param>
</servlet>

Best Practices

Template Structure

  1. Always include XML declaration for proper encoding handling
  2. Use proper namespace declaration for GSP tags: xmlns:gsp='http://groovy.codehaus.org/2005/gsp'
  3. Keep GSP tags minimal - complex logic should be in scriptlets
  4. Use expressions for simple output and scriptlets for complex logic

Performance Considerations

  1. Reuse engine instances when possible
  2. Cache compiled templates for frequently used templates
  3. Use appropriate indentation settings - simpler indentation is faster
  4. Disable validation for templates you trust to improve performance

XML Escaping

The engine automatically escapes special XML characters in text content, but not within GString expressions. If you need to output literal XML characters within expressions, handle escaping manually:

String templateText = """
<message>
  <content>User said: ${userInput}</content>  <!-- Automatically escaped -->
  <raw><gsp:expression>groovy.xml.XmlUtil.escapeXml(rawContent)</gsp:expression></raw>  <!-- Manual escaping -->
</message>
""";

Install with Tessl CLI

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

docs

basic-template-engines.md

index.md

markup-template-engine.md

streaming-template-engine.md

xml-template-engine.md

tile.json