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. $/<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([:]) 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 = $/\ <ul>\ <li><span class="fa fa-cloud "></span></li>\ <li><span class="fa fa-pencil fa-large fa-rotate-90"></span></li>\ </ul>\ <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.