Extending the _Event system in Grails (Re: was something else I can't remember now)

View: New views
5 Messages — Rating Filter:   Alert me  
< Prev | 1 - 2 | Next >

Re: Proposed change to g:render

by Graeme Rocher-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Seems like a useful feature. Open a JIRA as a feature request. patches
welcome :-)

Cheers

On Wed, Jun 24, 2009 at 8:07 PM, Scott Burch<scott@...> wrote:

> Sorry about all of the messages, trying to provide as much info as possible.
>
> I modified the render closure to add the attributes to the map and I can now
> share the full solution from code I am doing right now.
>
>
> >From my gsp file.
> -----------------------
>
>       <sws:render template="block" title="Recent Blog Entries"
> titleLinkText="view all" titleLinkUrl="${createLink(url:[controller:'node',
> action:'showAll', type:'standardNode'])}">
>         <cms:nodeSummary />
>       </sws:render>
>       <sws:render template="block" title="Blog Archive">
>         <cms:nodeArchive />
>       </sws:render>
>
> _block.gsp
> ---------------
> <div class="block">
>   <div class="title">
>     <g:if test="${titleLinkText}">
>       <span class="titleLink">
>         (<a href="${titleLinkUrl}">${titleLinkText}</a>)
>       </span>
>     </g:if>
>     <span>${title}</span>
>   </div>
>
>   <div class="body">${body}</div>
> </div>
>
>
> New maybe hacky render code
> ----------------------------
>
>     def render = { attrs, body ->
>         if(!groovyPagesTemplateEngine) throw new
> IllegalStateException("Property [groovyPagesTemplateEngine] must be set!")
>         if(!attrs.template)
>             throwTagError("Tag [render] is missing required attribute
> [template]")
>
>         def engine = groovyPagesTemplateEngine
>         def uri = grailsAttributes.getTemplateUri(attrs.template,request)
>         def var = attrs['var']
>         def contextPath = attrs.contextPath ? attrs.contextPath : ""
>
>         if(attrs.plugin) {
>             def plugin = pluginManager?.getGrailsPlugin(attrs.plugin)
>             if(plugin && !plugin.isBasePlugin()) contextPath =
> plugin.getPluginPath()
>         }
>
>         Template t
>         if(TEMPLATE_CACHE.containsKey(uri) && !engine.isReloadEnabled()) {
>            t = TEMPLATE_CACHE[uri]
>         }
>         else {
>           def r = engine.getResourceForUri("${contextPath}${uri}")
>           if(!r.exists()) r =
> engine.getResourceForUri("${contextPath}/grails-app/views/
> ${uri}")
>           t = engine.createTemplate( r )
>           TEMPLATE_CACHE[uri] = t
>         }
>
> // temporarily I just added the attrs map to the map that will be passed to
> t.make()
>         def b = [body:body ? body() : ''] + attrs
>
>         if(attrs.containsKey('bean')) {
>             if (attrs.model instanceof Map) {
>                 b += attrs.model
>             }
>         if (var) {
>         b.put(var, attrs.bean)
>         }
>         else {
>         b.put('it', attrs.bean)
>         }
>         t.make(b).writeTo(out)
>         }
>         else if(attrs.containsKey('collection')) {
>             def collection = attrs.collection
>             def key = 'it'
>             if(collection) {
>                 def first = collection.iterator().next()
>                 key = first ?
> GrailsNameUtils.getPropertyName(first.getClass()) : 'it'
>             }
>             collection.each {
>                 if (attrs.model instanceof Map) {
>                     b += attrs.model
>                 }
>             if (var) {
>             b.put(var, it)
>             }
>             else {
>                     b.put('it', it)
>             b.put(key, it)
>             }
>             t.make(b).writeTo(out)
>             }
>         }
>         else if(attrs.model instanceof Map) {
>             t.make( b + attrs.model ).writeTo(out)
>         }
> else if(attrs.template) {
> t.make(b).writeTo(out)
> }
>     }
>
>
>
>
>
>
>
>
>
>
>
>
> On Wed, 2009-06-24 at 14:39 -0400, Scott Burch wrote:
>
> Sorry, that was supposed to be _block.gsp not _renderWithBody.gsp
>
> On Wed, 2009-06-24 at 14:33 -0400, Scott Burch wrote:
>> To take this one step further, maybe create a new tag that passes on the
>> attributes and the body, so you can have.
>>
>> <g:renderWithBody template='block' title='some title'>
>> block contents here
>> </g:renderWithBody>
>>
>> And render with body can have access to title
>>
>> _renderWithBody.gsp
>> ------------------------
>>
>> <div class='block'>
>> <h1>${title}</h1>
>> <div class='blockBody'><g:renderBody /></div>
>> </div>
>>
>> Or am I going too far?  Am I missing functionality that already exists?
>> Seems like applyLayout should do this, but it either takes a body or a
>> template with no body, it does not take a template AND a body.
>>
>>
>>
>> On Wed, 2009-06-24 at 14:06 -0400, Scott Burch wrote:
>> > Just for fun, I took the original code and modified it for g.render to
>> > make this behavior happen.
>> >
>> > I have not fully tested it, but here it is working at least with
>> > templates and models.
>> >
>> > Mainly I pulled def b out of each of the if statements.
>> > I then inserted body into the Map b
>> > I then made sure that b is always passed to t.make
>> >
>> > I think we should probably change the key from 'body' to something
>> > like 'renderBody' and we should make a tag that renders the body like
>> > <g:renderBody>
>> >
>> > What does everyone else think?
>> >
>> >
>> >
>> >     def render = { attrs, body ->
>> >         if(!groovyPagesTemplateEngine) throw new
>> > IllegalStateException("Property [groovyPagesTemplateEngine] must be set!")
>> >         if(!attrs.template)
>> >             throwTagError("Tag [render] is missing required attribute
>> > [template]")
>> >
>> >         def engine = groovyPagesTemplateEngine
>> >         def uri =
>> > grailsAttributes.getTemplateUri(attrs.template,request)
>> >         def var = attrs['var']
>> >         def contextPath = attrs.contextPath ? attrs.contextPath : ""
>> >
>> >         if(attrs.plugin) {
>> >             def plugin = pluginManager?.getGrailsPlugin(attrs.plugin)
>> >             if(plugin && !plugin.isBasePlugin()) contextPath =
>> > plugin.getPluginPath()
>> >         }
>> >
>> >         Template t
>> >         if(TEMPLATE_CACHE.containsKey(uri) && !engine.isReloadEnabled())
>> > {
>> >            t = TEMPLATE_CACHE[uri]
>> >         }
>> >         else {
>> >           def r = engine.getResourceForUri("${contextPath}${uri}")
>> >           if(!r.exists()) r =
>> > engine.getResourceForUri("${contextPath}/grails-app/views/${uri}")
>> >           t = engine.createTemplate( r )
>> >           TEMPLATE_CACHE[uri] = t
>> >         }
>> >
>> >         def b = [body:body ? body() : '']
>> >
>> >         if(attrs.containsKey('bean')) {
>> >             if (attrs.model instanceof Map) {
>> >                 b += attrs.model
>> >             }
>> >         if (var) {
>> >         b.put(var, attrs.bean)
>> >         }
>> >         else {
>> >         b.put('it', attrs.bean)
>> >        }
>> >         t.make(b).writeTo(out)
>> >         }
>> >         else if(attrs.containsKey('collection')) {
>> >             def collection = attrs.collection
>> >             def key = 'it'
>> >             if(collection) {
>> >                 def first = collection.iterator().next()
>> >                 key = first ?
>> > GrailsNameUtils.getPropertyName(first.getClass()) : 'it'
>> >             }
>> >             collection.each {
>> >                 if (attrs.model instanceof Map) {
>> >                     b += attrs.model
>> >                 }
>> >             if (var) {
>> >             b.put(var, it)
>> >             }
>> >             else {
>> >                     b.put('it', it)
>> >             b.put(key, it)
>> >             }
>> >             t.make(b).writeTo(out)
>> >             }
>> >         }
>> >         else if(attrs.model instanceof Map) {
>> >             t.make( b + attrs.model ).writeTo(out)
>> >         }
>> > else if(attrs.template) {
>> > t.make(b).writeTo(out)
>> > }
>> >     }
>> >
>> >
>> > On Wed, 2009-06-24 at 12:02 -0400, Scott Burch wrote:
>> > > Maybe to put it better.  It is a hybrid between applyLayout and render
>> > > with features of both.
>> > >
>> > > On Wed, 2009-06-24 at 11:29 -0400, Jeff Brown wrote:
>> > > > On Wed, Jun 24, 2009 at 11:00 AM, Scott Burch<scott@...>
>> > > > wrote:
>> > > > > I frequently want to use the g.render tag with a body.  Currently
>> > > > > I must
>> > > > > create a taglib entry and place the body in a attribute that is
>> > > > > passed
>> > > > > to g.render.
>> > > > >
>> > > > > Why not make this the default behavior of g.render?  Looking at
>> > > > > the code
>> > > > > for g.render it looks like adding attrs.body = body() would do the
>> > > > > trick.  Of course in the rendered template you can then just add
>> > > > > ${body}
>> > > > > wherever you want the body or we can create a tag that renders the
>> > > > > body
>> > > > > (like <g:renderBody>).
>> > > > >
>> > > > > What do people think?  Should this be added to g.render tag or
>> > > > > make a
>> > > > > separate tag for this?  Anyone have a better idea?
>> > > > >
>> > > > > Scott
>> > > > >
>> > > > >
>> > > >
>> > > > Can you show a simple use case that justifies the feature?
>> > > >
>> > > > Thanks for the help.
>> > > >
>> > > >
>> > > >
>> > > >
>> > > > Jeff
>> > > >
>> > >
>> > >
>> > > ---------------------------------------------------------------------
>> > > To unsubscribe from this list, please visit:
>> > >
>> > >     http://xircles.codehaus.org/manage_email
>> > >
>> > >
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe from this list, please visit:
>>
>>     http://xircles.codehaus.org/manage_email
>>
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
>     http://xircles.codehaus.org/manage_email
>
>
>



--
Graeme Rocher
Head of Grails Development
SpringSource - Weapons for the War on Java Complexity
http://www.springsource.com

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

    http://xircles.codehaus.org/manage_email



Re: Proposed change to g:render

by nycsailor :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Graeme or Anyone,

I am happy to supply patches, the code below was a sloppy POC so it
would be better code.

Here are the remaining questions.

1) Should I patch the existing render tag or create a new one?  I'm torn
on this because I am changing the functionality of the tag a bit so a
new one seems like the way to go, but I don't want to contribute to tag
bloat.

2) Should I patch so that any attribute, other than the ones already
included, is passed through as a variable?

3) If the answer is yes to 2, should those variables be passed through
as a map?  Say a map called 'attrs' so <g:render foo='bar'> is attrs.foo
in the template rather than just foo.

Anyone have any opinions before I get started?



On Thu, 2009-06-25 at 10:35 +0100, Graeme Rocher wrote:

> Seems like a useful feature. Open a JIRA as a feature request. patches
> welcome :-)
>
> Cheers
>
> On Wed, Jun 24, 2009 at 8:07 PM, Scott Burch<scott@...> wrote:
> > Sorry about all of the messages, trying to provide as much info as possible.
> >
> > I modified the render closure to add the attributes to the map and I can now
> > share the full solution from code I am doing right now.
> >
> >
> > >From my gsp file.
> > -----------------------
> >
> >       <sws:render template="block" title="Recent Blog Entries"
> > titleLinkText="view all" titleLinkUrl="${createLink(url:[controller:'node',
> > action:'showAll', type:'standardNode'])}">
> >         <cms:nodeSummary />
> >       </sws:render>
> >       <sws:render template="block" title="Blog Archive">
> >         <cms:nodeArchive />
> >       </sws:render>
> >
> > _block.gsp
> > ---------------
> > <div class="block">
> >   <div class="title">
> >     <g:if test="${titleLinkText}">
> >       <span class="titleLink">
> >         (<a href="${titleLinkUrl}">${titleLinkText}</a>)
> >       </span>
> >     </g:if>
> >     <span>${title}</span>
> >   </div>
> >
> >   <div class="body">${body}</div>
> > </div>
> >
> >
> > New maybe hacky render code
> > ----------------------------
> >
> >     def render = { attrs, body ->
> >         if(!groovyPagesTemplateEngine) throw new
> > IllegalStateException("Property [groovyPagesTemplateEngine] must be set!")
> >         if(!attrs.template)
> >             throwTagError("Tag [render] is missing required attribute
> > [template]")
> >
> >         def engine = groovyPagesTemplateEngine
> >         def uri = grailsAttributes.getTemplateUri(attrs.template,request)
> >         def var = attrs['var']
> >         def contextPath = attrs.contextPath ? attrs.contextPath : ""
> >
> >         if(attrs.plugin) {
> >             def plugin = pluginManager?.getGrailsPlugin(attrs.plugin)
> >             if(plugin && !plugin.isBasePlugin()) contextPath =
> > plugin.getPluginPath()
> >         }
> >
> >         Template t
> >         if(TEMPLATE_CACHE.containsKey(uri) && !engine.isReloadEnabled()) {
> >            t = TEMPLATE_CACHE[uri]
> >         }
> >         else {
> >           def r = engine.getResourceForUri("${contextPath}${uri}")
> >           if(!r.exists()) r =
> > engine.getResourceForUri("${contextPath}/grails-app/views/
> > ${uri}")
> >           t = engine.createTemplate( r )
> >           TEMPLATE_CACHE[uri] = t
> >         }
> >
> > // temporarily I just added the attrs map to the map that will be passed to
> > t.make()
> >         def b = [body:body ? body() : ''] + attrs
> >
> >         if(attrs.containsKey('bean')) {
> >             if (attrs.model instanceof Map) {
> >                 b += attrs.model
> >             }
> >         if (var) {
> >         b.put(var, attrs.bean)
> >         }
> >         else {
> >         b.put('it', attrs.bean)
> >        }
> >         t.make(b).writeTo(out)
> >         }
> >         else if(attrs.containsKey('collection')) {
> >             def collection = attrs.collection
> >             def key = 'it'
> >             if(collection) {
> >                 def first = collection.iterator().next()
> >                 key = first ?
> > GrailsNameUtils.getPropertyName(first.getClass()) : 'it'
> >             }
> >             collection.each {
> >                 if (attrs.model instanceof Map) {
> >                     b += attrs.model
> >                 }
> >             if (var) {
> >             b.put(var, it)
> >             }
> >             else {
> >                     b.put('it', it)
> >             b.put(key, it)
> >             }
> >             t.make(b).writeTo(out)
> >             }
> >         }
> >         else if(attrs.model instanceof Map) {
> >             t.make( b + attrs.model ).writeTo(out)
> >         }
> > else if(attrs.template) {
> > t.make(b).writeTo(out)
> > }
> >     }
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> > On Wed, 2009-06-24 at 14:39 -0400, Scott Burch wrote:
> >
> > Sorry, that was supposed to be _block.gsp not _renderWithBody.gsp
> >
> > On Wed, 2009-06-24 at 14:33 -0400, Scott Burch wrote:
> >> To take this one step further, maybe create a new tag that passes on the
> >> attributes and the body, so you can have.
> >>
> >> <g:renderWithBody template='block' title='some title'>
> >> block contents here
> >> </g:renderWithBody>
> >>
> >> And render with body can have access to title
> >>
> >> _renderWithBody.gsp
> >> ------------------------
> >>
> >> <div class='block'>
> >> <h1>${title}</h1>
> >> <div class='blockBody'><g:renderBody /></div>
> >> </div>
> >>
> >> Or am I going too far?  Am I missing functionality that already exists?
> >> Seems like applyLayout should do this, but it either takes a body or a
> >> template with no body, it does not take a template AND a body.
> >>
> >>
> >>
> >> On Wed, 2009-06-24 at 14:06 -0400, Scott Burch wrote:
> >> > Just for fun, I took the original code and modified it for g.render to
> >> > make this behavior happen.
> >> >
> >> > I have not fully tested it, but here it is working at least with
> >> > templates and models.
> >> >
> >> > Mainly I pulled def b out of each of the if statements.
> >> > I then inserted body into the Map b
> >> > I then made sure that b is always passed to t.make
> >> >
> >> > I think we should probably change the key from 'body' to something
> >> > like 'renderBody' and we should make a tag that renders the body like
> >> > <g:renderBody>
> >> >
> >> > What does everyone else think?
> >> >
> >> >
> >> >
> >> >     def render = { attrs, body ->
> >> >         if(!groovyPagesTemplateEngine) throw new
> >> > IllegalStateException("Property [groovyPagesTemplateEngine] must be set!")
> >> >         if(!attrs.template)
> >> >             throwTagError("Tag [render] is missing required attribute
> >> > [template]")
> >> >
> >> >         def engine = groovyPagesTemplateEngine
> >> >         def uri =
> >> > grailsAttributes.getTemplateUri(attrs.template,request)
> >> >         def var = attrs['var']
> >> >         def contextPath = attrs.contextPath ? attrs.contextPath : ""
> >> >
> >> >         if(attrs.plugin) {
> >> >             def plugin = pluginManager?.getGrailsPlugin(attrs.plugin)
> >> >             if(plugin && !plugin.isBasePlugin()) contextPath =
> >> > plugin.getPluginPath()
> >> >         }
> >> >
> >> >         Template t
> >> >         if(TEMPLATE_CACHE.containsKey(uri) && !engine.isReloadEnabled())
> >> > {
> >> >            t = TEMPLATE_CACHE[uri]
> >> >         }
> >> >         else {
> >> >           def r = engine.getResourceForUri("${contextPath}${uri}")
> >> >           if(!r.exists()) r =
> >> > engine.getResourceForUri("${contextPath}/grails-app/views/${uri}")
> >> >           t = engine.createTemplate( r )
> >> >           TEMPLATE_CACHE[uri] = t
> >> >         }
> >> >
> >> >         def b = [body:body ? body() : '']
> >> >
> >> >         if(attrs.containsKey('bean')) {
> >> >             if (attrs.model instanceof Map) {
> >> >                 b += attrs.model
> >> >             }
> >> >         if (var) {
> >> >         b.put(var, attrs.bean)
> >> >         }
> >> >         else {
> >> >         b.put('it', attrs.bean)
> >> >        }
> >> >         t.make(b).writeTo(out)
> >> >         }
> >> >         else if(attrs.containsKey('collection')) {
> >> >             def collection = attrs.collection
> >> >             def key = 'it'
> >> >             if(collection) {
> >> >                 def first = collection.iterator().next()
> >> >                 key = first ?
> >> > GrailsNameUtils.getPropertyName(first.getClass()) : 'it'
> >> >             }
> >> >             collection.each {
> >> >                 if (attrs.model instanceof Map) {
> >> >                     b += attrs.model
> >> >                 }
> >> >             if (var) {
> >> >             b.put(var, it)
> >> >             }
> >> >             else {
> >> >                     b.put('it', it)
> >> >             b.put(key, it)
> >> >             }
> >> >             t.make(b).writeTo(out)
> >> >             }
> >> >         }
> >> >         else if(attrs.model instanceof Map) {
> >> >             t.make( b + attrs.model ).writeTo(out)
> >> >         }
> >> > else if(attrs.template) {
> >> > t.make(b).writeTo(out)
> >> > }
> >> >     }
> >> >
> >> >
> >> > On Wed, 2009-06-24 at 12:02 -0400, Scott Burch wrote:
> >> > > Maybe to put it better.  It is a hybrid between applyLayout and render
> >> > > with features of both.
> >> > >
> >> > > On Wed, 2009-06-24 at 11:29 -0400, Jeff Brown wrote:
> >> > > > On Wed, Jun 24, 2009 at 11:00 AM, Scott Burch<scott@...>
> >> > > > wrote:
> >> > > > > I frequently want to use the g.render tag with a body.  Currently
> >> > > > > I must
> >> > > > > create a taglib entry and place the body in a attribute that is
> >> > > > > passed
> >> > > > > to g.render.
> >> > > > >
> >> > > > > Why not make this the default behavior of g.render?  Looking at
> >> > > > > the code
> >> > > > > for g.render it looks like adding attrs.body = body() would do the
> >> > > > > trick.  Of course in the rendered template you can then just add
> >> > > > > ${body}
> >> > > > > wherever you want the body or we can create a tag that renders the
> >> > > > > body
> >> > > > > (like <g:renderBody>).
> >> > > > >
> >> > > > > What do people think?  Should this be added to g.render tag or
> >> > > > > make a
> >> > > > > separate tag for this?  Anyone have a better idea?
> >> > > > >
> >> > > > > Scott
> >> > > > >
> >> > > > >
> >> > > >
> >> > > > Can you show a simple use case that justifies the feature?
> >> > > >
> >> > > > Thanks for the help.
> >> > > >
> >> > > >
> >> > > >
> >> > > >
> >> > > > Jeff
> >> > > >
> >> > >
> >> > >
> >> > > ---------------------------------------------------------------------
> >> > > To unsubscribe from this list, please visit:
> >> > >
> >> > >     http://xircles.codehaus.org/manage_email
> >> > >
> >> > >
> >>
> >>
> >> ---------------------------------------------------------------------
> >> To unsubscribe from this list, please visit:
> >>
> >>     http://xircles.codehaus.org/manage_email
> >>
> >>
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe from this list, please visit:
> >
> >     http://xircles.codehaus.org/manage_email
> >
> >
> >
>
>
>


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

    http://xircles.codehaus.org/manage_email



Re: Proposed change to g:render

by nycsailor :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

One more question.

What variable should be used to pass the body.  It seems that I should
use one that is not very likely to conflict with one that someone is
trying to send.  I just use ${body} when I do this through taglibs.  Or
maybe ${renderBody}?

Scott


On Thu, 2009-06-25 at 09:06 -0400, Scott Burch wrote:

> Graeme or Anyone,
>
> I am happy to supply patches, the code below was a sloppy POC so it
> would be better code.
>
> Here are the remaining questions.
>
> 1) Should I patch the existing render tag or create a new one?  I'm torn
> on this because I am changing the functionality of the tag a bit so a
> new one seems like the way to go, but I don't want to contribute to tag
> bloat.
>
> 2) Should I patch so that any attribute, other than the ones already
> included, is passed through as a variable?
>
> 3) If the answer is yes to 2, should those variables be passed through
> as a map?  Say a map called 'attrs' so <g:render foo='bar'> is attrs.foo
> in the template rather than just foo.
>
> Anyone have any opinions before I get started?
>
>
>
> On Thu, 2009-06-25 at 10:35 +0100, Graeme Rocher wrote:
> > Seems like a useful feature. Open a JIRA as a feature request. patches
> > welcome :-)
> >
> > Cheers
> >
> > On Wed, Jun 24, 2009 at 8:07 PM, Scott Burch<scott@...> wrote:
> > > Sorry about all of the messages, trying to provide as much info as possible.
> > >
> > > I modified the render closure to add the attributes to the map and I can now
> > > share the full solution from code I am doing right now.
> > >
> > >
> > > >From my gsp file.
> > > -----------------------
> > >
> > >       <sws:render template="block" title="Recent Blog Entries"
> > > titleLinkText="view all" titleLinkUrl="${createLink(url:[controller:'node',
> > > action:'showAll', type:'standardNode'])}">
> > >         <cms:nodeSummary />
> > >       </sws:render>
> > >       <sws:render template="block" title="Blog Archive">
> > >         <cms:nodeArchive />
> > >       </sws:render>
> > >
> > > _block.gsp
> > > ---------------
> > > <div class="block">
> > >   <div class="title">
> > >     <g:if test="${titleLinkText}">
> > >       <span class="titleLink">
> > >         (<a href="${titleLinkUrl}">${titleLinkText}</a>)
> > >       </span>
> > >     </g:if>
> > >     <span>${title}</span>
> > >   </div>
> > >
> > >   <div class="body">${body}</div>
> > > </div>
> > >
> > >
> > > New maybe hacky render code
> > > ----------------------------
> > >
> > >     def render = { attrs, body ->
> > >         if(!groovyPagesTemplateEngine) throw new
> > > IllegalStateException("Property [groovyPagesTemplateEngine] must be set!")
> > >         if(!attrs.template)
> > >             throwTagError("Tag [render] is missing required attribute
> > > [template]")
> > >
> > >         def engine = groovyPagesTemplateEngine
> > >         def uri = grailsAttributes.getTemplateUri(attrs.template,request)
> > >         def var = attrs['var']
> > >         def contextPath = attrs.contextPath ? attrs.contextPath : ""
> > >
> > >         if(attrs.plugin) {
> > >             def plugin = pluginManager?.getGrailsPlugin(attrs.plugin)
> > >             if(plugin && !plugin.isBasePlugin()) contextPath =
> > > plugin.getPluginPath()
> > >         }
> > >
> > >         Template t
> > >         if(TEMPLATE_CACHE.containsKey(uri) && !engine.isReloadEnabled()) {
> > >            t = TEMPLATE_CACHE[uri]
> > >         }
> > >         else {
> > >           def r = engine.getResourceForUri("${contextPath}${uri}")
> > >           if(!r.exists()) r =
> > > engine.getResourceForUri("${contextPath}/grails-app/views/
> > > ${uri}")
> > >           t = engine.createTemplate( r )
> > >           TEMPLATE_CACHE[uri] = t
> > >         }
> > >
> > > // temporarily I just added the attrs map to the map that will be passed to
> > > t.make()
> > >         def b = [body:body ? body() : ''] + attrs
> > >
> > >         if(attrs.containsKey('bean')) {
> > >             if (attrs.model instanceof Map) {
> > >                 b += attrs.model
> > >             }
> > >         if (var) {
> > >         b.put(var, attrs.bean)
> > >         }
> > >         else {
> > >         b.put('it', attrs.bean)
> > >        }
> > >         t.make(b).writeTo(out)
> > >         }
> > >         else if(attrs.containsKey('collection')) {
> > >             def collection = attrs.collection
> > >             def key = 'it'
> > >             if(collection) {
> > >                 def first = collection.iterator().next()
> > >                 key = first ?
> > > GrailsNameUtils.getPropertyName(first.getClass()) : 'it'
> > >             }
> > >             collection.each {
> > >                 if (attrs.model instanceof Map) {
> > >                     b += attrs.model
> > >                 }
> > >             if (var) {
> > >             b.put(var, it)
> > >             }
> > >             else {
> > >                     b.put('it', it)
> > >             b.put(key, it)
> > >             }
> > >             t.make(b).writeTo(out)
> > >             }
> > >         }
> > >         else if(attrs.model instanceof Map) {
> > >             t.make( b + attrs.model ).writeTo(out)
> > >         }
> > > else if(attrs.template) {
> > > t.make(b).writeTo(out)
> > > }
> > >     }
> > >
> > >
> > >
> > >
> > >
> > >
> > >
> > >
> > >
> > >
> > >
> > >
> > > On Wed, 2009-06-24 at 14:39 -0400, Scott Burch wrote:
> > >
> > > Sorry, that was supposed to be _block.gsp not _renderWithBody.gsp
> > >
> > > On Wed, 2009-06-24 at 14:33 -0400, Scott Burch wrote:
> > >> To take this one step further, maybe create a new tag that passes on the
> > >> attributes and the body, so you can have.
> > >>
> > >> <g:renderWithBody template='block' title='some title'>
> > >> block contents here
> > >> </g:renderWithBody>
> > >>
> > >> And render with body can have access to title
> > >>
> > >> _renderWithBody.gsp
> > >> ------------------------
> > >>
> > >> <div class='block'>
> > >> <h1>${title}</h1>
> > >> <div class='blockBody'><g:renderBody /></div>
> > >> </div>
> > >>
> > >> Or am I going too far?  Am I missing functionality that already exists?
> > >> Seems like applyLayout should do this, but it either takes a body or a
> > >> template with no body, it does not take a template AND a body.
> > >>
> > >>
> > >>
> > >> On Wed, 2009-06-24 at 14:06 -0400, Scott Burch wrote:
> > >> > Just for fun, I took the original code and modified it for g.render to
> > >> > make this behavior happen.
> > >> >
> > >> > I have not fully tested it, but here it is working at least with
> > >> > templates and models.
> > >> >
> > >> > Mainly I pulled def b out of each of the if statements.
> > >> > I then inserted body into the Map b
> > >> > I then made sure that b is always passed to t.make
> > >> >
> > >> > I think we should probably change the key from 'body' to something
> > >> > like 'renderBody' and we should make a tag that renders the body like
> > >> > <g:renderBody>
> > >> >
> > >> > What does everyone else think?
> > >> >
> > >> >
> > >> >
> > >> >     def render = { attrs, body ->
> > >> >         if(!groovyPagesTemplateEngine) throw new
> > >> > IllegalStateException("Property [groovyPagesTemplateEngine] must be set!")
> > >> >         if(!attrs.template)
> > >> >             throwTagError("Tag [render] is missing required attribute
> > >> > [template]")
> > >> >
> > >> >         def engine = groovyPagesTemplateEngine
> > >> >         def uri =
> > >> > grailsAttributes.getTemplateUri(attrs.template,request)
> > >> >         def var = attrs['var']
> > >> >         def contextPath = attrs.contextPath ? attrs.contextPath : ""
> > >> >
> > >> >         if(attrs.plugin) {
> > >> >             def plugin = pluginManager?.getGrailsPlugin(attrs.plugin)
> > >> >             if(plugin && !plugin.isBasePlugin()) contextPath =
> > >> > plugin.getPluginPath()
> > >> >         }
> > >> >
> > >> >         Template t
> > >> >         if(TEMPLATE_CACHE.containsKey(uri) && !engine.isReloadEnabled())
> > >> > {
> > >> >            t = TEMPLATE_CACHE[uri]
> > >> >         }
> > >> >         else {
> > >> >           def r = engine.getResourceForUri("${contextPath}${uri}")
> > >> >           if(!r.exists()) r =
> > >> > engine.getResourceForUri("${contextPath}/grails-app/views/${uri}")
> > >> >           t = engine.createTemplate( r )
> > >> >           TEMPLATE_CACHE[uri] = t
> > >> >         }
> > >> >
> > >> >         def b = [body:body ? body() : '']
> > >> >
> > >> >         if(attrs.containsKey('bean')) {
> > >> >             if (attrs.model instanceof Map) {
> > >> >                 b += attrs.model
> > >> >             }
> > >> >         if (var) {
> > >> >         b.put(var, attrs.bean)
> > >> >         }
> > >> >         else {
> > >> >         b.put('it', attrs.bean)
> > >> >        }
> > >> >         t.make(b).writeTo(out)
> > >> >         }
> > >> >         else if(attrs.containsKey('collection')) {
> > >> >             def collection = attrs.collection
> > >> >             def key = 'it'
> > >> >             if(collection) {
> > >> >                 def first = collection.iterator().next()
> > >> >                 key = first ?
> > >> > GrailsNameUtils.getPropertyName(first.getClass()) : 'it'
> > >> >             }
> > >> >             collection.each {
> > >> >                 if (attrs.model instanceof Map) {
> > >> >                     b += attrs.model
> > >> >                 }
> > >> >             if (var) {
> > >> >             b.put(var, it)
> > >> >             }
> > >> >             else {
> > >> >                     b.put('it', it)
> > >> >             b.put(key, it)
> > >> >             }
> > >> >             t.make(b).writeTo(out)
> > >> >             }
> > >> >         }
> > >> >         else if(attrs.model instanceof Map) {
> > >> >             t.make( b + attrs.model ).writeTo(out)
> > >> >         }
> > >> > else if(attrs.template) {
> > >> > t.make(b).writeTo(out)
> > >> > }
> > >> >     }
> > >> >
> > >> >
> > >> > On Wed, 2009-06-24 at 12:02 -0400, Scott Burch wrote:
> > >> > > Maybe to put it better.  It is a hybrid between applyLayout and render
> > >> > > with features of both.
> > >> > >
> > >> > > On Wed, 2009-06-24 at 11:29 -0400, Jeff Brown wrote:
> > >> > > > On Wed, Jun 24, 2009 at 11:00 AM, Scott Burch<scott@...>
> > >> > > > wrote:
> > >> > > > > I frequently want to use the g.render tag with a body.  Currently
> > >> > > > > I must
> > >> > > > > create a taglib entry and place the body in a attribute that is
> > >> > > > > passed
> > >> > > > > to g.render.
> > >> > > > >
> > >> > > > > Why not make this the default behavior of g.render?  Looking at
> > >> > > > > the code
> > >> > > > > for g.render it looks like adding attrs.body = body() would do the
> > >> > > > > trick.  Of course in the rendered template you can then just add
> > >> > > > > ${body}
> > >> > > > > wherever you want the body or we can create a tag that renders the
> > >> > > > > body
> > >> > > > > (like <g:renderBody>).
> > >> > > > >
> > >> > > > > What do people think?  Should this be added to g.render tag or
> > >> > > > > make a
> > >> > > > > separate tag for this?  Anyone have a better idea?
> > >> > > > >
> > >> > > > > Scott
> > >> > > > >
> > >> > > > >
> > >> > > >
> > >> > > > Can you show a simple use case that justifies the feature?
> > >> > > >
> > >> > > > Thanks for the help.
> > >> > > >
> > >> > > >
> > >> > > >
> > >> > > >
> > >> > > > Jeff
> > >> > > >
> > >> > >
> > >> > >
> > >> > > ---------------------------------------------------------------------
> > >> > > To unsubscribe from this list, please visit:
> > >> > >
> > >> > >     http://xircles.codehaus.org/manage_email
> > >> > >
> > >> > >
> > >>
> > >>
> > >> ---------------------------------------------------------------------
> > >> To unsubscribe from this list, please visit:
> > >>
> > >>     http://xircles.codehaus.org/manage_email
> > >>
> > >>
> > >
> > >
> > > ---------------------------------------------------------------------
> > > To unsubscribe from this list, please visit:
> > >
> > >     http://xircles.codehaus.org/manage_email
> > >
> > >
> > >
> >
> >
> >
>
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
>     http://xircles.codehaus.org/manage_email
>
>


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

    http://xircles.codehaus.org/manage_email



Re: Proposed change to g:render

by Graeme Rocher-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Thu, Jun 25, 2009 at 2:06 PM, Scott Burch<scott@...> wrote:

> Graeme or Anyone,
>
> I am happy to supply patches, the code below was a sloppy POC so it
> would be better code.
>
> Here are the remaining questions.
>
> 1) Should I patch the existing render tag or create a new one?  I'm torn
> on this because I am changing the functionality of the tag a bit so a
> new one seems like the way to go, but I don't want to contribute to tag
> bloat.
>

I don't think you need a new once since its not really a breaking
change. You're simply making the body available to the template.

But personally I wouldn't make it available as a body variable but
rather pass the closure itself. People are used to doing "body()" to
get the body content so suddenly seeing just "body" seems odd. So
basically you should be able to do:

<g:render template="blah">some content</g:render>

and then in the template itself you do

my content: ${body()}

This also avoids the unnecessary invocation of the body inside the
render tag itself.

> 2) Should I patch so that any attribute, other than the ones already
> included, is passed through as a variable?

Hmm I don't think this is needed IMO. The model attribute already
allows you to pass whatever data is needed.

Cheers

>
> 3) If the answer is yes to 2, should those variables be passed through
> as a map?  Say a map called 'attrs' so <g:render foo='bar'> is attrs.foo
> in the template rather than just foo.
>
> Anyone have any opinions before I get started?
>
>
>
> On Thu, 2009-06-25 at 10:35 +0100, Graeme Rocher wrote:
>> Seems like a useful feature. Open a JIRA as a feature request. patches
>> welcome :-)
>>
>> Cheers
>>
>> On Wed, Jun 24, 2009 at 8:07 PM, Scott Burch<scott@...> wrote:
>> > Sorry about all of the messages, trying to provide as much info as possible.
>> >
>> > I modified the render closure to add the attributes to the map and I can now
>> > share the full solution from code I am doing right now.
>> >
>> >
>> > >From my gsp file.
>> > -----------------------
>> >
>> >       <sws:render template="block" title="Recent Blog Entries"
>> > titleLinkText="view all" titleLinkUrl="${createLink(url:[controller:'node',
>> > action:'showAll', type:'standardNode'])}">
>> >         <cms:nodeSummary />
>> >       </sws:render>
>> >       <sws:render template="block" title="Blog Archive">
>> >         <cms:nodeArchive />
>> >       </sws:render>
>> >
>> > _block.gsp
>> > ---------------
>> > <div class="block">
>> >   <div class="title">
>> >     <g:if test="${titleLinkText}">
>> >       <span class="titleLink">
>> >         (<a href="${titleLinkUrl}">${titleLinkText}</a>)
>> >       </span>
>> >     </g:if>
>> >     <span>${title}</span>
>> >   </div>
>> >
>> >   <div class="body">${body}</div>
>> > </div>
>> >
>> >
>> > New maybe hacky render code
>> > ----------------------------
>> >
>> >     def render = { attrs, body ->
>> >         if(!groovyPagesTemplateEngine) throw new
>> > IllegalStateException("Property [groovyPagesTemplateEngine] must be set!")
>> >         if(!attrs.template)
>> >             throwTagError("Tag [render] is missing required attribute
>> > [template]")
>> >
>> >         def engine = groovyPagesTemplateEngine
>> >         def uri = grailsAttributes.getTemplateUri(attrs.template,request)
>> >         def var = attrs['var']
>> >         def contextPath = attrs.contextPath ? attrs.contextPath : ""
>> >
>> >         if(attrs.plugin) {
>> >             def plugin = pluginManager?.getGrailsPlugin(attrs.plugin)
>> >             if(plugin && !plugin.isBasePlugin()) contextPath =
>> > plugin.getPluginPath()
>> >         }
>> >
>> >         Template t
>> >         if(TEMPLATE_CACHE.containsKey(uri) && !engine.isReloadEnabled()) {
>> >            t = TEMPLATE_CACHE[uri]
>> >         }
>> >         else {
>> >           def r = engine.getResourceForUri("${contextPath}${uri}")
>> >           if(!r.exists()) r =
>> > engine.getResourceForUri("${contextPath}/grails-app/views/
>> > ${uri}")
>> >           t = engine.createTemplate( r )
>> >           TEMPLATE_CACHE[uri] = t
>> >         }
>> >
>> > // temporarily I just added the attrs map to the map that will be passed to
>> > t.make()
>> >         def b = [body:body ? body() : ''] + attrs
>> >
>> >         if(attrs.containsKey('bean')) {
>> >             if (attrs.model instanceof Map) {
>> >                 b += attrs.model
>> >             }
>> >             if (var) {
>> >                     b.put(var, attrs.bean)
>> >             }
>> >             else {
>> >                     b.put('it', attrs.bean)
>> >             }
>> >             t.make(b).writeTo(out)
>> >         }
>> >         else if(attrs.containsKey('collection')) {
>> >             def collection = attrs.collection
>> >             def key = 'it'
>> >             if(collection) {
>> >                 def first = collection.iterator().next()
>> >                 key = first ?
>> > GrailsNameUtils.getPropertyName(first.getClass()) : 'it'
>> >             }
>> >             collection.each {
>> >                 if (attrs.model instanceof Map) {
>> >                     b += attrs.model
>> >                 }
>> >                     if (var) {
>> >                             b.put(var, it)
>> >                     }
>> >                     else {
>> >                     b.put('it', it)
>> >                             b.put(key, it)
>> >                     }
>> >                     t.make(b).writeTo(out)
>> >             }
>> >         }
>> >         else if(attrs.model instanceof Map) {
>> >             t.make( b + attrs.model ).writeTo(out)
>> >         }
>> >             else if(attrs.template) {
>> >                     t.make(b).writeTo(out)
>> >             }
>> >     }
>> >
>> >
>> >
>> >
>> >
>> >
>> >
>> >
>> >
>> >
>> >
>> >
>> > On Wed, 2009-06-24 at 14:39 -0400, Scott Burch wrote:
>> >
>> > Sorry, that was supposed to be _block.gsp not _renderWithBody.gsp
>> >
>> > On Wed, 2009-06-24 at 14:33 -0400, Scott Burch wrote:
>> >> To take this one step further, maybe create a new tag that passes on the
>> >> attributes and the body, so you can have.
>> >>
>> >> <g:renderWithBody template='block' title='some title'>
>> >>    block contents here
>> >> </g:renderWithBody>
>> >>
>> >> And render with body can have access to title
>> >>
>> >> _renderWithBody.gsp
>> >> ------------------------
>> >>
>> >> <div class='block'>
>> >>    <h1>${title}</h1>
>> >>    <div class='blockBody'><g:renderBody /></div>
>> >> </div>
>> >>
>> >> Or am I going too far?  Am I missing functionality that already exists?
>> >> Seems like applyLayout should do this, but it either takes a body or a
>> >> template with no body, it does not take a template AND a body.
>> >>
>> >>
>> >>
>> >> On Wed, 2009-06-24 at 14:06 -0400, Scott Burch wrote:
>> >> > Just for fun, I took the original code and modified it for g.render to
>> >> > make this behavior happen.
>> >> >
>> >> > I have not fully tested it, but here it is working at least with
>> >> > templates and models.
>> >> >
>> >> > Mainly I pulled def b out of each of the if statements.
>> >> > I then inserted body into the Map b
>> >> > I then made sure that b is always passed to t.make
>> >> >
>> >> > I think we should probably change the key from 'body' to something
>> >> > like 'renderBody' and we should make a tag that renders the body like
>> >> > <g:renderBody>
>> >> >
>> >> > What does everyone else think?
>> >> >
>> >> >
>> >> >
>> >> >     def render = { attrs, body ->
>> >> >         if(!groovyPagesTemplateEngine) throw new
>> >> > IllegalStateException("Property [groovyPagesTemplateEngine] must be set!")
>> >> >         if(!attrs.template)
>> >> >             throwTagError("Tag [render] is missing required attribute
>> >> > [template]")
>> >> >
>> >> >         def engine = groovyPagesTemplateEngine
>> >> >         def uri =
>> >> > grailsAttributes.getTemplateUri(attrs.template,request)
>> >> >         def var = attrs['var']
>> >> >         def contextPath = attrs.contextPath ? attrs.contextPath : ""
>> >> >
>> >> >         if(attrs.plugin) {
>> >> >             def plugin = pluginManager?.getGrailsPlugin(attrs.plugin)
>> >> >             if(plugin && !plugin.isBasePlugin()) contextPath =
>> >> > plugin.getPluginPath()
>> >> >         }
>> >> >
>> >> >         Template t
>> >> >         if(TEMPLATE_CACHE.containsKey(uri) && !engine.isReloadEnabled())
>> >> > {
>> >> >            t = TEMPLATE_CACHE[uri]
>> >> >         }
>> >> >         else {
>> >> >           def r = engine.getResourceForUri("${contextPath}${uri}")
>> >> >           if(!r.exists()) r =
>> >> > engine.getResourceForUri("${contextPath}/grails-app/views/${uri}")
>> >> >           t = engine.createTemplate( r )
>> >> >           TEMPLATE_CACHE[uri] = t
>> >> >         }
>> >> >
>> >> >         def b = [body:body ? body() : '']
>> >> >
>> >> >         if(attrs.containsKey('bean')) {
>> >> >             if (attrs.model instanceof Map) {
>> >> >                 b += attrs.model
>> >> >             }
>> >> >          if (var) {
>> >> >                  b.put(var, attrs.bean)
>> >> >          }
>> >> >          else {
>> >> >                  b.put('it', attrs.bean)
>> >> >          }
>> >> >          t.make(b).writeTo(out)
>> >> >         }
>> >> >         else if(attrs.containsKey('collection')) {
>> >> >             def collection = attrs.collection
>> >> >             def key = 'it'
>> >> >             if(collection) {
>> >> >                 def first = collection.iterator().next()
>> >> >                 key = first ?
>> >> > GrailsNameUtils.getPropertyName(first.getClass()) : 'it'
>> >> >             }
>> >> >             collection.each {
>> >> >                 if (attrs.model instanceof Map) {
>> >> >                     b += attrs.model
>> >> >                 }
>> >> >                  if (var) {
>> >> >                          b.put(var, it)
>> >> >                  }
>> >> >                  else {
>> >> >                     b.put('it', it)
>> >> >                          b.put(key, it)
>> >> >                  }
>> >> >                  t.make(b).writeTo(out)
>> >> >             }
>> >> >         }
>> >> >         else if(attrs.model instanceof Map) {
>> >> >             t.make( b + attrs.model ).writeTo(out)
>> >> >         }
>> >> >          else if(attrs.template) {
>> >> >                  t.make(b).writeTo(out)
>> >> >          }
>> >> >     }
>> >> >
>> >> >
>> >> > On Wed, 2009-06-24 at 12:02 -0400, Scott Burch wrote:
>> >> > > Maybe to put it better.  It is a hybrid between applyLayout and render
>> >> > > with features of both.
>> >> > >
>> >> > > On Wed, 2009-06-24 at 11:29 -0400, Jeff Brown wrote:
>> >> > > > On Wed, Jun 24, 2009 at 11:00 AM, Scott Burch<scott@...>
>> >> > > > wrote:
>> >> > > > > I frequently want to use the g.render tag with a body.  Currently
>> >> > > > > I must
>> >> > > > > create a taglib entry and place the body in a attribute that is
>> >> > > > > passed
>> >> > > > > to g.render.
>> >> > > > >
>> >> > > > > Why not make this the default behavior of g.render?  Looking at
>> >> > > > > the code
>> >> > > > > for g.render it looks like adding attrs.body = body() would do the
>> >> > > > > trick.  Of course in the rendered template you can then just add
>> >> > > > > ${body}
>> >> > > > > wherever you want the body or we can create a tag that renders the
>> >> > > > > body
>> >> > > > > (like <g:renderBody>).
>> >> > > > >
>> >> > > > > What do people think?  Should this be added to g.render tag or
>> >> > > > > make a
>> >> > > > > separate tag for this?  Anyone have a better idea?
>> >> > > > >
>> >> > > > > Scott
>> >> > > > >
>> >> > > > >
>> >> > > >
>> >> > > > Can you show a simple use case that justifies the feature?
>> >> > > >
>> >> > > > Thanks for the help.
>> >> > > >
>> >> > > >
>> >> > > >
>> >> > > >
>> >> > > > Jeff
>> >> > > >
>> >> > >
>> >> > >
>> >> > > ---------------------------------------------------------------------
>> >> > > To unsubscribe from this list, please visit:
>> >> > >
>> >> > >     http://xircles.codehaus.org/manage_email
>> >> > >
>> >> > >
>> >>
>> >>
>> >> ---------------------------------------------------------------------
>> >> To unsubscribe from this list, please visit:
>> >>
>> >>     http://xircles.codehaus.org/manage_email
>> >>
>> >>
>> >
>> >
>> > ---------------------------------------------------------------------
>> > To unsubscribe from this list, please visit:
>> >
>> >     http://xircles.codehaus.org/manage_email
>> >
>> >
>> >
>>
>>
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
>    http://xircles.codehaus.org/manage_email
>
>
>



--
Graeme Rocher
Head of Grails Development
SpringSource - Weapons for the War on Java Complexity
http://www.springsource.com

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

    http://xircles.codehaus.org/manage_email



Re: Proposed change to g:render

by nycsailor :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Graeme thanks for the answers.

On Thu, 2009-06-25 at 14:23 +0100, Graeme Rocher wrote:

> On Thu, Jun 25, 2009 at 2:06 PM, Scott Burch<scott@...> wrote:
> > Graeme or Anyone,
> >
> > I am happy to supply patches, the code below was a sloppy POC so it
> > would be better code.
> >
> > Here are the remaining questions.
> >
> > 1) Should I patch the existing render tag or create a new one?  I'm torn
> > on this because I am changing the functionality of the tag a bit so a
> > new one seems like the way to go, but I don't want to contribute to tag
> > bloat.
> >
>
> I don't think you need a new once since its not really a breaking
> change. You're simply making the body available to the template.
>
> But personally I wouldn't make it available as a body variable but
> rather pass the closure itself. People are used to doing "body()" to
> get the body content so suddenly seeing just "body" seems odd. So
> basically you should be able to do:
>
> <g:render template="blah">some content</g:render>
>
> and then in the template itself you do
>
> my content: ${body()}
>
> This also avoids the unnecessary invocation of the body inside the
> render tag itself.
>
> > 2) Should I patch so that any attribute, other than the ones already
> > included, is passed through as a variable?
>
> Hmm I don't think this is needed IMO. The model attribute already
> allows you to pass whatever data is needed.
>
> Cheers
> >
> > 3) If the answer is yes to 2, should those variables be passed through
> > as a map?  Say a map called 'attrs' so <g:render foo='bar'> is attrs.foo
> > in the template rather than just foo.
> >
> > Anyone have any opinions before I get started?
> >
> >
> >
> > On Thu, 2009-06-25 at 10:35 +0100, Graeme Rocher wrote:
> >> Seems like a useful feature. Open a JIRA as a feature request. patches
> >> welcome :-)
> >>
> >> Cheers
> >>
> >> On Wed, Jun 24, 2009 at 8:07 PM, Scott Burch<scott@...> wrote:
> >> > Sorry about all of the messages, trying to provide as much info as possible.
> >> >
> >> > I modified the render closure to add the attributes to the map and I can now
> >> > share the full solution from code I am doing right now.
> >> >
> >> >
> >> > >From my gsp file.
> >> > -----------------------
> >> >
> >> >       <sws:render template="block" title="Recent Blog Entries"
> >> > titleLinkText="view all" titleLinkUrl="${createLink(url:[controller:'node',
> >> > action:'showAll', type:'standardNode'])}">
> >> >         <cms:nodeSummary />
> >> >       </sws:render>
> >> >       <sws:render template="block" title="Blog Archive">
> >> >         <cms:nodeArchive />
> >> >       </sws:render>
> >> >
> >> > _block.gsp
> >> > ---------------
> >> > <div class="block">
> >> >   <div class="title">
> >> >     <g:if test="${titleLinkText}">
> >> >       <span class="titleLink">
> >> >         (<a href="${titleLinkUrl}">${titleLinkText}</a>)
> >> >       </span>
> >> >     </g:if>
> >> >     <span>${title}</span>
> >> >   </div>
> >> >
> >> >   <div class="body">${body}</div>
> >> > </div>
> >> >
> >> >
> >> > New maybe hacky render code
> >> > ----------------------------
> >> >
> >> >     def render = { attrs, body ->
> >> >         if(!groovyPagesTemplateEngine) throw new
> >> > IllegalStateException("Property [groovyPagesTemplateEngine] must be set!")
> >> >         if(!attrs.template)
> >> >             throwTagError("Tag [render] is missing required attribute
> >> > [template]")
> >> >
> >> >         def engine = groovyPagesTemplateEngine
> >> >         def uri = grailsAttributes.getTemplateUri(attrs.template,request)
> >> >         def var = attrs['var']
> >> >         def contextPath = attrs.contextPath ? attrs.contextPath : ""
> >> >
> >> >         if(attrs.plugin) {
> >> >             def plugin = pluginManager?.getGrailsPlugin(attrs.plugin)
> >> >             if(plugin && !plugin.isBasePlugin()) contextPath =
> >> > plugin.getPluginPath()
> >> >         }
> >> >
> >> >         Template t
> >> >         if(TEMPLATE_CACHE.containsKey(uri) && !engine.isReloadEnabled()) {
> >> >            t = TEMPLATE_CACHE[uri]
> >> >         }
> >> >         else {
> >> >           def r = engine.getResourceForUri("${contextPath}${uri}")
> >> >           if(!r.exists()) r =
> >> > engine.getResourceForUri("${contextPath}/grails-app/views/
> >> > ${uri}")
> >> >           t = engine.createTemplate( r )
> >> >           TEMPLATE_CACHE[uri] = t
> >> >         }
> >> >
> >> > // temporarily I just added the attrs map to the map that will be passed to
> >> > t.make()
> >> >         def b = [body:body ? body() : ''] + attrs
> >> >
> >> >         if(attrs.containsKey('bean')) {
> >> >             if (attrs.model instanceof Map) {
> >> >                 b += attrs.model
> >> >             }
> >> >             if (var) {
> >> >                     b.put(var, attrs.bean)
> >> >             }
> >> >             else {
> >> >                     b.put('it', attrs.bean)
> >> >             }
> >> >             t.make(b).writeTo(out)
> >> >         }
> >> >         else if(attrs.containsKey('collection')) {
> >> >             def collection = attrs.collection
> >> >             def key = 'it'
> >> >             if(collection) {
> >> >                 def first = collection.iterator().next()
> >> >                 key = first ?
> >> > GrailsNameUtils.getPropertyName(first.getClass()) : 'it'
> >> >             }
> >> >             collection.each {
> >> >                 if (attrs.model instanceof Map) {
> >> >                     b += attrs.model
> >> >                 }
> >> >                     if (var) {
> >> >                             b.put(var, it)
> >> >                     }
> >> >                     else {
> >> >                     b.put('it', it)
> >> >                             b.put(key, it)
> >> >                     }
> >> >                     t.make(b).writeTo(out)
> >> >             }
> >> >         }
> >> >         else if(attrs.model instanceof Map) {
> >> >             t.make( b + attrs.model ).writeTo(out)
> >> >         }
> >> >             else if(attrs.template) {
> >> >                     t.make(b).writeTo(out)
> >> >             }
> >> >     }
> >> >
> >> >
> >> >
> >> >
> >> >
> >> >
> >> >
> >> >
> >> >
> >> >
> >> >
> >> >
> >> > On Wed, 2009-06-24 at 14:39 -0400, Scott Burch wrote:
> >> >
> >> > Sorry, that was supposed to be _block.gsp not _renderWithBody.gsp
> >> >
> >> > On Wed, 2009-06-24 at 14:33 -0400, Scott Burch wrote:
> >> >> To take this one step further, maybe create a new tag that passes on the
> >> >> attributes and the body, so you can have.
> >> >>
> >> >> <g:renderWithBody template='block' title='some title'>
> >> >>    block contents here
> >> >> </g:renderWithBody>
> >> >>
> >> >> And render with body can have access to title
> >> >>
> >> >> _renderWithBody.gsp
> >> >> ------------------------
> >> >>
> >> >> <div class='block'>
> >> >>    <h1>${title}</h1>
> >> >>    <div class='blockBody'><g:renderBody /></div>
> >> >> </div>
> >> >>
> >> >> Or am I going too far?  Am I missing functionality that already exists?
> >> >> Seems like applyLayout should do this, but it either takes a body or a
> >> >> template with no body, it does not take a template AND a body.
> >> >>
> >> >>
> >> >>
> >> >> On Wed, 2009-06-24 at 14:06 -0400, Scott Burch wrote:
> >> >> > Just for fun, I took the original code and modified it for g.render to
> >> >> > make this behavior happen.
> >> >> >
> >> >> > I have not fully tested it, but here it is working at least with
> >> >> > templates and models.
> >> >> >
> >> >> > Mainly I pulled def b out of each of the if statements.
> >> >> > I then inserted body into the Map b
> >> >> > I then made sure that b is always passed to t.make
> >> >> >
> >> >> > I think we should probably change the key from 'body' to something
> >> >> > like 'renderBody' and we should make a tag that renders the body like
> >> >> > <g:renderBody>
> >> >> >
> >> >> > What does everyone else think?
> >> >> >
> >> >> >
> >> >> >
> >> >> >     def render = { attrs, body ->
> >> >> >         if(!groovyPagesTemplateEngine) throw new
> >> >> > IllegalStateException("Property [groovyPagesTemplateEngine] must be set!")
> >> >> >         if(!attrs.template)
> >> >> >             throwTagError("Tag [render] is missing required attribute
> >> >> > [template]")
> >> >> >
> >> >> >         def engine = groovyPagesTemplateEngine
> >> >> >         def uri =
> >> >> > grailsAttributes.getTemplateUri(attrs.template,request)
> >> >> >         def var = attrs['var']
> >> >> >         def contextPath = attrs.contextPath ? attrs.contextPath : ""
> >> >> >
> >> >> >         if(attrs.plugin) {
> >> >> >             def plugin = pluginManager?.getGrailsPlugin(attrs.plugin)
> >> >> >             if(plugin && !plugin.isBasePlugin()) contextPath =
> >> >> > plugin.getPluginPath()
> >> >> >         }
> >> >> >
> >> >> >         Template t
> >> >> >         if(TEMPLATE_CACHE.containsKey(uri) && !engine.isReloadEnabled())
> >> >> > {
> >> >> >            t = TEMPLATE_CACHE[uri]
> >> >> >         }
> >> >> >         else {
> >> >> >           def r = engine.getResourceForUri("${contextPath}${uri}")
> >> >> >           if(!r.exists()) r =
> >> >> > engine.getResourceForUri("${contextPath}/grails-app/views/${uri}")
> >> >> >           t = engine.createTemplate( r )
> >> >> >           TEMPLATE_CACHE[uri] = t
> >> >> >         }
> >> >> >
> >> >> >         def b = [body:body ? body() : '']
> >> >> >
> >> >> >         if(attrs.containsKey('bean')) {
> >> >> >             if (attrs.model instanceof Map) {
> >> >> >                 b += attrs.model
> >> >> >             }
> >> >> >          if (var) {
> >> >> >                  b.put(var, attrs.bean)
> >> >> >          }
> >> >> >          else {
> >> >> >                  b.put('it', attrs.bean)
> >> >> >          }
> >> >> >          t.make(b).writeTo(out)
> >> >> >         }
> >> >> >         else if(attrs.containsKey('collection')) {
> >> >> >             def collection = attrs.collection
> >> >> >             def key = 'it'
> >> >> >             if(collection) {
> >> >> >                 def first = collection.iterator().next()
> >> >> >                 key = first ?
> >> >> > GrailsNameUtils.getPropertyName(first.getClass()) : 'it'
> >> >> >             }
> >> >> >             collection.each {
> >> >> >                 if (attrs.model instanceof Map) {
> >> >> >                     b += attrs.model
> >> >> >                 }
> >> >> >                  if (var) {
> >> >> >                          b.put(var, it)
> >> >> >                  }
> >> >> >                  else {
> >> >> >                     b.put('it', it)
> >> >> >                          b.put(key, it)
> >> >> >                  }
> >> >> >                  t.make(b).writeTo(out)
> >> >> >             }
> >> >> >         }
> >> >> >         else if(attrs.model instanceof Map) {
> >> >> >             t.make( b + attrs.model ).writeTo(out)
> >> >> >         }
> >> >> >          else if(attrs.template) {
> >> >> >                  t.make(b).writeTo(out)
> >> >> >          }
> >> >> >     }
> >> >> >
> >> >> >
> >> >> > On Wed, 2009-06-24 at 12:02 -0400, Scott Burch wrote:
> >> >> > > Maybe to put it better.  It is a hybrid between applyLayout and render
> >> >> > > with features of both.
> >> >> > >
> >> >> > > On Wed, 2009-06-24 at 11:29 -0400, Jeff Brown wrote:
> >> >> > > > On Wed, Jun 24, 2009 at 11:00 AM, Scott Burch<scott@...>
> >> >> > > > wrote:
> >> >> > > > > I frequently want to use the g.render tag with a body.  Currently
> >> >> > > > > I must
> >> >> > > > > create a taglib entry and place the body in a attribute that is
> >> >> > > > > passed
> >> >> > > > > to g.render.
> >> >> > > > >
> >> >> > > > > Why not make this the default behavior of g.render?  Looking at
> >> >> > > > > the code
> >> >> > > > > for g.render it looks like adding attrs.body = body() would do the
> >> >> > > > > trick.  Of course in the rendered template you can then just add
> >> >> > > > > ${body}
> >> >> > > > > wherever you want the body or we can create a tag that renders the
> >> >> > > > > body
> >> >> > > > > (like <g:renderBody>).
> >> >> > > > >
> >> >> > > > > What do people think?  Should this be added to g.render tag or
> >> >> > > > > make a
> >> >> > > > > separate tag for this?  Anyone have a better idea?
> >> >> > > > >
> >> >> > > > > Scott
> >> >> > > > >
> >> >> > > > >
> >> >> > > >
> >> >> > > > Can you show a simple use case that justifies the feature?
> >> >> > > >
> >> >> > > > Thanks for the help.
> >> >> > > >
> >> >> > > >
> >> >> > > >
> >> >> > > >
> >> >> > > > Jeff
> >> >> > > >
> >> >> > >
> >> >> > >
> >> >> > > ---------------------------------------------------------------------
> >> >> > > To unsubscribe from this list, please visit:
> >> >> > >
> >> >> > >     http://xircles.codehaus.org/manage_email
> >> >> > >
> >> >> > >
> >> >>
> >> >>
> >> >> ---------------------------------------------------------------------
> >> >> To unsubscribe from this list, please visit:
> >> >>
> >> >>     http://xircles.codehaus.org/manage_email
> >> >>
> >> >>
> >> >
> >> >
> >> > ---------------------------------------------------------------------
> >> > To unsubscribe from this list, please visit:
> >> >
> >> >     http://xircles.codehaus.org/manage_email
> >> >
> >> >
> >> >
> >>
> >>
> >>
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe from this list, please visit:
> >
> >    http://xircles.codehaus.org/manage_email
> >
> >
> >
>
>
>


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

    http://xircles.codehaus.org/manage_email


< Prev | 1 - 2 | Next >