Reputation: 29377
Lets assume that I have the following configuration in my conf/InjectionConfig.groovy
file:
x {
a = { attrs, body -> out << "hello" }
b = { attrs, body -> out << "goodbye" }
}
and that I have a simple taglib such as
class XTagLib {
static namespace = "x"
}
What I want to do is that when I type <x:a />
to any of my views, it would print hello
. I've already tried to inject these to the metaclass of the taglib as both property and method but neither seem to work. As an example, here's basically what I'm doing right now in a service:
public void afterPropertiesSet() throws Exception {
GroovyClassLoader classLoader = new GroovyClassLoader(getClass().classLoader)
def slurper = new ConfigSlurper(GrailsUtil.environment)
ConfigObject xConfig
try {
xConfig = slurper.parse(classLoader.loadClass('InjectionConfig'))
}
catch (e) {
e.printStackTrace()
}
xConfig.x.each({
if ( !XTagLib.metaClass.hasMetaProperty(it.key) ) {
XTagLib.metaClass.registerBeanProperty(it.key, { args ->
def attrs = args[0], body = args[1]
it.value.call(attrs, body)
}
}
})
}
Am I just doing it wrong or is this even possible currently?
Upvotes: 4
Views: 637
Reputation: 13485
Well, this
def shell = new GroovyShell() // or get a GroovyClassLoader
Class yTagLibClass = shell.evaluate("class YTagLib { static namespace = 'x' }; return YTagLib")
yTagLibClass.metaClass.a = { attrs, body -> delegate.out << 'blabla' }
grailsApplication.addArtefact(TagLibArtefactHandler.TYPE, yTagLibClass)
<x:a/> nearly worked for me - registered a tag, except for it didn't output anything. You still need to make the closure resolve out
against Grails' taglib's out
property.
I don't see a pretty way to do it, as there's no access to instance variables, and out
is an instance variable. See Grails source, JspInvokeGrailsTagLibTag.doStartTagInternal() - you might find a way.
EDIT: I added delegate.
prefix that should resolve out
property of target object. Now I believe I deserve an acceptance :)
Upvotes: 2
Reputation: 10848
What I want to do is that when I type to any of my views, it would print hello
I think there's an alternative way to do what you intend: combine template & tagLib. First, create a template, then add it in your TagLib (with no complex configuration).
In my opinion, it's more simple than your approach.
Please take a look at this tutorial: http://jan-so.blogspot.com/2008/02/example-of-template-and-taglib-with.html
Upvotes: 1