GSP rendering programmatically
Suppose I have a gsp snippet stored in my database. How do I programmatically merge it with a 开发者_如何学Pythondata model to produce a string.
The applicationContext of any Grails app contains a bean named
groovyPagesTemplateEngine
By default this is a instance of GroovyPagesTemplateEngine. So you might use code like this in your controller or service:
class MyService/MyController {
def groovyPagesTemplateEngine
String renderGSPToString(String uri, Map model) {
groovyPagesTemplateEngine.createTemplate(uri).make(model).toString()
}
}
NB: this snippet is not really taken from running code, it should just clarify the idea.
I found a DIRTY (but working) way of rendering complex gsps offline using groovyPageRenderer with substituted scriptsource. In that case you have access to all gsp syntax including g:if
etc..
First define two dummy classes:
class StringPageLocator extends GrailsConventionGroovyPageLocator {
GroovyPageScriptSource findViewByPath(String content) {
return new StringScriptSource(content)
}
}
class StringScriptSource implements GroovyPageScriptSource{
String content
public StringScriptSource(String content) {
this.content=content
}
@Override String suggestedClassName() { "DummyName" }
@Override boolean isPublic() { true }
@Override String getScriptAsString() { return content }
@Override boolean isModified() { true }
@Override String getURI() { "DummyURI" }
}
And then you can use it as such:
def groovyPageLocator // Injected automaticaly to service/controller etc...
groovyPageRenderer.groovyPageLocator=new StringPageLocator()
String output=groovyPageRenderer.render(
view:'Hello2 ${user} <g:if test="${test}">TRUE!!!</g:if>',
model:[user:'test user2',test:true]
)
You can make a controller method that does what you want. Then you will have an HTTP api to accomplish what you want. The controller method's template will have a <g:render>
tag, appropriately parameterized.
精彩评论