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 {

    FontAwesomeTemplate(
        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.
        $//$
    }

}

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([:])
output.writeTo(writer)
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 = $/\\

\\

\\

\\

\\

This is a  home icon.

\\

This is a  settings icon.

\\
/$

assert result == expected

Code written with Groovy 2.3.6.

Original article

shadow-left