Reputation: 2146
I have a custom tag called <mk:pageViewTag>
which first renders .gsp
template and then executes its body inside:
Taglib (UtilTagLib.groovy):
string namespace = "mk"
def pageViewTag = { attrs, body ->
out << render(template: '/templates/pageTagView') {
body()
}
}
...
Template I render (templates/_pageTagView.gsp):
<body>
${ body() }
...
</body>
GSP I use custom tag on (test.gsp):
<mk:pageViewTag>
<g:set name="test" value="${1}">
${test?:0} %{--Here, I got 0. Variable test does not exist!--}%
</mk:pageViewTag>
Everything works perfectly except for <g:set>
tag, which does not perform as I expect. Grails simply cannot see the variable I declare.
In the example above I declared variable test
and initialized it with integer 1
. As an output I got 0
.
According to Grails Docs I can use scope
attribute, and it solves the problem when set to request
.
Are there any ways I can fix it otherwise? Why this happens?
NB: The inside of mk:pageViewTag
is huge so I cannot just declare a variable anywhere outside.
Upvotes: 2
Views: 1486
Reputation: 114
I declared a grails variable inside a template and used it in the parent gsp file (where the template is included).
Ex: Parent.gsp includes template: _child.gsp which has "<g:set var="a" value="${1}" />
". Printing the variable 'a' in Parent.gsp renders a "null".
Hence we found that while inserting templates with variables or set variables while rendering a template doesn't work. Because rendering a template takes time and is async with the Parent page.We can't be sure of the variable initialization until the rendering is completed.
If the scope is set to "request",then we say that this variable should be visible for the whole request cycle and they are stored in the request for further process or access.
Using <g:set var="a" value="${1}" scope='request'/>
or <g:set var="a" value="${1}" scope='session'/>
is recommended.
Refer these links of how to use scopes:
grails scope questions - page, request, flash
How to use grails <g:set> tag session scope?
Upvotes: 0
Reputation: 3216
g:set needs a var attribute not a name: http://grails.org/doc/2.2.1/ref/Tags/set.html
Upvotes: 1
Reputation: 1043
string namespace = "mk"
def pageViewTag = { attrs, body ->
out << render(template: '/templates/pageTagView', model:[body: body()])
}
templates/_pageTagView.gsp :
<body>
${body}
...
</body>
Upvotes: 0
Reputation: 2146
Not perfect, but quick solution that does not require tricks (well, almost).
I execute body
first and then I include it as template body.
Taglib (UtilTagLib.groovy):
string namespace = "mk"
def pageViewTag = { attrs, body ->
// Render body ahead!
String renderedBody = body()
out << render(template: '/templates/pageTagView') {
renderedBody
}
}
...
Upvotes: 1