You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Kalle Korhonen <ka...@gmail.com> on 2009/12/08 07:22:58 UTC

Best practice for initializing page to default context

Most things in T5 are delightfully simple, but I find this
surprisingly difficult: how to best initialize a page to default
context (and redirect to it). Imagine you have a search & result page.
If I access the page without any context I want all records to be
displayed. In onActivate() without parameters I set the context to
*all* and return this to redirect, then I query the database in
setupRender() to initialize the data for the grid. However, sorting
the grid will also cause a call to onActivate() without parameters,
resetting my data to the default context. The parameter-less call to
onActivate() would be harmless if I didn't do a redirect from
onActivate() but then I cannot set the default context and redirect.
In setupRender() I could decide whether redirect is needed or not but
at that time, I'm already committed to rendering the request.

Because events cause a parameterless onActivate()  call, I tend to
reserve onActivate() for possible component/event initialization needs
only and always link to pages with initial context already set. I also
find it roughly impossible to use overloaded versions of onActivate()
and subsequently, if my page has multiple entry points, I typically
resort to implementing it in a single onActivate(EventContext
eventContext) operation containing a big if-else clause. Since the
activation context is anyway sent with an event request (as in
?t:ac=mycontext), rather than using the encoded context for rendering,
wouldn't it be just simpler if that context was used for activating
the page for the event request and the following redirect for
rendering would just use whatever context onPassivate() returns? What
do others think, how do you handle this?

Kalle

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Best practice for initializing page to default context

Posted by "Thiago H. de Paula Figueiredo" <th...@gmail.com>.
Em Tue, 08 Dec 2009 16:23:37 -0200, ningdh <ni...@gmail.com> escreveu:

> Hi, Thiago

Hi!

> What Kalle and I concern is the onActivate must come first before  
> onPassivate, so if page A links to page B, A must set the context of B  
> first, right?

In this case, onActivate() is not invoked, so A must invoke one or more  
methods in the B instance that set the fields that contain B's context.
The activate event is only triggered when a page instance is attached to  
an incoming request. That's why onActivate() in A isn't invoked before  
onPassivate().

> If B has multiple param,  I can't think of a good way in general  
> onActivate way.

In this scenario (one page redirects to other), onActivate() isn't invoked  
automatically by Tapestry. Of course, B can invoke it explicitly.

>  And of course we can use createPageLink method with context, but the  
> problem of onActivate is that params must be in strict order. We must be  
> careful on the order and make sure everything goes well.

There was a very interesting discussion about using name/values pairs in  
the activation context some time ago:  
http://old.nabble.com/T5%3A-Passing-named-structured-type-params-in-URLs--to23453229s302.html#a23453229  
Some different approachs are described.

-- 
Thiago H. de Paula Figueiredo
Independent Java, Apache Tapestry 5 and Hibernate consultant, developer,  
and instructor
Owner, software architect and developer, Ars Machina Tecnologia da  
Informação Ltda.
http://www.arsmachina.com.br

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Best practice for initializing page to default context

Posted by ningdh <ni...@gmail.com>.
Hi, Thiago 

----- Original Message ----- 
From: "Thiago H. de Paula Figueiredo" <th...@gmail.com>
To: "Tapestry users" <us...@tapestry.apache.org>
Sent: Wednesday, December 09, 2009 2:09 AM
Subject: Re: Best practice for initializing page to default context


> Em Tue, 08 Dec 2009 15:49:15 -0200, Kalle Korhonen  
> <ka...@gmail.com> escreveu:
> 
>> DH's approach looks interesting, but maybe a bit involving with field
>> names encoded to the url. Thiago, I know it's the recommended approach
>> but I'm just saying it doesn't strike me as the ideal approach.
> 
> The ideal solution always depends on the specific problem and, of course,  
> depends on the taste of the developer. :)
> 
>> That sounds like "I don't understand and don't want to hear about it"
> 
> Please read what I wrote, not what you think I was thinking. ;)
> 
>> - why bother responding if that's the case? Now I'm not sure if it's
>> worth my time to write more details or sample code to describe what I
>> mean if you are not interested in explaining or exploring how to do it
>> better.
> 
> I answered that, AFAIK, Tapestry always use onPassivate() when rendering  
> an URL for a given page. You said that it wasn't always the case. I wanted  
> to explore your problem, but I couldn't understand your description of it.
> 

What Kalle and I concern is the onActivate must come first before onPassivate, so if page A links to page B, A must set the context of B first, right?
If B has multiple param,  I can't think of a good way in general onActivate way. And of course we can use createPageLink method with context, but the problem of onActivate is that params must be in strict order. We must be careful on the order and make sure everything goes well.

Too hard for me.

> -- 
> Thiago H. de Paula Figueiredo
> Independent Java, Apache Tapestry 5 and Hibernate consultant, developer,  
> and instructor
> Owner, software architect and developer, Ars Machina Tecnologia da  
> Informação Ltda.
> http://www.arsmachina.com.br
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
> 
>

Re: Best practice for initializing page to default context

Posted by "Thiago H. de Paula Figueiredo" <th...@gmail.com>.
Em Tue, 08 Dec 2009 15:49:15 -0200, Kalle Korhonen  
<ka...@gmail.com> escreveu:

> DH's approach looks interesting, but maybe a bit involving with field
> names encoded to the url. Thiago, I know it's the recommended approach
> but I'm just saying it doesn't strike me as the ideal approach.

The ideal solution always depends on the specific problem and, of course,  
depends on the taste of the developer. :)

> That sounds like "I don't understand and don't want to hear about it"

Please read what I wrote, not what you think I was thinking. ;)

> - why bother responding if that's the case? Now I'm not sure if it's
> worth my time to write more details or sample code to describe what I
> mean if you are not interested in explaining or exploring how to do it
> better.

I answered that, AFAIK, Tapestry always use onPassivate() when rendering  
an URL for a given page. You said that it wasn't always the case. I wanted  
to explore your problem, but I couldn't understand your description of it.

-- 
Thiago H. de Paula Figueiredo
Independent Java, Apache Tapestry 5 and Hibernate consultant, developer,  
and instructor
Owner, software architect and developer, Ars Machina Tecnologia da  
Informação Ltda.
http://www.arsmachina.com.br

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Best practice for initializing page to default context

Posted by Kalle Korhonen <ka...@gmail.com>.
On Tue, Dec 8, 2009 at 10:02 AM, ningdh <ni...@gmail.com> wrote:
> I can't think of a better way not to involve the field name encoded.

Yes, I understand why you did it.

> And if you don't like the field name exposed, you can also customize the param name by setting the annotation value, such as
> @PageActivationUnit("cat")

Oh, that's cool, didn't read your source that carefully... thanks for
that btw. I need to ponder about this a bit - I'd like to find a good,
generic pattern to follow.

Kalle


> ----- Original Message -----
> From: "Kalle Korhonen"
> To: "Tapestry users" <us...@tapestry.apache.org>
> Sent: Wednesday, December 09, 2009 1:49 AM
> Subject: Re: Best practice for initializing page to default context
>
>
>> On Tue, Dec 8, 2009 at 3:39 AM, Thiago H. de Paula Figueiredo
>> <th...@gmail.com> wrote:
>>> Em Tue, 08 Dec 2009 04:22:58 -0200, Kalle Korhonen
>>> <ka...@gmail.com> escreveu:
>>>> and subsequently, if my page has multiple entry points, I typically
>>>> resort to implementing it in a single onActivate(EventContext
>>>> eventContext) operation containing a big if-else clause.
>>> That's the recommended way when you have a variable number of activation
>>> context parameters.
>>
>> DH's approach looks interesting, but maybe a bit involving with field
>> names encoded to the url. Thiago, I know it's the recommended approach
>> but I'm just saying it doesn't strike me as the ideal approach.
>>
>>>> Since the activation context is anyway sent with an event request (as in
>>>> ?t:ac=mycontext), rather than using the encoded context for rendering,
>>>> wouldn't it be just simpler if that context was used for activating
>>>> the page for the event request and the following redirect for
>>>> rendering would just use whatever context onPassivate() returns?
>>> The activation context is always what onPassivate() returns. I don't
>>> understand what is the problem here.
>>
>> That sounds like "I don't understand and don't want to hear about it"
>> - why bother responding if that's the case? Now I'm not sure if it's
>> worth my time to write more details or sample code to describe what I
>> mean if you are not interested in explaining or exploring how to do it
>> better.
>>
>> Kalle
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
>> For additional commands, e-mail: users-help@tapestry.apache.org
>>
>>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Best practice for initializing page to default context

Posted by ningdh <ni...@gmail.com>.
I can't think of a better way not to involve the field name encoded.

And if you don't like the field name exposed, you can also customize the param name by setting the annotation value, such as 

@PageActivationUnit("cat")
private Category category;

Then the url is like /searchpage/cat-VALUE

I like this style a lot and use heavily in my multiple projects.

DH

----- Original Message ----- 
From: "Kalle Korhonen" 
To: "Tapestry users" <us...@tapestry.apache.org>
Sent: Wednesday, December 09, 2009 1:49 AM
Subject: Re: Best practice for initializing page to default context


> On Tue, Dec 8, 2009 at 3:39 AM, Thiago H. de Paula Figueiredo
> <th...@gmail.com> wrote:
>> Em Tue, 08 Dec 2009 04:22:58 -0200, Kalle Korhonen
>> <ka...@gmail.com> escreveu:
>>> and subsequently, if my page has multiple entry points, I typically
>>> resort to implementing it in a single onActivate(EventContext
>>> eventContext) operation containing a big if-else clause.
>> That's the recommended way when you have a variable number of activation
>> context parameters.
> 
> DH's approach looks interesting, but maybe a bit involving with field
> names encoded to the url. Thiago, I know it's the recommended approach
> but I'm just saying it doesn't strike me as the ideal approach.
> 
>>> Since the activation context is anyway sent with an event request (as in
>>> ?t:ac=mycontext), rather than using the encoded context for rendering,
>>> wouldn't it be just simpler if that context was used for activating
>>> the page for the event request and the following redirect for
>>> rendering would just use whatever context onPassivate() returns?
>> The activation context is always what onPassivate() returns. I don't
>> understand what is the problem here.
> 
> That sounds like "I don't understand and don't want to hear about it"
> - why bother responding if that's the case? Now I'm not sure if it's
> worth my time to write more details or sample code to describe what I
> mean if you are not interested in explaining or exploring how to do it
> better.
> 
> Kalle
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
> 
>

Re: Best practice for initializing page to default context

Posted by Kalle Korhonen <ka...@gmail.com>.
On Tue, Dec 8, 2009 at 3:39 AM, Thiago H. de Paula Figueiredo
<th...@gmail.com> wrote:
> Em Tue, 08 Dec 2009 04:22:58 -0200, Kalle Korhonen
> <ka...@gmail.com> escreveu:
>> and subsequently, if my page has multiple entry points, I typically
>> resort to implementing it in a single onActivate(EventContext
>> eventContext) operation containing a big if-else clause.
> That's the recommended way when you have a variable number of activation
> context parameters.

DH's approach looks interesting, but maybe a bit involving with field
names encoded to the url. Thiago, I know it's the recommended approach
but I'm just saying it doesn't strike me as the ideal approach.

>> Since the activation context is anyway sent with an event request (as in
>> ?t:ac=mycontext), rather than using the encoded context for rendering,
>> wouldn't it be just simpler if that context was used for activating
>> the page for the event request and the following redirect for
>> rendering would just use whatever context onPassivate() returns?
> The activation context is always what onPassivate() returns. I don't
> understand what is the problem here.

That sounds like "I don't understand and don't want to hear about it"
- why bother responding if that's the case? Now I'm not sure if it's
worth my time to write more details or sample code to describe what I
mean if you are not interested in explaining or exploring how to do it
better.

Kalle

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Best practice for initializing page to default context

Posted by "Thiago H. de Paula Figueiredo" <th...@gmail.com>.
Em Tue, 08 Dec 2009 04:22:58 -0200, Kalle Korhonen  
<ka...@gmail.com> escreveu:

> and subsequently, if my page has multiple entry points, I typically
> resort to implementing it in a single onActivate(EventContext
> eventContext) operation containing a big if-else clause.

That's the recommended way when you have a variable number of activation  
context parameters.

> Since the activation context is anyway sent with an event request (as in
> ?t:ac=mycontext), rather than using the encoded context for rendering,
> wouldn't it be just simpler if that context was used for activating
> the page for the event request and the following redirect for
> rendering would just use whatever context onPassivate() returns?

The activation context is always what onPassivate() returns. I don't  
understand what is the problem here.

-- 
Thiago H. de Paula Figueiredo
Independent Java, Apache Tapestry 5 and Hibernate consultant, developer,  
and instructor
Owner, software architect and developer, Ars Machina Tecnologia da  
Informação Ltda.
http://www.arsmachina.com.br

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Best practice for initializing page to default context

Posted by Kalle Korhonen <ka...@gmail.com>.
Yes, I agree with that Norman. That's sort of what I implied when I
said that I "always link to pages with initial context already set" -
i.e. the reverse works better - re-initialize the page if a specific
context is set. That's one way, what Howard suggests is another
(identify page internal links) and third is to differentiate between
an event and a render request. And of course, you can get it done by
setting various semi-persistent (flash etc). flags etc.

Kalle


On Tue, Dec 8, 2009 at 11:43 AM, Norman Franke <no...@myasd.com> wrote:
> I implemented a somewhat similar approach for search using an even more
> basic approach. Most of my search fields are @Persisted, but I still needed
> a way to know when to reset the search dialog. I ended up creating a new
> context parameter, consisting of the string "reset". Every time I wanted to
> create a blank search page, I'd send the reset parameter which would set all
> of the @Persist-ed properties to null. (Using the context parameter to the
> pagelink, one could even make that a custom component: NewSearch or
> something.) Otherwise, it would use the values as-is. This allowed someone
> to click on a result to get more details, but then come back with everything
> as it was. Rather simple, but effective in my case.
>
> Norman Franke
> Answering Service for Directors, Inc.
> www.myasd.com
>
>
>
> On Dec 8, 2009, at 1:59 PM, Howard Lewis Ship wrote:
>
>> I've had to solve this problem for one of my clients as well and I
>> think it's something that should go into the framework.  The approach
>> I took was to identify self-referential links (page render links that
>> are to the same page they originate from) using an additional query
>> parameter. This allows Tapestry to differentiate between requests that
>> start on a new page vs. those that continue on the page. Tapestry can
>> then fire a notification on components to perform initialization (on
>> page render requests without the query parameter).
>>
>> This would be a new lifecycle method, like pageAttached() or
>> pageLoaded().  I'm still working on the right terminology, for Widen
>> it is "initialized", as in method pageInitialized().
>>
>> On Mon, Dec 7, 2009 at 10:22 PM, Kalle Korhonen
>> <ka...@gmail.com> wrote:
>>>
>>> Most things in T5 are delightfully simple, but I find this
>>> surprisingly difficult: how to best initialize a page to default
>>> context (and redirect to it). Imagine you have a search & result page.
>>> If I access the page without any context I want all records to be
>>> displayed. In onActivate() without parameters I set the context to
>>> *all* and return this to redirect, then I query the database in
>>> setupRender() to initialize the data for the grid. However, sorting
>>> the grid will also cause a call to onActivate() without parameters,
>>> resetting my data to the default context. The parameter-less call to
>>> onActivate() would be harmless if I didn't do a redirect from
>>> onActivate() but then I cannot set the default context and redirect.
>>> In setupRender() I could decide whether redirect is needed or not but
>>> at that time, I'm already committed to rendering the request.
>>>
>>> Because events cause a parameterless onActivate()  call, I tend to
>>> reserve onActivate() for possible component/event initialization needs
>>> only and always link to pages with initial context already set. I also
>>> find it roughly impossible to use overloaded versions of onActivate()
>>> and subsequently, if my page has multiple entry points, I typically
>>> resort to implementing it in a single onActivate(EventContext
>>> eventContext) operation containing a big if-else clause. Since the
>>> activation context is anyway sent with an event request (as in
>>> ?t:ac=mycontext), rather than using the encoded context for rendering,
>>> wouldn't it be just simpler if that context was used for activating
>>> the page for the event request and the following redirect for
>>> rendering would just use whatever context onPassivate() returns? What
>>> do others think, how do you handle this?
>>>
>>> Kalle
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
>>> For additional commands, e-mail: users-help@tapestry.apache.org
>>>
>>>
>>
>>
>>
>> --
>> Howard M. Lewis Ship
>>
>> Creator of Apache Tapestry
>>
>> The source for Tapestry training, mentoring and support. Contact me to
>> learn how I can get you up and productive in Tapestry fast!
>>
>> (971) 678-5210
>> http://howardlewisship.com
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
>> For additional commands, e-mail: users-help@tapestry.apache.org
>>
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Best practice for initializing page to default context

Posted by Norman Franke <no...@myasd.com>.
I implemented a somewhat similar approach for search using an even  
more basic approach. Most of my search fields are @Persisted, but I  
still needed a way to know when to reset the search dialog. I ended up  
creating a new context parameter, consisting of the string "reset".  
Every time I wanted to create a blank search page, I'd send the reset  
parameter which would set all of the @Persist-ed properties to null.  
(Using the context parameter to the pagelink, one could even make that  
a custom component: NewSearch or something.) Otherwise, it would use  
the values as-is. This allowed someone to click on a result to get  
more details, but then come back with everything as it was. Rather  
simple, but effective in my case.

Norman Franke
Answering Service for Directors, Inc.
www.myasd.com



On Dec 8, 2009, at 1:59 PM, Howard Lewis Ship wrote:

> I've had to solve this problem for one of my clients as well and I
> think it's something that should go into the framework.  The approach
> I took was to identify self-referential links (page render links that
> are to the same page they originate from) using an additional query
> parameter. This allows Tapestry to differentiate between requests that
> start on a new page vs. those that continue on the page. Tapestry can
> then fire a notification on components to perform initialization (on
> page render requests without the query parameter).
>
> This would be a new lifecycle method, like pageAttached() or
> pageLoaded().  I'm still working on the right terminology, for Widen
> it is "initialized", as in method pageInitialized().
>
> On Mon, Dec 7, 2009 at 10:22 PM, Kalle Korhonen
> <ka...@gmail.com> wrote:
>> Most things in T5 are delightfully simple, but I find this
>> surprisingly difficult: how to best initialize a page to default
>> context (and redirect to it). Imagine you have a search & result  
>> page.
>> If I access the page without any context I want all records to be
>> displayed. In onActivate() without parameters I set the context to
>> *all* and return this to redirect, then I query the database in
>> setupRender() to initialize the data for the grid. However, sorting
>> the grid will also cause a call to onActivate() without parameters,
>> resetting my data to the default context. The parameter-less call to
>> onActivate() would be harmless if I didn't do a redirect from
>> onActivate() but then I cannot set the default context and redirect.
>> In setupRender() I could decide whether redirect is needed or not but
>> at that time, I'm already committed to rendering the request.
>>
>> Because events cause a parameterless onActivate()  call, I tend to
>> reserve onActivate() for possible component/event initialization  
>> needs
>> only and always link to pages with initial context already set. I  
>> also
>> find it roughly impossible to use overloaded versions of onActivate()
>> and subsequently, if my page has multiple entry points, I typically
>> resort to implementing it in a single onActivate(EventContext
>> eventContext) operation containing a big if-else clause. Since the
>> activation context is anyway sent with an event request (as in
>> ?t:ac=mycontext), rather than using the encoded context for  
>> rendering,
>> wouldn't it be just simpler if that context was used for activating
>> the page for the event request and the following redirect for
>> rendering would just use whatever context onPassivate() returns? What
>> do others think, how do you handle this?
>>
>> Kalle
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
>> For additional commands, e-mail: users-help@tapestry.apache.org
>>
>>
>
>
>
> -- 
> Howard M. Lewis Ship
>
> Creator of Apache Tapestry
>
> The source for Tapestry training, mentoring and support. Contact me to
> learn how I can get you up and productive in Tapestry fast!
>
> (971) 678-5210
> http://howardlewisship.com
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>


Re: Best practice for initializing page to default context

Posted by Kalle Korhonen <ka...@gmail.com>.
Opened https://issues.apache.org/jira/browse/TAP5-948 for it.

Kalle

On Tue, Dec 8, 2009 at 11:24 AM, Kalle Korhonen
<ka...@gmail.com> wrote:
> On Tue, Dec 8, 2009 at 10:59 AM, Howard Lewis Ship <hl...@gmail.com> wrote:
>> I've had to solve this problem for one of my clients as well and I
>> think it's something that should go into the framework.  The approach
>> I took was to identify self-referential links (page render links that
>> are to the same page they originate from) using an additional query
>> parameter. This allows Tapestry to differentiate between requests that
>> start on a new page vs. those that continue on the page. Tapestry can
>> then fire a notification on components to perform initialization (on
>> page render requests without the query parameter).
>> This would be a new lifecycle method, like pageAttached() or
>> pageLoaded().  I'm still working on the right terminology, for Widen
>> it is "initialized", as in method pageInitialized().
>
> Thank you Howard, that would excellent. Until it's in the framework,
> obviously you can get it done one way or another but framework support
> would make things easier and more consistent. I'd hate to come up with
> something that is half-there as an optional module if you are already
> working on solving it at the core framework level. Sounds like there's
> no issue open on it (?) - if not, I'll open one.
>
> Kalle
>
>
>> On Mon, Dec 7, 2009 at 10:22 PM, Kalle Korhonen
>> <ka...@gmail.com> wrote:
>>> Most things in T5 are delightfully simple, but I find this
>>> surprisingly difficult: how to best initialize a page to default
>>> context (and redirect to it). Imagine you have a search & result page.
>>> If I access the page without any context I want all records to be
>>> displayed. In onActivate() without parameters I set the context to
>>> *all* and return this to redirect, then I query the database in
>>> setupRender() to initialize the data for the grid. However, sorting
>>> the grid will also cause a call to onActivate() without parameters,
>>> resetting my data to the default context. The parameter-less call to
>>> onActivate() would be harmless if I didn't do a redirect from
>>> onActivate() but then I cannot set the default context and redirect.
>>> In setupRender() I could decide whether redirect is needed or not but
>>> at that time, I'm already committed to rendering the request.
>>>
>>> Because events cause a parameterless onActivate()  call, I tend to
>>> reserve onActivate() for possible component/event initialization needs
>>> only and always link to pages with initial context already set. I also
>>> find it roughly impossible to use overloaded versions of onActivate()
>>> and subsequently, if my page has multiple entry points, I typically
>>> resort to implementing it in a single onActivate(EventContext
>>> eventContext) operation containing a big if-else clause. Since the
>>> activation context is anyway sent with an event request (as in
>>> ?t:ac=mycontext), rather than using the encoded context for rendering,
>>> wouldn't it be just simpler if that context was used for activating
>>> the page for the event request and the following redirect for
>>> rendering would just use whatever context onPassivate() returns? What
>>> do others think, how do you handle this?
>>>
>>> Kalle
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
>>> For additional commands, e-mail: users-help@tapestry.apache.org
>>>
>>>
>>
>>
>>
>> --
>> Howard M. Lewis Ship
>>
>> Creator of Apache Tapestry
>>
>> The source for Tapestry training, mentoring and support. Contact me to
>> learn how I can get you up and productive in Tapestry fast!
>>
>> (971) 678-5210
>> http://howardlewisship.com
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
>> For additional commands, e-mail: users-help@tapestry.apache.org
>>
>>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Best practice for initializing page to default context

Posted by Kalle Korhonen <ka...@gmail.com>.
On Tue, Dec 8, 2009 at 10:59 AM, Howard Lewis Ship <hl...@gmail.com> wrote:
> I've had to solve this problem for one of my clients as well and I
> think it's something that should go into the framework.  The approach
> I took was to identify self-referential links (page render links that
> are to the same page they originate from) using an additional query
> parameter. This allows Tapestry to differentiate between requests that
> start on a new page vs. those that continue on the page. Tapestry can
> then fire a notification on components to perform initialization (on
> page render requests without the query parameter).
> This would be a new lifecycle method, like pageAttached() or
> pageLoaded().  I'm still working on the right terminology, for Widen
> it is "initialized", as in method pageInitialized().

Thank you Howard, that would excellent. Until it's in the framework,
obviously you can get it done one way or another but framework support
would make things easier and more consistent. I'd hate to come up with
something that is half-there as an optional module if you are already
working on solving it at the core framework level. Sounds like there's
no issue open on it (?) - if not, I'll open one.

Kalle


> On Mon, Dec 7, 2009 at 10:22 PM, Kalle Korhonen
> <ka...@gmail.com> wrote:
>> Most things in T5 are delightfully simple, but I find this
>> surprisingly difficult: how to best initialize a page to default
>> context (and redirect to it). Imagine you have a search & result page.
>> If I access the page without any context I want all records to be
>> displayed. In onActivate() without parameters I set the context to
>> *all* and return this to redirect, then I query the database in
>> setupRender() to initialize the data for the grid. However, sorting
>> the grid will also cause a call to onActivate() without parameters,
>> resetting my data to the default context. The parameter-less call to
>> onActivate() would be harmless if I didn't do a redirect from
>> onActivate() but then I cannot set the default context and redirect.
>> In setupRender() I could decide whether redirect is needed or not but
>> at that time, I'm already committed to rendering the request.
>>
>> Because events cause a parameterless onActivate()  call, I tend to
>> reserve onActivate() for possible component/event initialization needs
>> only and always link to pages with initial context already set. I also
>> find it roughly impossible to use overloaded versions of onActivate()
>> and subsequently, if my page has multiple entry points, I typically
>> resort to implementing it in a single onActivate(EventContext
>> eventContext) operation containing a big if-else clause. Since the
>> activation context is anyway sent with an event request (as in
>> ?t:ac=mycontext), rather than using the encoded context for rendering,
>> wouldn't it be just simpler if that context was used for activating
>> the page for the event request and the following redirect for
>> rendering would just use whatever context onPassivate() returns? What
>> do others think, how do you handle this?
>>
>> Kalle
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
>> For additional commands, e-mail: users-help@tapestry.apache.org
>>
>>
>
>
>
> --
> Howard M. Lewis Ship
>
> Creator of Apache Tapestry
>
> The source for Tapestry training, mentoring and support. Contact me to
> learn how I can get you up and productive in Tapestry fast!
>
> (971) 678-5210
> http://howardlewisship.com
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Best practice for initializing page to default context

Posted by Howard Lewis Ship <hl...@gmail.com>.
I've had to solve this problem for one of my clients as well and I
think it's something that should go into the framework.  The approach
I took was to identify self-referential links (page render links that
are to the same page they originate from) using an additional query
parameter. This allows Tapestry to differentiate between requests that
start on a new page vs. those that continue on the page. Tapestry can
then fire a notification on components to perform initialization (on
page render requests without the query parameter).

This would be a new lifecycle method, like pageAttached() or
pageLoaded().  I'm still working on the right terminology, for Widen
it is "initialized", as in method pageInitialized().

On Mon, Dec 7, 2009 at 10:22 PM, Kalle Korhonen
<ka...@gmail.com> wrote:
> Most things in T5 are delightfully simple, but I find this
> surprisingly difficult: how to best initialize a page to default
> context (and redirect to it). Imagine you have a search & result page.
> If I access the page without any context I want all records to be
> displayed. In onActivate() without parameters I set the context to
> *all* and return this to redirect, then I query the database in
> setupRender() to initialize the data for the grid. However, sorting
> the grid will also cause a call to onActivate() without parameters,
> resetting my data to the default context. The parameter-less call to
> onActivate() would be harmless if I didn't do a redirect from
> onActivate() but then I cannot set the default context and redirect.
> In setupRender() I could decide whether redirect is needed or not but
> at that time, I'm already committed to rendering the request.
>
> Because events cause a parameterless onActivate()  call, I tend to
> reserve onActivate() for possible component/event initialization needs
> only and always link to pages with initial context already set. I also
> find it roughly impossible to use overloaded versions of onActivate()
> and subsequently, if my page has multiple entry points, I typically
> resort to implementing it in a single onActivate(EventContext
> eventContext) operation containing a big if-else clause. Since the
> activation context is anyway sent with an event request (as in
> ?t:ac=mycontext), rather than using the encoded context for rendering,
> wouldn't it be just simpler if that context was used for activating
> the page for the event request and the following redirect for
> rendering would just use whatever context onPassivate() returns? What
> do others think, how do you handle this?
>
> Kalle
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>



-- 
Howard M. Lewis Ship

Creator of Apache Tapestry

The source for Tapestry training, mentoring and support. Contact me to
learn how I can get you up and productive in Tapestry fast!

(971) 678-5210
http://howardlewisship.com

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Best practice for initializing page to default context

Posted by NingDH <ni...@163.org>.
Of course, but since I am not very good at javassit, my implementation may be ugly and a bit long. Anyone please consummate it.
Like PageActivationContext, I introduce an PageActivationUnitWorker.
The key part is to collect the param fields and add the param map to page class in runtime. onActivate and onPassivate would use this map to set value or retrieve value.

1. For annotation:

@Target(FIELD)
@Documented
@Retention(RUNTIME)
public @interface PageActivationUnit {
 String value() default "";
}

2. For worker:
public class PageActivationUnitWorker implements ComponentClassTransformWorker {

 private TypeCoercer _typeCoercer;
 
 public PageActivationUnitWorker(TypeCoercer typeCoercer) {
  this._typeCoercer = typeCoercer;
 }
 
 public void transform(ClassTransformation transformation, MutableComponentModel model) {
  List<String> fieldNames = transformation.findFieldsWithAnnotation(PageActivationUnit.class);
  
  if (fieldNames != null && fieldNames.size() > 0) {
   
   Map<String, String> fieldParamMap = new HashMap<String, String>();
   for (String fieldName : fieldNames) {
    PageActivationUnit annotation = transformation.getFieldAnnotation(fieldName,
      PageActivationUnit.class);
    fieldParamMap.put(fieldName, getParameterName(fieldName, annotation.value()));
   }
   
   String typeCoercer = transformation.addInjectedField(TypeCoercer.class, "typeCoercer", _typeCoercer);
   
   TransformMethodSignature activate
         = new TransformMethodSignature(Modifier.PROTECTED | Modifier.FINAL, "boolean",
                                       "onActivate",
                                       new String[] {EventContext.class.getName()}, null);
   
   TransformMethodSignature passivate
             = new TransformMethodSignature(Modifier.PROTECTED | Modifier.FINAL, "java.lang.Object[]",
                                           "onPassivate",
                                           null, null);
   
   BodyBuilder activeBuilder = new BodyBuilder().begin();
   activeBuilder.addln("java.util.Map keyValueMap = new java.util.HashMap();");
   activeBuilder.add("for (int i = 0; i < $1.getCount(); i++)");
   activeBuilder.begin();
   activeBuilder.addln("String []keyValue = ((String)$1.get(String.class, i)).split(\"-\");");
   activeBuilder.addln("String key = keyValue[0];");
   activeBuilder.addln("String value = (keyValue.length > 1) ? keyValue[1] : null;");
   activeBuilder.addln("keyValueMap.put(key, value);");
   activeBuilder.end();
   // end for
   for (int i = 0, size = fieldNames.size(); i < size; i++) {
    String fieldName = fieldNames.get(i);
    String fieldType = transformation.getFieldType(fieldName);
    activeBuilder.addln("String fieldValue=(String)keyValueMap.get(\"%s\");", fieldParamMap.get(fieldName));
    activeBuilder.addln("if (fieldValue != null) {");
    activeBuilder.addln("%s=(%s)%s.coerce(fieldValue, Class.forName(\"%s\"));", fieldName, fieldType, typeCoercer, fieldType);
    activeBuilder.addln("}");
   }
   activeBuilder.addln("return true;");
   // end method body
   activeBuilder.end();
     
   BodyBuilder deactiveBuilder = new BodyBuilder().begin();
   for (int i = 0, size = fieldNames.size(); i < size; i++) {
    String fieldName = fieldNames.get(i);
    
    if (i == size - 1) {
     deactiveBuilder.add("\"%s-\" +  (%s != null ? (String)%s.coerce(%s, String.class) : \"\")", fieldParamMap.get(fieldName), fieldName, typeCoercer, fieldName);
    } else {
     deactiveBuilder.add("\"%s-\" +  (%s != null ? (String)%s.coerce(%s, String.class) : \"\"),", fieldParamMap.get(fieldName), fieldName, typeCoercer, fieldName);
    }
   }
   deactiveBuilder.end();
   
   transformation.addTransformedMethod(activate, activeBuilder.toString());
   transformation.addTransformedMethod(passivate, "return new Object[]" + deactiveBuilder.toString() + ";");
  }
 }

 private String getParameterName(String fieldName, String annotatedName)
    {
        if (InternalUtils.isNonBlank(annotatedName)) return annotatedName;

        return InternalUtils.stripMemberName(fieldName);
    }
}

3. In app module

public static void contributeComponentClassTransformWorker(
            OrderedConfiguration<ComponentClassTransformWorker> configuration, TypeCoercer typeCoercer) {
     configuration.add("PageActivationUnit", new PageActivationUnitWorker(typeCoercer), "before:OnEvent");
    }

That's all.
One disadvantage is that you can't use primitive type for param field, so use Integer instead of int.

DH
http://www.gaonline.com.cn
----- Original Message ----- 
From: "Inge Solvoll" 
To: "Tapestry users" <us...@tapestry.apache.org>
Sent: Tuesday, December 08, 2009 4:14 PM
Subject: Re: Best practice for initializing page to default context


> Would it be possible for you to share that code with us? I don't necessarily
> want to use that approach, but it would be very helpful to see how you
> implemented it.
> 
> Inge
> 
> On Tue, Dec 8, 2009 at 9:10 AM, DH <ni...@gmail.com> wrote:
> 
>> Once I found it difficult too, and I never used  EventContext because I
>> think it is not better than multiple onActivate.
>>
>> Finally I wrote my own PageActivationContext called PageActivationUnit, the
>> difference is that PageActivationContext only can occur once, but
>> PageActivationUnit can be used in multiple fields.
>>
>> For example, a product search page, it has params like
>> category,keyword,pagesize,pageno,brand and so on. If using
>> PageActivationUnit, the java would be like:
>>
>> @PageActivationUnit
>> private Category category;
>>
>> @PageActivationUnit
>> private String keyword;
>>
>> @PageActivationUnit
>> private Integer pagesize;
>>
>> @PageActivationUnit
>> private Integer pageNo;
>>
>> @PageActivationUnit
>> private Brand brand;
>>
>> PageActivationUnit will handle all the activate and passivate event for me,
>> and the url requested would be like
>> '/searchpage/category-value/keyword-value/pagesize-10/pageNo-2/brand-value'.
>> Yes, I encode the field name in the url and its value in a pair.
>> Another advantage is if later another param 'orderBy' is added, I don't
>> have to change any code at all.
>>
>> DH
>> http://www.gaonline.com.cn
>>
>> ----- Original Message -----
>> From: "Kalle Korhonen"
>> To: "Tapestry users" <us...@tapestry.apache.org>
>> Sent: Tuesday, December 08, 2009 2:22 PM
>> Subject: Best practice for initializing page to default context
>>
>>
>> > Most things in T5 are delightfully simple, but I find this
>> > surprisingly difficult: how to best initialize a page to default
>> > context (and redirect to it). Imagine you have a search & result page.
>> > If I access the page without any context I want all records to be
>> > displayed. In onActivate() without parameters I set the context to
>> > *all* and return this to redirect, then I query the database in
>> > setupRender() to initialize the data for the grid. However, sorting
>> > the grid will also cause a call to onActivate() without parameters,
>> > resetting my data to the default context. The parameter-less call to
>> > onActivate() would be harmless if I didn't do a redirect from
>> > onActivate() but then I cannot set the default context and redirect.
>> > In setupRender() I could decide whether redirect is needed or not but
>> > at that time, I'm already committed to rendering the request.
>> >
>> > Because events cause a parameterless onActivate()  call, I tend to
>> > reserve onActivate() for possible component/event initialization needs
>> > only and always link to pages with initial context already set. I also
>> > find it roughly impossible to use overloaded versions of onActivate()
>> > and subsequently, if my page has multiple entry points, I typically
>> > resort to implementing it in a single onActivate(EventContext
>> > eventContext) operation containing a big if-else clause. Since the
>> > activation context is anyway sent with an event request (as in
>> > ?t:ac=mycontext), rather than using the encoded context for rendering,
>> > wouldn't it be just simpler if that context was used for activating
>> > the page for the event request and the following redirect for
>> > rendering would just use whatever context onPassivate() returns? What
>> > do others think, how do you handle this?
>> >
>> > Kalle
>> >
>> > ---------------------------------------------------------------------
>> > To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
>> > For additional commands, e-mail: users-help@tapestry.apache.org
>> >
>> >
>>
>

Re: Best practice for initializing page to default context

Posted by DH <ni...@gmail.com>.
Of course, but since I am not very good at javassit, my implementation may be ugly and a bit long. Anyone please consummate it.
Like PageActivationContext, I introduce an PageActivationUnitWorker.
The key part is to collect the param fields and add the param map to page class in runtime. onActivate and onPassivate would use this map to set value or retrieve value.

1. For annotation:

@Target(FIELD)
@Documented
@Retention(RUNTIME)
public @interface PageActivationUnit {
 String value() default "";
}

2. For worker:
public class PageActivationUnitWorker implements ComponentClassTransformWorker {

 private TypeCoercer _typeCoercer;
 
 public PageActivationUnitWorker(TypeCoercer typeCoercer) {
  this._typeCoercer = typeCoercer;
 }
 
 public void transform(ClassTransformation transformation, MutableComponentModel model) {
  List<String> fieldNames = transformation.findFieldsWithAnnotation(PageActivationUnit.class);
  
  if (fieldNames != null && fieldNames.size() > 0) {
   
   Map<String, String> fieldParamMap = new HashMap<String, String>();
   for (String fieldName : fieldNames) {
    PageActivationUnit annotation = transformation.getFieldAnnotation(fieldName,
      PageActivationUnit.class);
    fieldParamMap.put(fieldName, getParameterName(fieldName, annotation.value()));
   }
   
   String typeCoercer = transformation.addInjectedField(TypeCoercer.class, "typeCoercer", _typeCoercer);
   
   TransformMethodSignature activate
         = new TransformMethodSignature(Modifier.PROTECTED | Modifier.FINAL, "boolean",
                                       "onActivate",
                                       new String[] {EventContext.class.getName()}, null);
   
   TransformMethodSignature passivate
             = new TransformMethodSignature(Modifier.PROTECTED | Modifier.FINAL, "java.lang.Object[]",
                                           "onPassivate",
                                           null, null);
   
   BodyBuilder activeBuilder = new BodyBuilder().begin();
   activeBuilder.addln("java.util.Map keyValueMap = new java.util.HashMap();");
   activeBuilder.add("for (int i = 0; i < $1.getCount(); i++)");
   activeBuilder.begin();
   activeBuilder.addln("String []keyValue = ((String)$1.get(String.class, i)).split(\"-\");");
   activeBuilder.addln("String key = keyValue[0];");
   activeBuilder.addln("String value = (keyValue.length > 1) ? keyValue[1] : null;");
   activeBuilder.addln("keyValueMap.put(key, value);");
   activeBuilder.end();
   // end for
   for (int i = 0, size = fieldNames.size(); i < size; i++) {
    String fieldName = fieldNames.get(i);
    String fieldType = transformation.getFieldType(fieldName);
    activeBuilder.addln("String fieldValue=(String)keyValueMap.get(\"%s\");", fieldParamMap.get(fieldName));
    activeBuilder.addln("if (fieldValue != null) {");
    activeBuilder.addln("%s=(%s)%s.coerce(fieldValue, Class.forName(\"%s\"));", fieldName, fieldType, typeCoercer, fieldType);
    activeBuilder.addln("}");
   }
   activeBuilder.addln("return true;");
   // end method body
   activeBuilder.end();
     
   BodyBuilder deactiveBuilder = new BodyBuilder().begin();
   for (int i = 0, size = fieldNames.size(); i < size; i++) {
    String fieldName = fieldNames.get(i);
    
    if (i == size - 1) {
     deactiveBuilder.add("\"%s-\" +  (%s != null ? (String)%s.coerce(%s, String.class) : \"\")", fieldParamMap.get(fieldName), fieldName, typeCoercer, fieldName);
    } else {
     deactiveBuilder.add("\"%s-\" +  (%s != null ? (String)%s.coerce(%s, String.class) : \"\"),", fieldParamMap.get(fieldName), fieldName, typeCoercer, fieldName);
    }
   }
   deactiveBuilder.end();
   
   transformation.addTransformedMethod(activate, activeBuilder.toString());
   transformation.addTransformedMethod(passivate, "return new Object[]" + deactiveBuilder.toString() + ";");
  }
 }

 private String getParameterName(String fieldName, String annotatedName)
    {
        if (InternalUtils.isNonBlank(annotatedName)) return annotatedName;

        return InternalUtils.stripMemberName(fieldName);
    }
}

3. In app module

public static void contributeComponentClassTransformWorker(
            OrderedConfiguration<ComponentClassTransformWorker> configuration, TypeCoercer typeCoercer) {
     configuration.add("PageActivationUnit", new PageActivationUnitWorker(typeCoercer), "before:OnEvent");
    }

That's all.
One disadvantage is that you can't use primitive type for param field, so use Integer instead of int.

DH
http://www.gaonline.com.cn
----- Original Message ----- 
From: "Inge Solvoll" 
To: "Tapestry users" <us...@tapestry.apache.org>
Sent: Tuesday, December 08, 2009 4:14 PM
Subject: Re: Best practice for initializing page to default context


> Would it be possible for you to share that code with us? I don't necessarily
> want to use that approach, but it would be very helpful to see how you
> implemented it.
> 
> Inge
> 
> On Tue, Dec 8, 2009 at 9:10 AM, DH <ni...@gmail.com> wrote:
> 
>> Once I found it difficult too, and I never used  EventContext because I
>> think it is not better than multiple onActivate.
>>
>> Finally I wrote my own PageActivationContext called PageActivationUnit, the
>> difference is that PageActivationContext only can occur once, but
>> PageActivationUnit can be used in multiple fields.
>>
>> For example, a product search page, it has params like
>> category,keyword,pagesize,pageno,brand and so on. If using
>> PageActivationUnit, the java would be like:
>>
>> @PageActivationUnit
>> private Category category;
>>
>> @PageActivationUnit
>> private String keyword;
>>
>> @PageActivationUnit
>> private Integer pagesize;
>>
>> @PageActivationUnit
>> private Integer pageNo;
>>
>> @PageActivationUnit
>> private Brand brand;
>>
>> PageActivationUnit will handle all the activate and passivate event for me,
>> and the url requested would be like
>> '/searchpage/category-value/keyword-value/pagesize-10/pageNo-2/brand-value'.
>> Yes, I encode the field name in the url and its value in a pair.
>> Another advantage is if later another param 'orderBy' is added, I don't
>> have to change any code at all.
>>
>> DH
>> http://www.gaonline.com.cn
>>
>> ----- Original Message -----
>> From: "Kalle Korhonen"
>> To: "Tapestry users" <us...@tapestry.apache.org>
>> Sent: Tuesday, December 08, 2009 2:22 PM
>> Subject: Best practice for initializing page to default context
>>
>>
>> > Most things in T5 are delightfully simple, but I find this
>> > surprisingly difficult: how to best initialize a page to default
>> > context (and redirect to it). Imagine you have a search & result page.
>> > If I access the page without any context I want all records to be
>> > displayed. In onActivate() without parameters I set the context to
>> > *all* and return this to redirect, then I query the database in
>> > setupRender() to initialize the data for the grid. However, sorting
>> > the grid will also cause a call to onActivate() without parameters,
>> > resetting my data to the default context. The parameter-less call to
>> > onActivate() would be harmless if I didn't do a redirect from
>> > onActivate() but then I cannot set the default context and redirect.
>> > In setupRender() I could decide whether redirect is needed or not but
>> > at that time, I'm already committed to rendering the request.
>> >
>> > Because events cause a parameterless onActivate()  call, I tend to
>> > reserve onActivate() for possible component/event initialization needs
>> > only and always link to pages with initial context already set. I also
>> > find it roughly impossible to use overloaded versions of onActivate()
>> > and subsequently, if my page has multiple entry points, I typically
>> > resort to implementing it in a single onActivate(EventContext
>> > eventContext) operation containing a big if-else clause. Since the
>> > activation context is anyway sent with an event request (as in
>> > ?t:ac=mycontext), rather than using the encoded context for rendering,
>> > wouldn't it be just simpler if that context was used for activating
>> > the page for the event request and the following redirect for
>> > rendering would just use whatever context onPassivate() returns? What
>> > do others think, how do you handle this?
>> >
>> > Kalle
>> >
>> > ---------------------------------------------------------------------
>> > To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
>> > For additional commands, e-mail: users-help@tapestry.apache.org
>> >
>> >
>>
>

Re: Best practice for initializing page to default context

Posted by Inge Solvoll <in...@gmail.com>.
Would it be possible for you to share that code with us? I don't necessarily
want to use that approach, but it would be very helpful to see how you
implemented it.

Inge

On Tue, Dec 8, 2009 at 9:10 AM, DH <ni...@gmail.com> wrote:

> Once I found it difficult too, and I never used  EventContext because I
> think it is not better than multiple onActivate.
>
> Finally I wrote my own PageActivationContext called PageActivationUnit, the
> difference is that PageActivationContext only can occur once, but
> PageActivationUnit can be used in multiple fields.
>
> For example, a product search page, it has params like
> category,keyword,pagesize,pageno,brand and so on. If using
> PageActivationUnit, the java would be like:
>
> @PageActivationUnit
> private Category category;
>
> @PageActivationUnit
> private String keyword;
>
> @PageActivationUnit
> private Integer pagesize;
>
> @PageActivationUnit
> private Integer pageNo;
>
> @PageActivationUnit
> private Brand brand;
>
> PageActivationUnit will handle all the activate and passivate event for me,
> and the url requested would be like
> '/searchpage/category-value/keyword-value/pagesize-10/pageNo-2/brand-value'.
> Yes, I encode the field name in the url and its value in a pair.
> Another advantage is if later another param 'orderBy' is added, I don't
> have to change any code at all.
>
> DH
> http://www.gaonline.com.cn
>
> ----- Original Message -----
> From: "Kalle Korhonen"
> To: "Tapestry users" <us...@tapestry.apache.org>
> Sent: Tuesday, December 08, 2009 2:22 PM
> Subject: Best practice for initializing page to default context
>
>
> > Most things in T5 are delightfully simple, but I find this
> > surprisingly difficult: how to best initialize a page to default
> > context (and redirect to it). Imagine you have a search & result page.
> > If I access the page without any context I want all records to be
> > displayed. In onActivate() without parameters I set the context to
> > *all* and return this to redirect, then I query the database in
> > setupRender() to initialize the data for the grid. However, sorting
> > the grid will also cause a call to onActivate() without parameters,
> > resetting my data to the default context. The parameter-less call to
> > onActivate() would be harmless if I didn't do a redirect from
> > onActivate() but then I cannot set the default context and redirect.
> > In setupRender() I could decide whether redirect is needed or not but
> > at that time, I'm already committed to rendering the request.
> >
> > Because events cause a parameterless onActivate()  call, I tend to
> > reserve onActivate() for possible component/event initialization needs
> > only and always link to pages with initial context already set. I also
> > find it roughly impossible to use overloaded versions of onActivate()
> > and subsequently, if my page has multiple entry points, I typically
> > resort to implementing it in a single onActivate(EventContext
> > eventContext) operation containing a big if-else clause. Since the
> > activation context is anyway sent with an event request (as in
> > ?t:ac=mycontext), rather than using the encoded context for rendering,
> > wouldn't it be just simpler if that context was used for activating
> > the page for the event request and the following redirect for
> > rendering would just use whatever context onPassivate() returns? What
> > do others think, how do you handle this?
> >
> > Kalle
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> > For additional commands, e-mail: users-help@tapestry.apache.org
> >
> >
>

Re: Best practice for initializing page to default context

Posted by DH <ni...@gmail.com>.
Once I found it difficult too, and I never used  EventContext because I think it is not better than multiple onActivate.

Finally I wrote my own PageActivationContext called PageActivationUnit, the difference is that PageActivationContext only can occur once, but PageActivationUnit can be used in multiple fields.

For example, a product search page, it has params like category,keyword,pagesize,pageno,brand and so on. If using PageActivationUnit, the java would be like:

@PageActivationUnit
private Category category;

@PageActivationUnit
private String keyword;

@PageActivationUnit
private Integer pagesize;

@PageActivationUnit
private Integer pageNo;

@PageActivationUnit
private Brand brand;

PageActivationUnit will handle all the activate and passivate event for me, and the url requested would be like '/searchpage/category-value/keyword-value/pagesize-10/pageNo-2/brand-value'. 
Yes, I encode the field name in the url and its value in a pair.
Another advantage is if later another param 'orderBy' is added, I don't have to change any code at all.

DH
http://www.gaonline.com.cn

----- Original Message ----- 
From: "Kalle Korhonen" 
To: "Tapestry users" <us...@tapestry.apache.org>
Sent: Tuesday, December 08, 2009 2:22 PM
Subject: Best practice for initializing page to default context


> Most things in T5 are delightfully simple, but I find this
> surprisingly difficult: how to best initialize a page to default
> context (and redirect to it). Imagine you have a search & result page.
> If I access the page without any context I want all records to be
> displayed. In onActivate() without parameters I set the context to
> *all* and return this to redirect, then I query the database in
> setupRender() to initialize the data for the grid. However, sorting
> the grid will also cause a call to onActivate() without parameters,
> resetting my data to the default context. The parameter-less call to
> onActivate() would be harmless if I didn't do a redirect from
> onActivate() but then I cannot set the default context and redirect.
> In setupRender() I could decide whether redirect is needed or not but
> at that time, I'm already committed to rendering the request.
> 
> Because events cause a parameterless onActivate()  call, I tend to
> reserve onActivate() for possible component/event initialization needs
> only and always link to pages with initial context already set. I also
> find it roughly impossible to use overloaded versions of onActivate()
> and subsequently, if my page has multiple entry points, I typically
> resort to implementing it in a single onActivate(EventContext
> eventContext) operation containing a big if-else clause. Since the
> activation context is anyway sent with an event request (as in
> ?t:ac=mycontext), rather than using the encoded context for rendering,
> wouldn't it be just simpler if that context was used for activating
> the page for the event request and the following redirect for
> rendering would just use whatever context onPassivate() returns? What
> do others think, how do you handle this?
> 
> Kalle
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
> 
>