[groovy-user] SimpleTemplateEngine and static imports

207 views
Skip to first unread message

Erik Pragt

unread,
Jan 15, 2011, 3:51:36 PM1/15/11
to us...@groovy.codehaus.org
Hi all,

I'm trying to use the SimpleTemplateEngine in combination with some static imports to capitalize some words, like this:

import static org.apache.commons.lang.WordUtils.capitalize

import groovy.text.SimpleTemplateEngine

def text = 'Dear "${capitalize(\'erik\')} $lastname",\nSo nice to meet you in <% print city %>.\nSee you in ${month},\n${signed}'

def binding = ["firstname":"Sam", "lastname":"Pullara", "city":"San Francisco", "month":"December", "signed":"Groovy-Dev"]

def engine = new SimpleTemplateEngine()
template = engine.createTemplate(text).make(binding)

def result = 'Dear "Sam Pullara",\nSo nice to meet you in San Francisco.\nSee you in December,\nGroovy-Dev'

assert result == template.toString()

This doesn't work, because it cannot find the capitalize method:

groovy.lang.MissingMethodException: No signature of method: SimpleTemplateScript14.capitalize() is applicable for argument types: (java.lang.String) values: [erik]
        at SimpleTemplateScript14.run(SimpleTemplateScript14.groovy:2)
        at groovy.text.SimpleTemplateEngine$SimpleTemplate$1.writeTo(SimpleTemplateEngine.java:164)
        at groovy.text.SimpleTemplateEngine$SimpleTemplate$1.toString(SimpleTemplateEngine.java:176)
        at ConsoleScript15.run(ConsoleScript15:14)

Whenever I use the fully qualified name, it works, but importing brings me no luck, even though it's nicely advertised on the documentation page: http://groovy.codehaus.org/Groovy+Templates

For what it's worth, I've tried it with the Groovy which comes with Grails 1.3.2.

Kind regards,

Erik Pragt

Roshan Dawrani

unread,
Jan 15, 2011, 11:07:39 PM1/15/11
to us...@groovy.codehaus.org
Confirmed the issue on 1.7.6 too.

Since the documentation clearly says that it should work, it makes it a bug.

Static imports have been changing quite dynamically in recent past, so maybe some regression there.
--
Roshan
Blog: http://roshandawrani.wordpress.com/
Twitter: @roshandawrani
Skype: roshandawrani

   
 
       
 
 

Erik Pragt

unread,
Jan 17, 2011, 5:11:37 PM1/17/11
to us...@groovy.codehaus.org
Hi Roshan,

Should I file a JIRA for this?

Erik

roshan...@gmail.com

unread,
Jan 17, 2011, 7:55:32 PM1/17/11
to us...@groovy.codehaus.org
Hi Erik,

Yes, please do.

Cheers.

---------------------------------------------------
Sent from BlackBerry


From: Erik Pragt <erik....@gmail.com>
Date: Mon, 17 Jan 2011 23:11:37 +0100
Subject: Re: [groovy-user] SimpleTemplateEngine and static imports

Erik Pragt

unread,
Feb 7, 2011, 3:53:48 PM2/7/11
to us...@groovy.codehaus.org
Hi Roshan,

I finally filed a bug for this:


Kind regards,

Erik Pragt

Cédric CHAMPEAU

unread,
Feb 8, 2011, 2:45:55 AM2/8/11
to us...@groovy.codehaus.org
I've checked an eye on this issue. It's not especially related to static imports : any import made in the caller won't be made available to the template engine (I would have been surprised that it worked). So I guess that when the documentation states that you should have set a static import, it means *inside* the template. There are two workarounds for this :

1. export the capitalize function in the binding :
    def binding = ["firstname":"Sam", "lastname":"Pullara", "city":"San Francisco", "month":"December", "signed":"Groovy-Dev", "capitalize":  org.apache.commons.lang.WordUtils.&capitalize]

2. add a static import *in* the template (just like you would add imports in a JSP) :

    def text = '<% import static org.apache.commons.lang.WordUtils.capitalize %>Dear "${capitalize(\'erik\')} $lastname",\nSo nice to meet you in <% print city %>.\nSee you in ${month},\n${signed}'

Whatever suits your needs.

Cédric

Xiaoping Jia

unread,
Jul 7, 2011, 9:18:35 PM7/7/11
to us...@groovy.codehaus.org
Hi,

It seems neither of the suggested solutions works in 1.8.0. The only way
that works is to use the fully qualified names.

Is this a regression in 1.8?

Best regards,

Xiaoping Jia

> > > __________________________________________________________________

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email


Cédric Champeau

unread,
Jul 8, 2011, 3:28:05 AM7/8/11
to us...@groovy.codehaus.org
Can you paste an example which does not work in 1.8 ?

Thanks,

Xiaoping Jia

unread,
Jul 8, 2011, 10:53:47 AM7/8/11
to us...@groovy.codehaus.org
Hi, Cédric,

I attach a simple test and the output of the test runs. There are 4
tests, only test3() works. I tested with both SimpleTemplateEngine and
GStringTemplateEngine. Note that the exceptions thrown by the two
engines are different for test2()

Thanks!

Xiaoping

TemplateTest.groovy
Util.groovy
output.txt

Cédric Champeau

unread,
Jul 8, 2011, 11:21:15 AM7/8/11
to us...@groovy.codehaus.org
Did it work in Groovy 1.7 ? If so, it's a regression. If not, anyway, you should file a JIRA issue for this. As a workaround, you can add the following setup line :

Binding.metaClass.methodMissing = { String name, args -> delegate[name](args) }

The problem is that the template engine uses a Binding class internally instead of a map, and Binding doesn't support method calls like Map does. I tested the workaround with success.
Reply all
Reply to author
Forward
0 new messages