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

Managing a MongoDB deployment? Take a load off and live migrate to MongoDB Atlas, the official automated service, with little to no downtime.

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.

MongoDB Atlas is the easiest way to run the fastest-growing database for modern applications — no installation, setup, or configuration required. Easily live migrate an existing workload or start with 512MB of storage for free.


Published at DZone with permission of Hubert Klein Ikkink, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

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

{{ parent.tldr }}

{{ parent.urlSource.name }}