Generic Top

I just announced the new Learn Spring course, focused on the fundamentals of Spring 5 and Spring Boot 2:

>> CHECK OUT THE COURSE

1. Overview

In this introductory tutorial, we’ll explore the concept of template engines in Groovy.

In Groovy, we can use GStrings to generate dynamic text easily. However, the template engines provide a better way of handling dynamic text using static templates.

These templates are convenient in defining static templates for various notifications like SMS and emails.

2. What is Groovy’s TemplateEngine?

Groovy’s TemplateEngine is an abstract class that contains the createTemplate method.

All template framework engines available in Groovy extend TemplateEngine and implement createTemplate. Additionally, every engine returns the Template interface object.

The Template interface has a method make, which takes a map for binding variables. Therefore, it must be implemented by every template framework.

Let’s discuss the functionality and behavior of all the available template frameworks in Groovy.

3. SimpleTemplateEngine

The SimpleTemplateEngine generates dynamic text using String interpolation and scriptlets. This engine is quite useful for simple notifications like SMS and simple text emails.

For example:

def smsTemplate = 'Dear <% print user %>, Thanks for reading our Article. ${signature}'
def bindMap = [user: "Norman", signature: "Baeldung"]
def smsText = new SimpleTemplateEngine().createTemplate(smsTemplate).make(bindMap)

assert smsText.toString() == "Dear Norman, Thanks for reading our Article. Baeldung"

4. StreamingTemplateEngine

In a general sense, the StreamingTemplateEngine works similarly to SimpleTemplateEngine. However, internally it uses Writable closures to generate a template.

For the same reason, it holds benefits when working over larger Strings(> 64K). Hence, it’s more efficient than SimpleTemplateEngine.

Let’s write a quick example to generate a dynamic email content using a static template.

Firstly, we’ll create a static articleEmail template:

Dear <% out << (user) %>,
Please read the requested article below.
<% out << (articleText) %>
From,
<% out << (signature) %>

Here, we’re using <% %> scriptlets for dynamic text and out for the writer.

Now, we’ll generate the content of an email using StreamingTemplateEngine:

def articleEmailTemplate = new File('src/main/resources/articleEmail.template')
def bindMap = [user: "Norman", signature: "Baeldung"]

bindMap.articleText = """1. Overview
This is a tutorial article on Template Engines...""" //can be a string larger than 64k

def articleEmailText = new StreamingTemplateEngine().createTemplate(articleEmailTemplate).make(bindMap)

assert articleEmailText.toString() == """Dear Norman,
Please read the requested article below.
1. Overview
This is a tutorial article on Template Engines...
From,
Baeldung"""

5. GStringTemplateEngine

As the name suggests, GStringTemplateEngine uses GString to generate dynamic text from static templates.

Firstly, let’s write a simple email template using GString:

Dear $user,
Thanks for subscribing our services.
${signature}

Now, we’ll use GStringTemplateEngine to create dynamic content:

def emailTemplate = new File('src/main/resources/email.template')
def emailText = new GStringTemplateEngine().createTemplate(emailTemplate).make(bindMap)

6. XmlTemplateEngine

The XmlTemplateEngine is useful when we want to create dynamic XML outputs. It requires XML schema as input and allows two special tags, <gsp:scriptlet> to inject script and <gsp:expression> to inject an expression.

For example, let’s convert the already discussed email template to XML:

def emailXmlTemplate = '''
<xs xmlns:gsp='groovy-server-pages'>
    <gsp:scriptlet>def emailContent = "Thanks for subscribing our services."</gsp:scriptlet>
    <email>
        <greet>Dear ${user}</greet>
        <content><gsp:expression>emailContent</gsp:expression></content>
        <signature>${signature}</signature>
    </email>
</xs>'''

def emailXml = new XmlTemplateEngine().createTemplate(emailXmlTemplate).make(bindMap)

Hence, the emailXml will have XML rendered, and the content will be:

<xs>
  <email>
    <greet>
      Dear Norman
    </greet>
    <content>
      Thanks for subscribing our services.
    </content>
    <signature>
      Baeldung
    </signature>
  </email>
</xs>

It’s interesting to note the XML output is indented and beautified itself by the template framework.

7. MarkupTemplateEngine

This template framework is a complete package to generate HTML and other markup languages.

Additionally, it uses Domain Specific Language to process the templates and is the most optimized among all template frameworks available in Groovy.

7.1. HTML

Let’s write a quick example to render HTML for the already discussed email template:

def emailHtmlTemplate = """
html {
    head {
        title('Service Subscription Email')
    }
    body {
        p('Dear Norman')
        p('Thanks for subscribing our services.')
        p('Baeldung')
    }
}"""
def emailHtml = new MarkupTemplateEngine().createTemplate(emailHtmlTemplate).make()

Therefore, the content of emailHtml will be:

<html><head><title>Service Subscription Email</title></head>
<body><p>Dear Norman</p><p>Thanks for subscribing our services.</p><p>Baeldung</p></body></html>

7.2. XML

Likewise, we can render XML:

def emailXmlTemplate = """
xmlDeclaration()  
    xs{
        email {
            greet('Dear Norman')
            content('Thanks for subscribing our services.')
            signature('Baeldung')
        }  
    }"""
def emailXml = new MarkupTemplateEngine().createTemplate(emailXmlTemplate).make()

Therefore, the content of emailXml will be:

<?xml version='1.0'?>
<xs><email><greet>Dear Norman</greet><content>Thanks for subscribing our services.</content>
<signature>Baeldung</signature></email></xs>

7.3. TemplateConfiguration

Note that unlike like XmlTemplateEngine, the template output of this framework is not indented and beautified by itself.

For such configuration, we’ll use the TemplateConfiguration class:

TemplateConfiguration config = new TemplateConfiguration()
config.autoIndent = true
config.autoEscape = true
config.autoNewLine = true
                               
def templateEngine = new MarkupTemplateEngine(config)

7.4. Internationalization

Additionally, the locale property of TemplateConfiguration is available to enable the support of internationalization.

Firstly, we’ll create a static template file email.tpl and copy the already discussed emailHtmlTemplate string into it. This will be treated as the default template.

Likewise, we’ll create locale-based template files like email_ja_JP.tpl for Japanese, email_fr_FR.tpl for French, etc.

Finally, all we need is to set the locale in the TemplateConfiguration object:

config.locale = Locale.JAPAN

Hence, the corresponding locale-based template will be picked.

8. Conclusion

In this article, we’ve seen various template frameworks available in Groovy.

We can leverage these handy template engines to generate dynamic text using static templates. Therefore, they can be helpful in the dynamic generation of various kinds of notifications or on-screen messages and errors.

As usual, the code implementations of this tutorial are available on the GitHub project.

Generic bottom

I just announced the new Learn Spring course, focused on the fundamentals of Spring 5 and Spring Boot 2:

>> CHECK OUT THE COURSE