Over a million developers have joined DZone.

Groovy Goodness: Use Custom Template Class with MarkupTemplateEngine

DZone's Guide to

Groovy Goodness: Use Custom Template Class with MarkupTemplateEngine

· Java Zone ·
Free Resource

The CMS developers love. Open Source, API-first and Enterprise-grade. Try BloomReach CMS for free.

Since Groovy 2.3 we can use the new MarkupTemplateEngine to generate XML/HTML content. The engine compiles the template for better performance and optionally provides type checking on model attributes used in the template. We can configure the template engine to use a custom base template class instead of the default BaseTemplate. In our custom template class we can add new methods that can be invoked from our template content.

Let's create a new base template class with an icon method to output valid FontAwesome markup:

// File: FontAwesomeTemplate.groovy
package com.mrhaki.groovy.tmpl

import groovy.text.markup.*
import groovy.text.*

abstract class FontAwesomeTemplate extends BaseTemplate {

        final MarkupTemplateEngine templateEngine, 
        final Map model, 
        final Map<String,String> modelTypes, 
        final TemplateConfiguration configuration) {
        super(templateEngine, model, modelTypes, configuration)

     * Generate FontAwesome markup. 
     * @param icon Name of the icon, will be prefixed with 'fa-'.
     * @param attributes Optional extra attributes, will be added to markup
     *                   and prefixed with 'fa-'.
     * @return Span element with class attribute value for FontAwesome
    String icon(final String icon, final String[] attributes = []) {
        // Prefix attribute names with fa-.
        final faAttributes = attributes.collect { "fa-$it" }

        // Create markup.
        $/<span class="fa fa-${icon} ${faAttributes.join(' ')}"></span>/$


Now we can create a new MarkupTemplateEngine and use our FontAwesomeTemplate class as the base template. We assign our template class to the baseTemplateClass property of TemplateConfiguration:

import com.mrhaki.groovy.tmpl.*
import groovy.text.*
import groovy.text.markup.*

// Create configuration and set 
// base template class to
// FontAwesomeTemplate.
TemplateConfiguration config = new TemplateConfiguration(
    baseTemplateClass: FontAwesomeTemplate

// Create engine with configuration.
MarkupTemplateEngine engine = new MarkupTemplateEngine(config)     

// Create template with text using
// the icon method.
Template template = engine.createTemplate('''
    ul {
        // Use the name of the icon as argument
        // for the icon method.
        li icon('cloud')

        // Any extra arguments are assumed
        // to be FontAwesome attributes.
        li icon('pencil', 'large', 'rotate-90')

    // If we want to use the icon method in between
    // text we must use the ${stringOf notation}.
    p "This is a ${stringOf {icon('home')}} home icon."

    // Or use yieldUnescaped method.
    p {
        yield "This is a "
        yieldUnescaped icon('cog')
        yield " settings icon."


// Render output for template.
Writer writer = new StringWriter()                          
Writable output = template.make([:])  
String result = writer.toString()

// This is what we would expect as a result.
// (/ is the continuation character, so it is 
//  actually all one line)
def expected = $/\
<li><span class="fa fa-cloud "></span></li>\
<li><span class="fa fa-pencil fa-large fa-rotate-90"></span></li>\
<p>This is a <span class="fa fa-home "></span> home icon.</p>\
<p>This is a <span class="fa fa-cog "></span> settings icon.</p>\

assert result == expected

Code written with Groovy 2.3.6.

BloomReach CMS: the API-first CMS of the future. Open-source & enterprise-grade. - As a Java developer, you will feel at home using Maven builds and your favorite IDE (e.g. Eclipse or IntelliJ) and continuous integration server (e.g. Jenkins). Manage your Java objects using Spring Framework, write your templates in JSP or Freemarker. Try for free.


Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}