I'm not sure if this is a good, long-term solution but I was able to get
around the limitation of recursing the same block by creating
DynRenderBlock:

public abstract class DynRenderBlock extends RenderBlock {
        @Parameter(required=true,cache=false)
    public abstract Block getBlock();
}


On Thu, 2006-08-03 at 11:18 -0400, Dan Adams wrote:
> I discovered something interesting about this: When a parameter (eg
> 'block') is accessed, it sets _$block$Cached to true. After the
> component finishes rendering, cleanupAfterRender() is called in
> AbstractComponent which sets _$block$Cached = false and _$block = null.
> The thing is, when you render recursively this way, cleanupAfterRender()
> is *never called*. Here's what happens:
> 
> - [EMAIL PROTECTED] calls @RenderTest
> - @RenderTest begins rendering and in turn renders [EMAIL PROTECTED]
> - [EMAIL PROTECTED] calls @RenderTest
> - @RenderTest should now render [EMAIL PROTECTED] But since @RenderTest is
> still rendering, _$block$Cached still = true so getBlock() is never
> called. So the value that is cached is used which is [EMAIL PROTECTED] thus
> causing the infinite recursion.
> 
> So here's a question. How do you get around this? In order to do
> recursion you have to have some sort of stack to store the values at
> each level in the recursion. Is there some way of emulating that stack
> via informal parameters or something?
> 
> On Thu, 2006-08-03 at 11:01 -0400, Dan Adams wrote:
> > I also just tried this that also had the same effect:
> > 
> > <block jwcid="[EMAIL PROTECTED]">
> >     <comp jwcid="@RenderTest" />
> > </block>
> > 
> > and a component @RenderTest:
> > 
> >     foo<br/>
> >     <rblock jwcid="@RenderBlock" block="ognl:page.getBlock()" />
> > 
> > This the thing I don't understand: in this post
> > http://www.behindthesite.com/blog/C1931765677/E923478269/index.html
> > he does essentially the same thing. But I don't seem to be able to do
> > recursion at all because the first time I call @RenderBlock it caches
> > the parameter value, no matter if it's in the same template or if it's
> > in another component all together. 
> > 
> > At this point I'm thoroughly confused at how to do this. I mean, there
> > has *got* to be a way to do what I want to do right? I love tapestry and
> > I don't mean to rant or complain, but why is doing recursion so
> > difficult? Will this be changed in T4.1 or T5? If I'm just being stupid
> > and not seeing something, please will someone point it out. :)
> > 
> > On Thu, 2006-08-03 at 10:47 -0400, Dan Adams wrote:
> > > Nope, no difference. I also tried changing it to this with no effect:
> > > 
> > > <block jwcid="[EMAIL PROTECTED]">
> > >   foo<br/>
> > >   <rblock jwcid="@RenderBlock" block="component:testrenderer"
> > > name="ognl:getBlock()" />
> > > </block>
> > > 
> > > <block jwcid="[EMAIL PROTECTED]">
> > >   <rblock jwcid="@RenderBlock"
> > > block="ognl:components.testrenderer.getParameter('name')" />
> > > </block>
> > > 
> > > I know that the informal parameters are not cached so I thought I'd try
> > > it. but then the block parameter for the second @RenderBlock is still
> > > cached so it has the same effect.
> > > 
> > > I thought that there also might be a way of temporarily disabling
> > > parameter caching with a component or something. So I checked the
> > > tapestry class enhancement code for parameters. It creates a property
> > > that stores whether or not each parameter is cached each time the
> > > parameter is accessed and there doesn't seem to be a way for me to
> > > access those as they are private properties created in the enhanced
> > > class.
> > > 
> > > On Thu, 2006-08-03 at 20:08 +0530, Karthik N wrote:
> > > > very interesting problem.
> > > > 
> > > > just a wild thought after looking at your configuration - what if you 
> > > > change
> > > > "ognl:getBlock()" to "ognl:block"  - does that make a difference ??
> > > > 
> > > > On 8/3/06, Dan Adams <[EMAIL PROTECTED]> wrote:
> > > > >
> > > > > Okay, here's a test case. I have this is in the template:
> > > > >
> > > > > <rblock jwcid="@RenderBlock" block="component:test" />
> > > > >
> > > > > <block jwcid="[EMAIL PROTECTED]">
> > > > >         foo<br/>
> > > > >         <rblock jwcid="@RenderBlock" block="ognl:getBlock()" />
> > > > > </block>
> > > > >
> > > > > <block jwcid="[EMAIL PROTECTED]">bar</block>
> > > > >
> > > > > and this in the class:
> > > > >
> > > > >         public abstract int getIndex();
> > > > >         public abstract void setIndex(int i);
> > > > >
> > > > >         public String[] getBlocks() {
> > > > >                 return new String[] { "test", "block1" };
> > > > >         }
> > > > >
> > > > >         public Object getBlock() {
> > > > >                 int i = getIndex();
> > > > >                 setIndex(i + 1);
> > > > >                 return getComponent( getBlocks()[i] );
> > > > >         }
> > > > >
> > > > > Now, this *should* under my understanding (I think there is something 
> > > > > I
> > > > > missing about how tapestry renders and evaluates whether parameters 
> > > > > have
> > > > > been cached) print out "foo bar". But instead it continuously prints 
> > > > > out
> > > > > "foo". If you set a breakpoint in getBlock() it is only called once.
> > > > > What am I missing here?
> > > > >
> > > > > It seems that because the second renderblock is in the template that 
> > > > > the
> > > > > next time that block is rendered, tapestry considers the parameter
> > > > > cached and doesn't re-evaluate it. And I don't know of a way to tell
> > > > > tapestry not to cache it because obviously I can't change the @Block
> > > > > component specification. Any ideas?
> > > > >
> > > > > On Thu, 2006-08-03 at 19:17 +0530, Karthik N wrote:
> > > > > > i've faced a similar problem before try and set cache="false" for 
> > > > > > your
> > > > > > parameters.
> > > > > >
> > > > > > On 8/3/06, Dan Adams <[EMAIL PROTECTED]> wrote:
> > > > > > >
> > > > > > > I actually already created an @Eval component that does just 
> > > > > > > that. The
> > > > > > > problem is that the expression that returns the block to render to
> > > > > > > @RenderBlock is only evaluated the first time.
> > > > > > >
> > > > > > > On Wed, 2006-08-02 at 18:19 -0700, Epstein, Ezra wrote:
> > > > > > > > This may not be the issue, but...
> > > > > > > >
> > > > > > > > You could make a "dyna-eval" component that (re-)evaluates an 
> > > > > > > > ognl
> > > > > > > expression wherever/whenever you choose.
> > > > > > > >
> > > > > > > > OGNL is pretty easy to work with.
> > > > > > > >
> > > > > > > > Perhaps that could work?
> > > > > > > >
> > > > > > > > Thanks,
> > > > > > > >
> > > > > > > > Ezra Epstein
> > > > > > > >
> > > > > > > > -----Original Message-----
> > > > > > > > From: Dan Adams [mailto:[EMAIL PROTECTED]
> > > > > > > > Sent: Wednesday, August 02, 2006 2:31 PM
> > > > > > > > To: Tapestry users
> > > > > > > > Subject: Re: recursive rendering
> > > > > > > >
> > > > > > > > Thanks Mike. Yeah, I've read that article at least twice now and
> > > > > read
> > > > > > > through the code. :) I'm having a problem that you may have run 
> > > > > > > into;
> > > > > much
> > > > > > > like your code the block to render is returned via an ognl 
> > > > > > > expression
> > > > > and it
> > > > > > > apprears the the expression is only being evaluated once and not 
> > > > > > > each
> > > > > time.
> > > > > > > Did you ever have this problem?
> > > > > > > >
> > > > > > > > On Tue, 2006-08-01 at 16:04 -0700, Mike Henderson wrote:
> > > > > > > > > Hi,
> > > > > > > > >   It's a T3 example but it should show how it's done:
> > > > > > > > >
> > > > > > > > >
> > > > > http://www.behindthesite.com/blog/C1931765677/E923478269/index.html
> > > > > > > > >
> > > > > > > > > Mike
> > > > > > > > >
> > > > > > > > >
> > > > > > > > >
> > > > > ---------------------------------------------------------------------
> > > > > > > > > To unsubscribe, e-mail: [EMAIL PROTECTED]
> > > > > > > > > For additional commands, e-mail: [EMAIL PROTECTED]
> > > > > > > > >
> > > > > > > > --
> > > > > > > > Dan Adams
> > > > > > > > Senior Software Engineer
> > > > > > > > Interactive Factory
> > > > > > > > 617.235.5857
> > > > > > > >
> > > > > > > >
> > > > > > > >
> > > > > ---------------------------------------------------------------------
> > > > > > > > To unsubscribe, e-mail: [EMAIL PROTECTED]
> > > > > > > > For additional commands, e-mail: [EMAIL PROTECTED]
> > > > > > > >
> > > > > > > >
> > > > > ---------------------------------------------------------------------
> > > > > > > > To unsubscribe, e-mail: [EMAIL PROTECTED]
> > > > > > > > For additional commands, e-mail: [EMAIL PROTECTED]
> > > > > > > >
> > > > > > > --
> > > > > > > Dan Adams
> > > > > > > Senior Software Engineer
> > > > > > > Interactive Factory
> > > > > > > 617.235.5857
> > > > > > >
> > > > > > >
> > > > > > > ---------------------------------------------------------------------
> > > > > > > To unsubscribe, e-mail: [EMAIL PROTECTED]
> > > > > > > For additional commands, e-mail: [EMAIL PROTECTED]
> > > > > > >
> > > > > > >
> > > > > >
> > > > > >
> > > > > --
> > > > > Dan Adams
> > > > > Senior Software Engineer
> > > > > Interactive Factory
> > > > > 617.235.5857
> > > > >
> > > > >
> > > > > ---------------------------------------------------------------------
> > > > > To unsubscribe, e-mail: [EMAIL PROTECTED]
> > > > > For additional commands, e-mail: [EMAIL PROTECTED]
> > > > >
> > > > >
> > > > 
> > > > 
-- 
Dan Adams
Senior Software Engineer
Interactive Factory
617.235.5857


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to