Re: Best way to extend a component?

2010-05-14 Thread Robin Komiwes
Component extension is one of my big preoccupation of my day work. That's
really a big question and there is no obvious answer.
I'm trying to explore ways with Tapestry 5 jQuery and I may blog on it in
the next weeks.

For example, I'm using workers to achieve what Benny Law said: adding mixins
to extend a component

And you have to add a bit of extra code per usage in the
> .tml (t:mixin="...").
>

Theses workers automatically adds mixins when transforming a class, i.e. :
http://github.com/got5/tapestry5-jquery/blob/master/src/main/java/org/got5/tapestry5/jquery/services/FormResourcesInclusionWorker.java

I'm also experimenting to create an abstract component class designed for
extension
http://github.com/got5/tapestry5-jquery/blob/master/src/main/java/org/got5/tapestry5/jquery/base/AbstractExtendableComponent.java

It is POC code but I think there are some ways to explore.


On Thu, May 13, 2010 at 11:34 PM, Steve Eynon <
steve.ey...@alienfactory.co.uk> wrote:

>  - a bit off topic I know but...
>
> I like "beforeRender()" and "afterRender()" for it's clear when they
> occur and why. Whereas beginRender() and endRender() sound like
> instructions - but onBeginRender() and onEndRender() on the other hand
> are also very clear, if not more so... Hmm...
>
>
> On 13 May 2010 17:12, Robert Zeigler  wrote:
> >
> > * Note: I misnamed the method beforeRender in my earlier e-mail; should
> be beginRender.  It's always bugged me that's it's "beginRender" and
> "afterRender" instead of "beginRender" and "endRender" or "beforeRender" and
> "afterRender". :)
>
> -
> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> For additional commands, e-mail: users-h...@tapestry.apache.org
>
>


Re: Best way to extend a component?

2010-05-13 Thread Steve Eynon
 - a bit off topic I know but...

I like "beforeRender()" and "afterRender()" for it's clear when they
occur and why. Whereas beginRender() and endRender() sound like
instructions - but onBeginRender() and onEndRender() on the other hand
are also very clear, if not more so... Hmm...


On 13 May 2010 17:12, Robert Zeigler  wrote:
>
> * Note: I misnamed the method beforeRender in my earlier e-mail; should be 
> beginRender.  It's always bugged me that's it's "beginRender" and 
> "afterRender" instead of "beginRender" and "endRender" or "beforeRender" and 
> "afterRender". :)

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



Re: Best way to extend a component?

2010-05-13 Thread Andreas Bohnert

so, I just hope 5.2 is around the corner ...

Robert Zeigler wrote:

Thiago is right; it's more like a pipeline, although not exactly a pipeline, either. :) 
It's still a state machine, stepping through the various render phases, but in each 
render phase, you have a series of "sub states", one for each mixin, + the 
component's own method.  In 5.2, you can explicitly define the order of execution to make 
sure your mixin executes before any others, etc. (all of the commands supported by 
OrderedConfiguration are supported).  And in 5.2, you can directly access a component's 
parameter from within the mixin, even if the component's parameter doesn't have a public 
getter.

Robert

On May 13, 2010, at 5/133:15 PM , Thiago H. de Paula Figueiredo wrote:

   

On Thu, 13 May 2010 17:09:45 -0300, Andreas Bohnert  wrote:

 

this looks very promising!!
that is what I was asking for and would solve at least my problem :)

So with mixins you do/can not override a method, you build a execution chain 
instead?
   

In a simplified view, mixins work like you had copied their methods to the 
component or page to which the mixin is applied. I wouldn't say it's an 
execution chain. This sounds more similar to Tapestry-IoC's pipelines.

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

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



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

   




Re: Best way to extend a component?

2010-05-13 Thread Robert Zeigler
Right.  I'm simply pointing out a way to do that with mixins.
For instance, we can add:

@BindParamater;
private SelectModel model;

private BlankOption originalOption;

and make beginRender* look something like this

void beginRender() {
  originalOption = blankOption;
  if (blankOption == AUTO) {
 //we're changing this /just/ before the select gets rendered, 
overriding the user-defined value (or the default value) so that Tapestry's 
"AUTO" branch of the switch never gets invoked; we've now made the component
 //do the right thing.
 if (required && model.getOptions.size() == 1) {
blankOption=NEVER;
 }  else {
blankOption=ALWAYS;
 }
  }
}

void afterRender() {
  blankOption = originalOption; //this isn't strictly necessary, but it's a 
nicety.
}

* Note: I misnamed the method beforeRender in my earlier e-mail; should be 
beginRender.  It's always bugged me that's it's "beginRender" and "afterRender" 
instead of "beginRender" and "endRender" or "beforeRender" and "afterRender". :)


Voila.  Apply your mixin.  "auto" behavior as desired, in a reusable format.

Robert

On May 13, 2010, at 5/131:44 PM , Benny Law wrote:

> As I explained before, I want to change the "auto" behavior to make it
> smarter. Currently, there is really no intelligence in the logic: a blank
> option is added if the field is not required, and no blank option is added
> if the field is required. When the option list is static, I can set the
> blank option myself, no problem. But when the list is dynamic, I don't know
> ahead of time how many options there will be, so I want the Select component
> to decide for me. If the field is required, I still want a blank option
> unless there is exactly one option because I don't want the first option to
> be selected as a default. I want the user to consciously choose a value.
> 
> On Thu, May 13, 2010 at 2:30 PM, Robert Zeigler  wrote:
> 
>> Why are you wanting to change the "auto" behavior in the first place?
>> In the few cases where there is no "sensible" default value, is using the
>> "blankLabel" and "blankOption" parameters so excruciatingly onerous? If so,
>> why not not simply wrap the select component in a custom select component
>> that provides the values you want? You would have to provide parameters in
>> your wrapper that passed through to the underlying select, but this is
>> certainly doable.
>> 
>> In fact, this particular case could be handled (I think?) in 5.2 in a very
>> clean way.  5.2 introduces the possibility for mixins to bind and manipulate
>> the containing component's parameters.  So you could, in theory, write a
>> mixin that sets the appropriate values for you.  Basically, you would have
>> something like this:
>> 
>> public class Blank {
>> 
>> @BindParameter
>> private boolean required;
>> 
>> @BindParameter
>> private BlankOption blankOption;
>> 
>> @BindParameter
>> private blankLabel blankLabel;
>> 
>> void beginRender() {//this will happen before the select's before
>> render...
>> if (//whatever condition you want) {
>>   blankOption=ALWAYS;//we've now overridden the default check in
>> showBlankOption() b/c by the time that renders, showBlankOption will see
>> "blankOption" as being ALWAYS instead of AUTO.
>>   blankLabel="Select one...";
>> } else {
>>   blankOption=NEVER;
>> }
>> }
>> 
>> }
>> 
>> Which you could then use like:
>> 
>> 
>> 
>> which seems very non-onerous to me. :)
>> 
>> Robert
>> 
>> On May 13, 2010, at 5/1312:56 PM , Benny Law wrote:
>> 
>>> I did look at the demo Geoff posted. How is that going to provide what I
>>> need? I'm sorry, but I fail to see this "easy fix" you mentioned. Maybe
>> you
>>> can be a bit more specific?
>>> 
>>> 
>>> On Thu, May 13, 2010 at 1:15 PM, Christian Riedel
>>> wrote:
>>> 
 Well I agree that some more extensibility could be made here and there.
 That particular problem looks like it's worth a JIRA with a patch from
>> you
 that makes the component extensible to fix that problem :)
 
 On the other hand there is an easy fix. Just look at the demo Geoff
>> posted.
 Why do you insist on the BlankOption thing? Just add your blank option
 directly to the list select-options. Then there is no blank option at
>> all...
 
 
 Am 13.05.2010 um 16:43 schrieb Benny Law:
 
> Thanks Geoff, but no, it doesn't. Your example shows how the Select
> component works as is. What I need is a smarter interpretation of
> BlankOption.AUTO. Basically, if you look at the showBlankOption()
>> method
 in
> the Select class, you see this:
> 
>  switch (blankOption)
>  {
>  case ALWAYS:
>  return true;
> 
>  case NEVER:
>  return false;
> 
>  default:
>  return !isRequired();
>  }
> 
> What I want is this:
> 
>  switch (blankOption) {
> 
>  case ALWAYS:
>

Re: Best way to extend a component?

2010-05-13 Thread Thiago H. de Paula Figueiredo
On Thu, 13 May 2010 17:56:22 -0300, Benny Law   
wrote:



Precisely. Thank you, Alex.
Mixins are excellent for some things, but not a replacement for  
subclassing for every case.


I agree. There's a very hard balance between opening and keeping backward  
compatibility.



And you have to add a bit of extra code per usage in the
.tml (t:mixin="...").


I don't see as a problem at all, but it's my taste, of course. :)

--
Thiago H. de Paula Figueiredo
Independent Java, Apache Tapestry 5 and Hibernate consultant, developer,  
and instructor

Owner, Ars Machina Tecnologia da Informação Ltda.
http://www.arsmachina.com.br

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



Re: Best way to extend a component?

2010-05-13 Thread Robert Zeigler
Thiago is right; it's more like a pipeline, although not exactly a pipeline, 
either. :) It's still a state machine, stepping through the various render 
phases, but in each render phase, you have a series of "sub states", one for 
each mixin, + the component's own method.  In 5.2, you can explicitly define 
the order of execution to make sure your mixin executes before any others, etc. 
(all of the commands supported by OrderedConfiguration are supported).  And in 
5.2, you can directly access a component's parameter from within the mixin, 
even if the component's parameter doesn't have a public getter.

Robert

On May 13, 2010, at 5/133:15 PM , Thiago H. de Paula Figueiredo wrote:

> On Thu, 13 May 2010 17:09:45 -0300, Andreas Bohnert  
> wrote:
> 
>> this looks very promising!!
>> that is what I was asking for and would solve at least my problem :)
>> 
>> So with mixins you do/can not override a method, you build a execution chain 
>> instead?
> 
> In a simplified view, mixins work like you had copied their methods to the 
> component or page to which the mixin is applied. I wouldn't say it's an 
> execution chain. This sounds more similar to Tapestry-IoC's pipelines.
> 
> -- 
> Thiago H. de Paula Figueiredo
> Independent Java, Apache Tapestry 5 and Hibernate consultant, developer, and 
> instructor
> Owner, Ars Machina Tecnologia da Informação Ltda.
> http://www.arsmachina.com.br
> 
> -
> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> For additional commands, e-mail: users-h...@tapestry.apache.org


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



Re: Best way to extend a component?

2010-05-13 Thread Benny Law
Precisely. Thank you, Alex.
Mixins are excellent for some things, but not a replacement for subclassing
for every case. And you have to add a bit of extra code per usage in the
.tml (t:mixin="...").

On Thu, May 13, 2010 at 4:20 PM, Alex Kotchnev  wrote:

> I think it is fair to say that T5 has indeed gone to great lengths to try
> to
> isolate the user from changes in the framework. Thus, if T5 decides to
> change the internal implementation of how a Select works, there wouldn't be
> 100 people screaming "See, we told you that Tapestry has never been and
> will
> never will be backwards compatible".
>
> That is great and all, except that you run into the infamous T5 learning
> curve. Most developers that start with T5 already know a thing or two about
> Java, object orientation, and server side / web programming . Thus, if you
> give them some objects / classes, most people know how to extend a class
> and
> try to inject some custom behavior that way. There certainly are
> "alternative" ways of using the existing components (e.g. wrapping them in
> others, mixins, whatever) that in the general sense provide the needed
> extensibility. However,  getting your head around those approaches (e.g.
> mixins), seems to require a big mountain of knowledge before being able to
> do some simple things that seem like they should be easily achievable
> through subclassing.
>
> So, the "next best option" (and I really use "best" in a very loose way, as
> in the least evil) is to go out and copy the source (I think I've seen a
> few
> recommendations on the list to do that "if you don't like not being able to
> subclass") of the existing components ( which most people can understand),
> and make their tweaks in the user's copy of the component. Thus, if the
> framework moves on, it can technically say "See, we did all of this in a
> backwards compatible way, everyone who was using our public API is still in
> a good shape" . Now, the problem is that when the user copied the source
> from the T5 components, there is a pretty good chance that the copied
> source
> relies on a whole bunch of "internal services" (which give no guarantees of
> backward compatibility), and when the internal services move on, all the
> breakage will occur in the "copied" code. Thus, technically, although the
> public APIs did remain consistent and pristine, the end result is that by
> encouraging this approach the breakage becomes a lot bigger and seemingly
> harder to fix ('cause we all know that when you copy the source of a T5
> component you might not understand ALL that's inside).
>
> Anyway, I don't really have a solution - both sides have valid points.
> Certainly, the framework authors should be able to evolve the framework as
> they see fit w/o having people screaming in their ear about backward
> compatibility. At the same point, the combination of not being able to
> subclass plus the plethora of new (and sometimes not easy to grasp)
> concepts
> makes it way too difficult when you just want to do "this little tweak"
> (even with the understanding that you're tying yourself to the
> implementation). T5 prides itself on how easy it is to create new
> components
> - create a class, a template, and boom - you can start using it just like
> any other component. Maybe there are things that can be done in limited
> ways
> to open up the most common components in ways that don't break their
> encapsulation (e.g. maybe events) but allow for easier extension. Back to
> the issue of documentation (which the wiki might help with), maybe as a
> community we can do a better job of explaining and giving examples of these
> new concepts .
>
> Anyway, my 2c.
>
> Regards,
>
> Alex K
>
>
>
> On Thu, May 13, 2010 at 3:43 PM, Benny Law  wrote:
>
> > On Thu, May 13, 2010 at 3:29 PM, Thiago H. de Paula Figueiredo <
> > thiag...@gmail.com> wrote:
> >
> > > On Thu, 13 May 2010 15:44:50 -0300, Benny Law 
> > > wrote:
> > >
> > >  I want the user to consciously choose a value.
> > >>
> > >
> > > 
> > does
> > > the trick, no?
> > >
> >
> > No, because I don't want the blank option if there is only one valid
> option
> > in the model, or if there is a valid initial value (if the bound property
> > is
> > not null to begin with and is one of the valid options). Again, this
> logic
> > depends on the number of options available (as well as the current
> value),
> > and I don't know the option list size if it is a dynamic list.
> >
> > I want this logic in the Select component across the board because it is
> > generic and not specific to special cases. I don't want to incur extra
> code
> > per usage. The simplest solution is just to override the spot in Select
> > where it decides what to do when BlankOption is AUTO. It's a very simple
> > case where inheritance + override would be very effective.
> >
> >
> > >
> > > --
> > > Thiago H. de Paula Figueiredo
> > > Independent Java, Apache Tapestry 5 and Hibernate consultant,
> developer,
> > > and instructor
> >

Re: Best way to extend a component?

2010-05-13 Thread Andreas Bohnert

this was the good roundup!

Andreas

Alex Kotchnev wrote:

I think it is fair to say that T5 has indeed gone to great lengths to try to
isolate the user from changes in the framework. Thus, if T5 decides to
change the internal implementation of how a Select works, there wouldn't be
100 people screaming "See, we told you that Tapestry has never been and will
never will be backwards compatible".

That is great and all, except that you run into the infamous T5 learning
curve. Most developers that start with T5 already know a thing or two about
Java, object orientation, and server side / web programming . Thus, if you
give them some objects / classes, most people know how to extend a class and
try to inject some custom behavior that way. There certainly are
"alternative" ways of using the existing components (e.g. wrapping them in
others, mixins, whatever) that in the general sense provide the needed
extensibility. However,  getting your head around those approaches (e.g.
mixins), seems to require a big mountain of knowledge before being able to
do some simple things that seem like they should be easily achievable
through subclassing.

So, the "next best option" (and I really use "best" in a very loose way, as
in the least evil) is to go out and copy the source (I think I've seen a few
recommendations on the list to do that "if you don't like not being able to
subclass") of the existing components ( which most people can understand),
and make their tweaks in the user's copy of the component. Thus, if the
framework moves on, it can technically say "See, we did all of this in a
backwards compatible way, everyone who was using our public API is still in
a good shape" . Now, the problem is that when the user copied the source
from the T5 components, there is a pretty good chance that the copied source
relies on a whole bunch of "internal services" (which give no guarantees of
backward compatibility), and when the internal services move on, all the
breakage will occur in the "copied" code. Thus, technically, although the
public APIs did remain consistent and pristine, the end result is that by
encouraging this approach the breakage becomes a lot bigger and seemingly
harder to fix ('cause we all know that when you copy the source of a T5
component you might not understand ALL that's inside).

Anyway, I don't really have a solution - both sides have valid points.
Certainly, the framework authors should be able to evolve the framework as
they see fit w/o having people screaming in their ear about backward
compatibility. At the same point, the combination of not being able to
subclass plus the plethora of new (and sometimes not easy to grasp) concepts
makes it way too difficult when you just want to do "this little tweak"
(even with the understanding that you're tying yourself to the
implementation). T5 prides itself on how easy it is to create new components
- create a class, a template, and boom - you can start using it just like
any other component. Maybe there are things that can be done in limited ways
to open up the most common components in ways that don't break their
encapsulation (e.g. maybe events) but allow for easier extension. Back to
the issue of documentation (which the wiki might help with), maybe as a
community we can do a better job of explaining and giving examples of these
new concepts .

Anyway, my 2c.

Regards,

Alex K



On Thu, May 13, 2010 at 3:43 PM, Benny Law  wrote:

   

On Thu, May 13, 2010 at 3:29 PM, Thiago H. de Paula Figueiredo<
thiag...@gmail.com>  wrote:

 

On Thu, 13 May 2010 15:44:50 -0300, Benny Law
wrote:

  I want the user to consciously choose a value.
   

   

does
 

the trick, no?

   

No, because I don't want the blank option if there is only one valid option
in the model, or if there is a valid initial value (if the bound property
is
not null to begin with and is one of the valid options). Again, this logic
depends on the number of options available (as well as the current value),
and I don't know the option list size if it is a dynamic list.

I want this logic in the Select component across the board because it is
generic and not specific to special cases. I don't want to incur extra code
per usage. The simplest solution is just to override the spot in Select
where it decides what to do when BlankOption is AUTO. It's a very simple
case where inheritance + override would be very effective.


 

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

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


   


   




Re: Res: Best way to extend a component?

2010-05-13 Thread Andreas Bohnert

very good roundup!

Everton Agner wrote:

If component classes were not meant to be subclassed, wouldn't it be nice to make them as 
"final classes"?

It would not let people lose some time on it, since it would be seen at 
compilation time, and it's kinda logical.


- Everton Agner Ramos






De: Alex Kotchnev
Para: Tapestry users
Enviadas: Quinta-feira, 13 de Maio de 2010 17:20:41
Assunto: Re: Best way to extend a component?

I think it is fair to say that T5 has indeed gone to great lengths to try to
isolate the user from changes in the framework. Thus, if T5 decides to
change the internal implementation of how a Select works, there wouldn't be
100 people screaming "See, we told you that Tapestry has never been and will
never will be backwards compatible".

That is great and all, except that you run into the infamous T5 learning
curve. Most developers that start with T5 already know a thing or two about
Java, object orientation, and server side / web programming . Thus, if you
give them some objects / classes, most people know how to extend a class and
try to inject some custom behavior that way. There certainly are
"alternative" ways of using the existing components (e.g. wrapping them in
others, mixins, whatever) that in the general sense provide the needed
extensibility. However,  getting your head around those approaches (e.g.
mixins), seems to require a big mountain of knowledge before being able to
do some simple things that seem like they should be easily achievable
through subclassing.

So, the "next best option" (and I really use "best" in a very loose way, as
in the least evil) is to go out and copy the source (I think I've seen a few
recommendations on the list to do that "if you don't like not being able to
subclass") of the existing components ( which most people can understand),
and make their tweaks in the user's copy of the component. Thus, if the
framework moves on, it can technically say "See, we did all of this in a
backwards compatible way, everyone who was using our public API is still in
a good shape" . Now, the problem is that when the user copied the source
from the T5 components, there is a pretty good chance that the copied source
relies on a whole bunch of "internal services" (which give no guarantees of
backward compatibility), and when the internal services move on, all the
breakage will occur in the "copied" code. Thus, technically, although the
public APIs did remain consistent and pristine, the end result is that by
encouraging this approach the breakage becomes a lot bigger and seemingly
harder to fix ('cause we all know that when you copy the source of a T5
component you might not understand ALL that's inside).

Anyway, I don't really have a solution - both sides have valid points.
Certainly, the framework authors should be able to evolve the framework as
they see fit w/o having people screaming in their ear about backward
compatibility. At the same point, the combination of not being able to
subclass plus the plethora of new (and sometimes not easy to grasp) concepts
makes it way too difficult when you just want to do "this little tweak"
(even with the understanding that you're tying yourself to the
implementation). T5 prides itself on how easy it is to create new components
- create a class, a template, and boom - you can start using it just like
any other component. Maybe there are things that can be done in limited ways
to open up the most common components in ways that don't break their
encapsulation (e.g. maybe events) but allow for easier extension. Back to
the issue of documentation (which the wiki might help with), maybe as a
community we can do a better job of explaining and giving examples of these
new concepts .

Anyway, my 2c.

Regards,

Alex K



On Thu, May 13, 2010 at 3:43 PM, Benny Law  wrote:

   

On Thu, May 13, 2010 at 3:29 PM, Thiago H. de Paula Figueiredo<
thiag...@gmail.com>  wrote:

 

On Thu, 13 May 2010 15:44:50 -0300, Benny Law
wrote:

  I want the user to consciously choose a value.
   

   

does
 

the trick, no?

   

No, because I don't want the blank option if there is only one valid option
in the model, or if there is a valid initial value (if the bound property
is
not null to begin with and is one of the valid options). Again, this logic
depends on the number of options available (as well as the current value),
and I don't know the option list size if it is a dynamic list.

I want this logic in the Select component across the board because it is
generic and not specific to special cases. I don't want to incur extra code
per usage. The simplest solution is just to override the spot in Select
where it decides what to do when BlankOption is AUTO. It's a very simple
case where inheritance + override would 

Res: Best way to extend a component?

2010-05-13 Thread Everton Agner
If component classes were not meant to be subclassed, wouldn't it be nice to 
make them as "final classes"?

It would not let people lose some time on it, since it would be seen at 
compilation time, and it's kinda logical.


- Everton Agner Ramos






De: Alex Kotchnev 
Para: Tapestry users 
Enviadas: Quinta-feira, 13 de Maio de 2010 17:20:41
Assunto: Re: Best way to extend a component?

I think it is fair to say that T5 has indeed gone to great lengths to try to
isolate the user from changes in the framework. Thus, if T5 decides to
change the internal implementation of how a Select works, there wouldn't be
100 people screaming "See, we told you that Tapestry has never been and will
never will be backwards compatible".

That is great and all, except that you run into the infamous T5 learning
curve. Most developers that start with T5 already know a thing or two about
Java, object orientation, and server side / web programming . Thus, if you
give them some objects / classes, most people know how to extend a class and
try to inject some custom behavior that way. There certainly are
"alternative" ways of using the existing components (e.g. wrapping them in
others, mixins, whatever) that in the general sense provide the needed
extensibility. However,  getting your head around those approaches (e.g.
mixins), seems to require a big mountain of knowledge before being able to
do some simple things that seem like they should be easily achievable
through subclassing.

So, the "next best option" (and I really use "best" in a very loose way, as
in the least evil) is to go out and copy the source (I think I've seen a few
recommendations on the list to do that "if you don't like not being able to
subclass") of the existing components ( which most people can understand),
and make their tweaks in the user's copy of the component. Thus, if the
framework moves on, it can technically say "See, we did all of this in a
backwards compatible way, everyone who was using our public API is still in
a good shape" . Now, the problem is that when the user copied the source
from the T5 components, there is a pretty good chance that the copied source
relies on a whole bunch of "internal services" (which give no guarantees of
backward compatibility), and when the internal services move on, all the
breakage will occur in the "copied" code. Thus, technically, although the
public APIs did remain consistent and pristine, the end result is that by
encouraging this approach the breakage becomes a lot bigger and seemingly
harder to fix ('cause we all know that when you copy the source of a T5
component you might not understand ALL that's inside).

Anyway, I don't really have a solution - both sides have valid points.
Certainly, the framework authors should be able to evolve the framework as
they see fit w/o having people screaming in their ear about backward
compatibility. At the same point, the combination of not being able to
subclass plus the plethora of new (and sometimes not easy to grasp) concepts
makes it way too difficult when you just want to do "this little tweak"
(even with the understanding that you're tying yourself to the
implementation). T5 prides itself on how easy it is to create new components
- create a class, a template, and boom - you can start using it just like
any other component. Maybe there are things that can be done in limited ways
to open up the most common components in ways that don't break their
encapsulation (e.g. maybe events) but allow for easier extension. Back to
the issue of documentation (which the wiki might help with), maybe as a
community we can do a better job of explaining and giving examples of these
new concepts .

Anyway, my 2c.

Regards,

Alex K



On Thu, May 13, 2010 at 3:43 PM, Benny Law  wrote:

> On Thu, May 13, 2010 at 3:29 PM, Thiago H. de Paula Figueiredo <
> thiag...@gmail.com> wrote:
>
> > On Thu, 13 May 2010 15:44:50 -0300, Benny Law 
> > wrote:
> >
> >  I want the user to consciously choose a value.
> >>
> >
> > 
> does
> > the trick, no?
> >
>
> No, because I don't want the blank option if there is only one valid option
> in the model, or if there is a valid initial value (if the bound property
> is
> not null to begin with and is one of the valid options). Again, this logic
> depends on the number of options available (as well as the current value),
> and I don't know the option list size if it is a dynamic list.
>
> I want this logic in the Select component across the board because it is
> generic and not specific to special cases. I don't want to incur extra code
> per usage. The simplest solution is just to override the spot in Select
> where it decides what to do when B

Re: Best way to extend a component?

2010-05-13 Thread Alex Kotchnev
I think it is fair to say that T5 has indeed gone to great lengths to try to
isolate the user from changes in the framework. Thus, if T5 decides to
change the internal implementation of how a Select works, there wouldn't be
100 people screaming "See, we told you that Tapestry has never been and will
never will be backwards compatible".

That is great and all, except that you run into the infamous T5 learning
curve. Most developers that start with T5 already know a thing or two about
Java, object orientation, and server side / web programming . Thus, if you
give them some objects / classes, most people know how to extend a class and
try to inject some custom behavior that way. There certainly are
"alternative" ways of using the existing components (e.g. wrapping them in
others, mixins, whatever) that in the general sense provide the needed
extensibility. However,  getting your head around those approaches (e.g.
mixins), seems to require a big mountain of knowledge before being able to
do some simple things that seem like they should be easily achievable
through subclassing.

So, the "next best option" (and I really use "best" in a very loose way, as
in the least evil) is to go out and copy the source (I think I've seen a few
recommendations on the list to do that "if you don't like not being able to
subclass") of the existing components ( which most people can understand),
and make their tweaks in the user's copy of the component. Thus, if the
framework moves on, it can technically say "See, we did all of this in a
backwards compatible way, everyone who was using our public API is still in
a good shape" . Now, the problem is that when the user copied the source
from the T5 components, there is a pretty good chance that the copied source
relies on a whole bunch of "internal services" (which give no guarantees of
backward compatibility), and when the internal services move on, all the
breakage will occur in the "copied" code. Thus, technically, although the
public APIs did remain consistent and pristine, the end result is that by
encouraging this approach the breakage becomes a lot bigger and seemingly
harder to fix ('cause we all know that when you copy the source of a T5
component you might not understand ALL that's inside).

Anyway, I don't really have a solution - both sides have valid points.
Certainly, the framework authors should be able to evolve the framework as
they see fit w/o having people screaming in their ear about backward
compatibility. At the same point, the combination of not being able to
subclass plus the plethora of new (and sometimes not easy to grasp) concepts
makes it way too difficult when you just want to do "this little tweak"
(even with the understanding that you're tying yourself to the
implementation). T5 prides itself on how easy it is to create new components
- create a class, a template, and boom - you can start using it just like
any other component. Maybe there are things that can be done in limited ways
to open up the most common components in ways that don't break their
encapsulation (e.g. maybe events) but allow for easier extension. Back to
the issue of documentation (which the wiki might help with), maybe as a
community we can do a better job of explaining and giving examples of these
new concepts .

Anyway, my 2c.

Regards,

Alex K



On Thu, May 13, 2010 at 3:43 PM, Benny Law  wrote:

> On Thu, May 13, 2010 at 3:29 PM, Thiago H. de Paula Figueiredo <
> thiag...@gmail.com> wrote:
>
> > On Thu, 13 May 2010 15:44:50 -0300, Benny Law 
> > wrote:
> >
> >  I want the user to consciously choose a value.
> >>
> >
> > 
> does
> > the trick, no?
> >
>
> No, because I don't want the blank option if there is only one valid option
> in the model, or if there is a valid initial value (if the bound property
> is
> not null to begin with and is one of the valid options). Again, this logic
> depends on the number of options available (as well as the current value),
> and I don't know the option list size if it is a dynamic list.
>
> I want this logic in the Select component across the board because it is
> generic and not specific to special cases. I don't want to incur extra code
> per usage. The simplest solution is just to override the spot in Select
> where it decides what to do when BlankOption is AUTO. It's a very simple
> case where inheritance + override would be very effective.
>
>
> >
> > --
> > Thiago H. de Paula Figueiredo
> > Independent Java, Apache Tapestry 5 and Hibernate consultant, developer,
> > and instructor
> > Owner, Ars Machina Tecnologia da Informação Ltda.
> > http://www.arsmachina.com.br
> >
> > -
> > To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> > For additional commands, e-mail: users-h...@tapestry.apache.org
> >
> >
>


Re: Best way to extend a component?

2010-05-13 Thread Thiago H. de Paula Figueiredo
On Thu, 13 May 2010 17:09:45 -0300, Andreas Bohnert   
wrote:



this looks very promising!!
that is what I was asking for and would solve at least my problem :)

So with mixins you do/can not override a method, you build a execution  
chain instead?


In a simplified view, mixins work like you had copied their methods to the  
component or page to which the mixin is applied. I wouldn't say it's an  
execution chain. This sounds more similar to Tapestry-IoC's pipelines.


--
Thiago H. de Paula Figueiredo
Independent Java, Apache Tapestry 5 and Hibernate consultant, developer,  
and instructor

Owner, Ars Machina Tecnologia da Informação Ltda.
http://www.arsmachina.com.br

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



Re: Best way to extend a component?

2010-05-13 Thread Andreas Bohnert

this looks very promising!!
that is what I was asking for and would solve at least my problem :)

So with mixins you do/can not override a method, you build a execution 
chain instead?


Andreas

Robert Zeigler wrote:

Why are you wanting to change the "auto" behavior in the first place?
In the few cases where there is no "sensible" default value, is using the "blankLabel" 
and "blankOption" parameters so excruciatingly onerous? If so, why not not simply wrap the select 
component in a custom select component that provides the values you want? You would have to provide 
parameters in your wrapper that passed through to the underlying select, but this is certainly doable.

In fact, this particular case could be handled (I think?) in 5.2 in a very 
clean way.  5.2 introduces the possibility for mixins to bind and manipulate 
the containing component's parameters.  So you could, in theory, write a mixin 
that sets the appropriate values for you.  Basically, you would have something 
like this:

public class Blank {

@BindParameter
private boolean required;

@BindParameter
private BlankOption blankOption;

@BindParameter
private blankLabel blankLabel;

void beforeRender() {//this will happen before the select's before render...
   if (//whatever condition you want) {
 blankOption=ALWAYS;//we've now overridden the default check in showBlankOption() b/c 
by the time that renders, showBlankOption will see "blankOption" as being 
ALWAYS instead of AUTO.
 blankLabel="Select one...";
   } else {
 blankOption=NEVER;
   }
}

}

Which you could then use like:



which seems very non-onerous to me. :)

Robert

On May 13, 2010, at 5/1312:56 PM , Benny Law wrote:

   

I did look at the demo Geoff posted. How is that going to provide what I
need? I'm sorry, but I fail to see this "easy fix" you mentioned. Maybe you
can be a bit more specific?


On Thu, May 13, 2010 at 1:15 PM, Christian Riedel
wrote:

 

Well I agree that some more extensibility could be made here and there.
That particular problem looks like it's worth a JIRA with a patch from you
that makes the component extensible to fix that problem :)

On the other hand there is an easy fix. Just look at the demo Geoff posted.
Why do you insist on the BlankOption thing? Just add your blank option
directly to the list select-options. Then there is no blank option at all...


Am 13.05.2010 um 16:43 schrieb Benny Law:

   

Thanks Geoff, but no, it doesn't. Your example shows how the Select
component works as is. What I need is a smarter interpretation of
BlankOption.AUTO. Basically, if you look at the showBlankOption() method
 

in
   

the Select class, you see this:

   switch (blankOption)
   {
   case ALWAYS:
   return true;

   case NEVER:
   return false;

   default:
   return !isRequired();
   }

What I want is this:

   switch (blankOption) {

   case ALWAYS:
   return true;

   case NEVER:
   return false;

   // AUTO: Decide based on model size, current value, and required
 

or
   

not.
   default:
   List  options = model.getOptions();

   if (options.size() == 1) {
   return !isRequired();
   }
   if (options.size() == 0 || value == null) {
   return true;
   }
   if (value != null) {
   for (OptionModel option: options) {
   if (option.getValue().equals( value )) {
   return !isRequired();
   }
   }
   }
   return true;
   }

I hope it's clear what I want to achieve with the enhanced logic for
 

AUTO.
   

Regards,

Benny

On Thu, May 13, 2010 at 10:29 AM, Geoff Callender<
geoff.callender.jumpst...@gmail.com>  wrote:

 

Does this help at all?



   

http://jumpstart.doublenegative.com.au/jumpstart/examples/select/varied/$N/$N/$N/$N
   

Cheers,

Geoff

On 14/05/2010, at 12:11 AM, Benny Law wrote:

   

We are talking about subclassing a Tapestry component here. To give you
 

an
   

example, I wanted to subclass the Select component to override how
BlankOption.AUTO is interpreted. I wanted the logic to not just look at
 

the
   

required property but also to consider how many options are available
 

and
   

whether there is a current value. (I find the current logic lacking
 

because,
   

for example, the first option will always be selected as default if
 

required
   

is true, but there may not be a meaningful default for the field.) All
 

I
   

needed to do was to override the showBlankOption() method, but I
 

couldn't
   

because it's a private method. I ended up making a duplicate of the
 

Select
   

component with a modified s

Re: Best way to extend a component?

2010-05-13 Thread Benny Law
On Thu, May 13, 2010 at 3:29 PM, Thiago H. de Paula Figueiredo <
thiag...@gmail.com> wrote:

> On Thu, 13 May 2010 15:44:50 -0300, Benny Law 
> wrote:
>
>  I want the user to consciously choose a value.
>>
>
>  does
> the trick, no?
>

No, because I don't want the blank option if there is only one valid option
in the model, or if there is a valid initial value (if the bound property is
not null to begin with and is one of the valid options). Again, this logic
depends on the number of options available (as well as the current value),
and I don't know the option list size if it is a dynamic list.

I want this logic in the Select component across the board because it is
generic and not specific to special cases. I don't want to incur extra code
per usage. The simplest solution is just to override the spot in Select
where it decides what to do when BlankOption is AUTO. It's a very simple
case where inheritance + override would be very effective.


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


Re: Best way to extend a component?

2010-05-13 Thread Thiago H. de Paula Figueiredo
On Thu, 13 May 2010 15:44:50 -0300, Benny Law   
wrote:



I want the user to consciously choose a value.


 does  
the trick, no?


--
Thiago H. de Paula Figueiredo
Independent Java, Apache Tapestry 5 and Hibernate consultant, developer,  
and instructor

Owner, Ars Machina Tecnologia da Informação Ltda.
http://www.arsmachina.com.br

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



Re: Best way to extend a component?

2010-05-13 Thread Christian Riedel

> If the field is required, I still want a blank option
> unless there is exactly one option because I don't want the first option to
> be selected as a default. I want the user to consciously choose a value.
> 

...wait. what? if it is required is probably not valid to choose the blank 
option, right? sounds like a "marketing" requirement to me...



> On Thu, May 13, 2010 at 2:30 PM, Robert Zeigler  wrote:
> 
>> Why are you wanting to change the "auto" behavior in the first place?
>> In the few cases where there is no "sensible" default value, is using the
>> "blankLabel" and "blankOption" parameters so excruciatingly onerous? If so,
>> why not not simply wrap the select component in a custom select component
>> that provides the values you want? You would have to provide parameters in
>> your wrapper that passed through to the underlying select, but this is
>> certainly doable.
>> 
>> In fact, this particular case could be handled (I think?) in 5.2 in a very
>> clean way.  5.2 introduces the possibility for mixins to bind and manipulate
>> the containing component's parameters.  So you could, in theory, write a
>> mixin that sets the appropriate values for you.  Basically, you would have
>> something like this:
>> 
>> public class Blank {
>> 
>> @BindParameter
>> private boolean required;
>> 
>> @BindParameter
>> private BlankOption blankOption;
>> 
>> @BindParameter
>> private blankLabel blankLabel;
>> 
>> void beforeRender() {//this will happen before the select's before
>> render...
>> if (//whatever condition you want) {
>>   blankOption=ALWAYS;//we've now overridden the default check in
>> showBlankOption() b/c by the time that renders, showBlankOption will see
>> "blankOption" as being ALWAYS instead of AUTO.
>>   blankLabel="Select one...";
>> } else {
>>   blankOption=NEVER;
>> }
>> }
>> 
>> }
>> 
>> Which you could then use like:
>> 
>> 
>> 
>> which seems very non-onerous to me. :)
>> 
>> Robert
>> 
>> On May 13, 2010, at 5/1312:56 PM , Benny Law wrote:
>> 
>>> I did look at the demo Geoff posted. How is that going to provide what I
>>> need? I'm sorry, but I fail to see this "easy fix" you mentioned. Maybe
>> you
>>> can be a bit more specific?
>>> 
>>> 
>>> On Thu, May 13, 2010 at 1:15 PM, Christian Riedel
>>> wrote:
>>> 
 Well I agree that some more extensibility could be made here and there.
 That particular problem looks like it's worth a JIRA with a patch from
>> you
 that makes the component extensible to fix that problem :)
 
 On the other hand there is an easy fix. Just look at the demo Geoff
>> posted.
 Why do you insist on the BlankOption thing? Just add your blank option
 directly to the list select-options. Then there is no blank option at
>> all...
 
 
 Am 13.05.2010 um 16:43 schrieb Benny Law:
 
> Thanks Geoff, but no, it doesn't. Your example shows how the Select
> component works as is. What I need is a smarter interpretation of
> BlankOption.AUTO. Basically, if you look at the showBlankOption()
>> method
 in
> the Select class, you see this:
> 
>  switch (blankOption)
>  {
>  case ALWAYS:
>  return true;
> 
>  case NEVER:
>  return false;
> 
>  default:
>  return !isRequired();
>  }
> 
> What I want is this:
> 
>  switch (blankOption) {
> 
>  case ALWAYS:
>  return true;
> 
>  case NEVER:
>  return false;
> 
>  // AUTO: Decide based on model size, current value, and required
 or
> not.
>  default:
>  List options = model.getOptions();
> 
>  if (options.size() == 1) {
>  return !isRequired();
>  }
>  if (options.size() == 0 || value == null) {
>  return true;
>  }
>  if (value != null) {
>  for (OptionModel option: options) {
>  if (option.getValue().equals( value )) {
>  return !isRequired();
>  }
>  }
>  }
>  return true;
>  }
> 
> I hope it's clear what I want to achieve with the enhanced logic for
 AUTO.
> 
> Regards,
> 
> Benny
> 
> On Thu, May 13, 2010 at 10:29 AM, Geoff Callender <
> geoff.callender.jumpst...@gmail.com> wrote:
> 
>> Does this help at all?
>> 
>> 
>> 
 
>> http://jumpstart.doublenegative.com.au/jumpstart/examples/select/varied/$N/$N/$N/$N
>> 
>> Cheers,
>> 
>> Geoff
>> 
>> On 14/05/2010, at 12:11 AM, Benny Law wrote:
>> 
>>> We are talking about subclassing a Tapestry component here. To give
>> you
>> an
>>> example, I wanted to subclass the Select component to override how
>>> BlankOption.AUTO is interpreted. I wanted the logic to not j

Re: Best way to extend a component?

2010-05-13 Thread Christian Riedel
...add some really heavy logic to your page/component:

tml:


 


page:


@Property
private String[] options;

@Persist
@Property
private String o;

@SetupRender
void setup() {

options = reallyExpensiveDBQuery();

if (options.length > 1) {

options = addDefaultToOptions();
}
}

private String[] addDefaultToOptions() {

final String[] result = new String[options.length + 1];

result[0] = "___default___";

for (int i = 1; i <= options.length; i++) {
result[i] = options[i-1];
}

return result;
}

private String[] reallyExpensiveDBQuery() {

return new String[] { "1", "2" };
}

public String getBlank() {

return "NEVER";
}


is that the solution to your problem?



Am 13.05.2010 um 20:44 schrieb Benny Law:

> As I explained before, I want to change the "auto" behavior to make it
> smarter. Currently, there is really no intelligence in the logic: a blank
> option is added if the field is not required, and no blank option is added
> if the field is required. When the option list is static, I can set the
> blank option myself, no problem. But when the list is dynamic, I don't know
> ahead of time how many options there will be, so I want the Select component
> to decide for me. If the field is required, I still want a blank option
> unless there is exactly one option because I don't want the first option to
> be selected as a default. I want the user to consciously choose a value.
> 
> On Thu, May 13, 2010 at 2:30 PM, Robert Zeigler  wrote:
> 
>> Why are you wanting to change the "auto" behavior in the first place?
>> In the few cases where there is no "sensible" default value, is using the
>> "blankLabel" and "blankOption" parameters so excruciatingly onerous? If so,
>> why not not simply wrap the select component in a custom select component
>> that provides the values you want? You would have to provide parameters in
>> your wrapper that passed through to the underlying select, but this is
>> certainly doable.
>> 
>> In fact, this particular case could be handled (I think?) in 5.2 in a very
>> clean way.  5.2 introduces the possibility for mixins to bind and manipulate
>> the containing component's parameters.  So you could, in theory, write a
>> mixin that sets the appropriate values for you.  Basically, you would have
>> something like this:
>> 
>> public class Blank {
>> 
>> @BindParameter
>> private boolean required;
>> 
>> @BindParameter
>> private BlankOption blankOption;
>> 
>> @BindParameter
>> private blankLabel blankLabel;
>> 
>> void beforeRender() {//this will happen before the select's before
>> render...
>> if (//whatever condition you want) {
>>   blankOption=ALWAYS;//we've now overridden the default check in
>> showBlankOption() b/c by the time that renders, showBlankOption will see
>> "blankOption" as being ALWAYS instead of AUTO.
>>   blankLabel="Select one...";
>> } else {
>>   blankOption=NEVER;
>> }
>> }
>> 
>> }
>> 
>> Which you could then use like:
>> 
>> 
>> 
>> which seems very non-onerous to me. :)
>> 
>> Robert
>> 
>> On May 13, 2010, at 5/1312:56 PM , Benny Law wrote:
>> 
>>> I did look at the demo Geoff posted. How is that going to provide what I
>>> need? I'm sorry, but I fail to see this "easy fix" you mentioned. Maybe
>> you
>>> can be a bit more specific?
>>> 
>>> 
>>> On Thu, May 13, 2010 at 1:15 PM, Christian Riedel
>>> wrote:
>>> 
 Well I agree that some more extensibility could be made here and there.
 That particular problem looks like it's worth a JIRA with a patch from
>> you
 that makes the component extensible to fix that problem :)
 
 On the other hand there is an easy fix. Just look at the demo Geoff
>> posted.
 Why do you insist on the BlankOption thing? Just add your blank option
 directly to the list select-options. Then there is no blank option at
>> all...
 
 
 Am 13.05.2010 um 16:43 schrieb Benny Law:
 
> Thanks Geoff, but no, it doesn't. Your example shows how the Select
> component works as is. What I need is a smarter interpretation of
> BlankOption.AUTO. Basically, if you look at the showBlankOption()
>> method
 in
> the Select class, you see this:
> 
>  switch (blankOption)
>  {
>  case ALWAYS:
>  return true;
> 
>  case NEVER:
>  return false;
> 
>  default:
>  return !isRequired();
>  }
> 
> What I want is this:
> 
>  switch (blankOption) {
> 
>  case ALWAYS:
>  return true;
> 
>  case NEVER:
>  return false;
> 
>  // AUTO: Decide based on model size, current value, and required
 or
> not.
>  defaul

Re: Best way to extend a component?

2010-05-13 Thread Benny Law
As I explained before, I want to change the "auto" behavior to make it
smarter. Currently, there is really no intelligence in the logic: a blank
option is added if the field is not required, and no blank option is added
if the field is required. When the option list is static, I can set the
blank option myself, no problem. But when the list is dynamic, I don't know
ahead of time how many options there will be, so I want the Select component
to decide for me. If the field is required, I still want a blank option
unless there is exactly one option because I don't want the first option to
be selected as a default. I want the user to consciously choose a value.

On Thu, May 13, 2010 at 2:30 PM, Robert Zeigler  wrote:

> Why are you wanting to change the "auto" behavior in the first place?
> In the few cases where there is no "sensible" default value, is using the
> "blankLabel" and "blankOption" parameters so excruciatingly onerous? If so,
> why not not simply wrap the select component in a custom select component
> that provides the values you want? You would have to provide parameters in
> your wrapper that passed through to the underlying select, but this is
> certainly doable.
>
> In fact, this particular case could be handled (I think?) in 5.2 in a very
> clean way.  5.2 introduces the possibility for mixins to bind and manipulate
> the containing component's parameters.  So you could, in theory, write a
> mixin that sets the appropriate values for you.  Basically, you would have
> something like this:
>
> public class Blank {
>
> @BindParameter
> private boolean required;
>
> @BindParameter
> private BlankOption blankOption;
>
> @BindParameter
> private blankLabel blankLabel;
>
> void beforeRender() {//this will happen before the select's before
> render...
>  if (//whatever condition you want) {
>blankOption=ALWAYS;//we've now overridden the default check in
> showBlankOption() b/c by the time that renders, showBlankOption will see
> "blankOption" as being ALWAYS instead of AUTO.
>blankLabel="Select one...";
>  } else {
>blankOption=NEVER;
>  }
> }
>
> }
>
> Which you could then use like:
>
> 
>
> which seems very non-onerous to me. :)
>
> Robert
>
> On May 13, 2010, at 5/1312:56 PM , Benny Law wrote:
>
> > I did look at the demo Geoff posted. How is that going to provide what I
> > need? I'm sorry, but I fail to see this "easy fix" you mentioned. Maybe
> you
> > can be a bit more specific?
> >
> >
> > On Thu, May 13, 2010 at 1:15 PM, Christian Riedel
> > wrote:
> >
> >> Well I agree that some more extensibility could be made here and there.
> >> That particular problem looks like it's worth a JIRA with a patch from
> you
> >> that makes the component extensible to fix that problem :)
> >>
> >> On the other hand there is an easy fix. Just look at the demo Geoff
> posted.
> >> Why do you insist on the BlankOption thing? Just add your blank option
> >> directly to the list select-options. Then there is no blank option at
> all...
> >>
> >>
> >> Am 13.05.2010 um 16:43 schrieb Benny Law:
> >>
> >>> Thanks Geoff, but no, it doesn't. Your example shows how the Select
> >>> component works as is. What I need is a smarter interpretation of
> >>> BlankOption.AUTO. Basically, if you look at the showBlankOption()
> method
> >> in
> >>> the Select class, you see this:
> >>>
> >>>   switch (blankOption)
> >>>   {
> >>>   case ALWAYS:
> >>>   return true;
> >>>
> >>>   case NEVER:
> >>>   return false;
> >>>
> >>>   default:
> >>>   return !isRequired();
> >>>   }
> >>>
> >>> What I want is this:
> >>>
> >>>   switch (blankOption) {
> >>>
> >>>   case ALWAYS:
> >>>   return true;
> >>>
> >>>   case NEVER:
> >>>   return false;
> >>>
> >>>   // AUTO: Decide based on model size, current value, and required
> >> or
> >>> not.
> >>>   default:
> >>>   List options = model.getOptions();
> >>>
> >>>   if (options.size() == 1) {
> >>>   return !isRequired();
> >>>   }
> >>>   if (options.size() == 0 || value == null) {
> >>>   return true;
> >>>   }
> >>>   if (value != null) {
> >>>   for (OptionModel option: options) {
> >>>   if (option.getValue().equals( value )) {
> >>>   return !isRequired();
> >>>   }
> >>>   }
> >>>   }
> >>>   return true;
> >>>   }
> >>>
> >>> I hope it's clear what I want to achieve with the enhanced logic for
> >> AUTO.
> >>>
> >>> Regards,
> >>>
> >>> Benny
> >>>
> >>> On Thu, May 13, 2010 at 10:29 AM, Geoff Callender <
> >>> geoff.callender.jumpst...@gmail.com> wrote:
> >>>
>  Does this help at all?
> 
> 
> 
> >>
> http://jumpstart.doublenegative.com.au/jumpstart/examples/select/varied/$N/$N/$N/$N
> 
>  Cheers,
> 
>  Geoff
> 
>  On 14/05/2010, at 12:11 AM, Benny Law w

Re: Best way to extend a component?

2010-05-13 Thread Thiago H. de Paula Figueiredo
On Thu, 13 May 2010 15:30:11 -0300, Robert Zeigler   
wrote:


In fact, this particular case could be handled (I think?) in 5.2 in a  
very clean way.


I was thinking in a mixin too, but in 5.1 and using DOM rewriting. A  
little more complicated, but still viable.


Or just bind the blankOption to a getter that would have the logic there.

--
Thiago H. de Paula Figueiredo
Independent Java, Apache Tapestry 5 and Hibernate consultant, developer,  
and instructor

Owner, Ars Machina Tecnologia da Informação Ltda.
http://www.arsmachina.com.br

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



Re: Best way to extend a component?

2010-05-13 Thread Robert Zeigler
Why are you wanting to change the "auto" behavior in the first place?
In the few cases where there is no "sensible" default value, is using the 
"blankLabel" and "blankOption" parameters so excruciatingly onerous? If so, why 
not not simply wrap the select component in a custom select component that 
provides the values you want? You would have to provide parameters in your 
wrapper that passed through to the underlying select, but this is certainly 
doable.

In fact, this particular case could be handled (I think?) in 5.2 in a very 
clean way.  5.2 introduces the possibility for mixins to bind and manipulate 
the containing component's parameters.  So you could, in theory, write a mixin 
that sets the appropriate values for you.  Basically, you would have something 
like this:

public class Blank {

@BindParameter
private boolean required;

@BindParameter
private BlankOption blankOption;

@BindParameter
private blankLabel blankLabel;

void beforeRender() {//this will happen before the select's before render...
  if (//whatever condition you want) {
blankOption=ALWAYS;//we've now overridden the default check in 
showBlankOption() b/c by the time that renders, showBlankOption will see 
"blankOption" as being ALWAYS instead of AUTO. 
blankLabel="Select one...";
  } else {
blankOption=NEVER;
  }
}

}

Which you could then use like:



which seems very non-onerous to me. :)

Robert

On May 13, 2010, at 5/1312:56 PM , Benny Law wrote:

> I did look at the demo Geoff posted. How is that going to provide what I
> need? I'm sorry, but I fail to see this "easy fix" you mentioned. Maybe you
> can be a bit more specific?
> 
> 
> On Thu, May 13, 2010 at 1:15 PM, Christian Riedel
> wrote:
> 
>> Well I agree that some more extensibility could be made here and there.
>> That particular problem looks like it's worth a JIRA with a patch from you
>> that makes the component extensible to fix that problem :)
>> 
>> On the other hand there is an easy fix. Just look at the demo Geoff posted.
>> Why do you insist on the BlankOption thing? Just add your blank option
>> directly to the list select-options. Then there is no blank option at all...
>> 
>> 
>> Am 13.05.2010 um 16:43 schrieb Benny Law:
>> 
>>> Thanks Geoff, but no, it doesn't. Your example shows how the Select
>>> component works as is. What I need is a smarter interpretation of
>>> BlankOption.AUTO. Basically, if you look at the showBlankOption() method
>> in
>>> the Select class, you see this:
>>> 
>>>   switch (blankOption)
>>>   {
>>>   case ALWAYS:
>>>   return true;
>>> 
>>>   case NEVER:
>>>   return false;
>>> 
>>>   default:
>>>   return !isRequired();
>>>   }
>>> 
>>> What I want is this:
>>> 
>>>   switch (blankOption) {
>>> 
>>>   case ALWAYS:
>>>   return true;
>>> 
>>>   case NEVER:
>>>   return false;
>>> 
>>>   // AUTO: Decide based on model size, current value, and required
>> or
>>> not.
>>>   default:
>>>   List options = model.getOptions();
>>> 
>>>   if (options.size() == 1) {
>>>   return !isRequired();
>>>   }
>>>   if (options.size() == 0 || value == null) {
>>>   return true;
>>>   }
>>>   if (value != null) {
>>>   for (OptionModel option: options) {
>>>   if (option.getValue().equals( value )) {
>>>   return !isRequired();
>>>   }
>>>   }
>>>   }
>>>   return true;
>>>   }
>>> 
>>> I hope it's clear what I want to achieve with the enhanced logic for
>> AUTO.
>>> 
>>> Regards,
>>> 
>>> Benny
>>> 
>>> On Thu, May 13, 2010 at 10:29 AM, Geoff Callender <
>>> geoff.callender.jumpst...@gmail.com> wrote:
>>> 
 Does this help at all?
 
 
 
>> http://jumpstart.doublenegative.com.au/jumpstart/examples/select/varied/$N/$N/$N/$N
 
 Cheers,
 
 Geoff
 
 On 14/05/2010, at 12:11 AM, Benny Law wrote:
 
> We are talking about subclassing a Tapestry component here. To give you
 an
> example, I wanted to subclass the Select component to override how
> BlankOption.AUTO is interpreted. I wanted the logic to not just look at
 the
> required property but also to consider how many options are available
>> and
> whether there is a current value. (I find the current logic lacking
 because,
> for example, the first option will always be selected as default if
 required
> is true, but there may not be a meaningful default for the field.) All
>> I
> needed to do was to override the showBlankOption() method, but I
>> couldn't
> because it's a private method. I ended up making a duplicate of the
 Select
> component with a modified showBlankOption() method. It just didn't feel
> right. I don't think all this talk about capturing common logic in a
>> base
> class or creating a s

Re: Best way to extend a component?

2010-05-13 Thread Benny Law
I did look at the demo Geoff posted. How is that going to provide what I
need? I'm sorry, but I fail to see this "easy fix" you mentioned. Maybe you
can be a bit more specific?


On Thu, May 13, 2010 at 1:15 PM, Christian Riedel
wrote:

> Well I agree that some more extensibility could be made here and there.
> That particular problem looks like it's worth a JIRA with a patch from you
> that makes the component extensible to fix that problem :)
>
> On the other hand there is an easy fix. Just look at the demo Geoff posted.
> Why do you insist on the BlankOption thing? Just add your blank option
> directly to the list select-options. Then there is no blank option at all...
>
>
> Am 13.05.2010 um 16:43 schrieb Benny Law:
>
> > Thanks Geoff, but no, it doesn't. Your example shows how the Select
> > component works as is. What I need is a smarter interpretation of
> > BlankOption.AUTO. Basically, if you look at the showBlankOption() method
> in
> > the Select class, you see this:
> >
> >switch (blankOption)
> >{
> >case ALWAYS:
> >return true;
> >
> >case NEVER:
> >return false;
> >
> >default:
> >return !isRequired();
> >}
> >
> > What I want is this:
> >
> >switch (blankOption) {
> >
> >case ALWAYS:
> >return true;
> >
> >case NEVER:
> >return false;
> >
> >// AUTO: Decide based on model size, current value, and required
> or
> > not.
> >default:
> >List options = model.getOptions();
> >
> >if (options.size() == 1) {
> >return !isRequired();
> >}
> >if (options.size() == 0 || value == null) {
> >return true;
> >}
> >if (value != null) {
> >for (OptionModel option: options) {
> >if (option.getValue().equals( value )) {
> >return !isRequired();
> >}
> >}
> >}
> >return true;
> >}
> >
> > I hope it's clear what I want to achieve with the enhanced logic for
> AUTO.
> >
> > Regards,
> >
> > Benny
> >
> > On Thu, May 13, 2010 at 10:29 AM, Geoff Callender <
> > geoff.callender.jumpst...@gmail.com> wrote:
> >
> >> Does this help at all?
> >>
> >>
> >>
> http://jumpstart.doublenegative.com.au/jumpstart/examples/select/varied/$N/$N/$N/$N
> >>
> >> Cheers,
> >>
> >> Geoff
> >>
> >> On 14/05/2010, at 12:11 AM, Benny Law wrote:
> >>
> >>> We are talking about subclassing a Tapestry component here. To give you
> >> an
> >>> example, I wanted to subclass the Select component to override how
> >>> BlankOption.AUTO is interpreted. I wanted the logic to not just look at
> >> the
> >>> required property but also to consider how many options are available
> and
> >>> whether there is a current value. (I find the current logic lacking
> >> because,
> >>> for example, the first option will always be selected as default if
> >> required
> >>> is true, but there may not be a meaningful default for the field.) All
> I
> >>> needed to do was to override the showBlankOption() method, but I
> couldn't
> >>> because it's a private method. I ended up making a duplicate of the
> >> Select
> >>> component with a modified showBlankOption() method. It just didn't feel
> >>> right. I don't think all this talk about capturing common logic in a
> base
> >>> class or creating a service for it applies here.
> >>>
> >>> In my opinion, a good framework should provide the option for extending
> >> its
> >>> components easily. I believe that with proper design and careful
> >>> consideration, inheritance can still be very useful. Developers should
> >>> understand any potential risks involved in subclassing, but closing the
> >> door
> >>> to subclassing for the sake of backward-compatibility may be an
> overkill
> >>> IMHO. Everything has pros and cons, and the developer is ultimately
> >>> responsible for weighing them and choosing what's best for their
> >> situation.
> >>>
> >>> BTW, if anyone can think of a clean way to solve my problem with the
> >> Select
> >>> component, please let me know. Thanks.
> >>>
> >>> Benny
> >>
> >>
>
>
> -
> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> For additional commands, e-mail: users-h...@tapestry.apache.org
>
>


Re: Best way to extend a component?

2010-05-13 Thread Christian Riedel
Well I agree that some more extensibility could be made here and there. That 
particular problem looks like it's worth a JIRA with a patch from you that 
makes the component extensible to fix that problem :)

On the other hand there is an easy fix. Just look at the demo Geoff posted. Why 
do you insist on the BlankOption thing? Just add your blank option directly to 
the list select-options. Then there is no blank option at all... 


Am 13.05.2010 um 16:43 schrieb Benny Law:

> Thanks Geoff, but no, it doesn't. Your example shows how the Select
> component works as is. What I need is a smarter interpretation of
> BlankOption.AUTO. Basically, if you look at the showBlankOption() method in
> the Select class, you see this:
> 
>switch (blankOption)
>{
>case ALWAYS:
>return true;
> 
>case NEVER:
>return false;
> 
>default:
>return !isRequired();
>}
> 
> What I want is this:
> 
>switch (blankOption) {
> 
>case ALWAYS:
>return true;
> 
>case NEVER:
>return false;
> 
>// AUTO: Decide based on model size, current value, and required or
> not.
>default:
>List options = model.getOptions();
> 
>if (options.size() == 1) {
>return !isRequired();
>}
>if (options.size() == 0 || value == null) {
>return true;
>}
>if (value != null) {
>for (OptionModel option: options) {
>if (option.getValue().equals( value )) {
>return !isRequired();
>}
>}
>}
>return true;
>}
> 
> I hope it's clear what I want to achieve with the enhanced logic for AUTO.
> 
> Regards,
> 
> Benny
> 
> On Thu, May 13, 2010 at 10:29 AM, Geoff Callender <
> geoff.callender.jumpst...@gmail.com> wrote:
> 
>> Does this help at all?
>> 
>> 
>> http://jumpstart.doublenegative.com.au/jumpstart/examples/select/varied/$N/$N/$N/$N
>> 
>> Cheers,
>> 
>> Geoff
>> 
>> On 14/05/2010, at 12:11 AM, Benny Law wrote:
>> 
>>> We are talking about subclassing a Tapestry component here. To give you
>> an
>>> example, I wanted to subclass the Select component to override how
>>> BlankOption.AUTO is interpreted. I wanted the logic to not just look at
>> the
>>> required property but also to consider how many options are available and
>>> whether there is a current value. (I find the current logic lacking
>> because,
>>> for example, the first option will always be selected as default if
>> required
>>> is true, but there may not be a meaningful default for the field.) All I
>>> needed to do was to override the showBlankOption() method, but I couldn't
>>> because it's a private method. I ended up making a duplicate of the
>> Select
>>> component with a modified showBlankOption() method. It just didn't feel
>>> right. I don't think all this talk about capturing common logic in a base
>>> class or creating a service for it applies here.
>>> 
>>> In my opinion, a good framework should provide the option for extending
>> its
>>> components easily. I believe that with proper design and careful
>>> consideration, inheritance can still be very useful. Developers should
>>> understand any potential risks involved in subclassing, but closing the
>> door
>>> to subclassing for the sake of backward-compatibility may be an overkill
>>> IMHO. Everything has pros and cons, and the developer is ultimately
>>> responsible for weighing them and choosing what's best for their
>> situation.
>>> 
>>> BTW, if anyone can think of a clean way to solve my problem with the
>> Select
>>> component, please let me know. Thanks.
>>> 
>>> Benny
>> 
>> 


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



Re: Best way to extend a component?

2010-05-13 Thread Benny Law
Thanks Geoff, but no, it doesn't. Your example shows how the Select
component works as is. What I need is a smarter interpretation of
BlankOption.AUTO. Basically, if you look at the showBlankOption() method in
the Select class, you see this:

switch (blankOption)
{
case ALWAYS:
return true;

case NEVER:
return false;

default:
return !isRequired();
}

What I want is this:

switch (blankOption) {

case ALWAYS:
return true;

case NEVER:
return false;

// AUTO: Decide based on model size, current value, and required or
not.
default:
List options = model.getOptions();

if (options.size() == 1) {
return !isRequired();
}
if (options.size() == 0 || value == null) {
return true;
}
if (value != null) {
for (OptionModel option: options) {
if (option.getValue().equals( value )) {
return !isRequired();
}
}
}
return true;
}

I hope it's clear what I want to achieve with the enhanced logic for AUTO.

Regards,

Benny

On Thu, May 13, 2010 at 10:29 AM, Geoff Callender <
geoff.callender.jumpst...@gmail.com> wrote:

> Does this help at all?
>
>
> http://jumpstart.doublenegative.com.au/jumpstart/examples/select/varied/$N/$N/$N/$N
>
> Cheers,
>
> Geoff
>
> On 14/05/2010, at 12:11 AM, Benny Law wrote:
>
> > We are talking about subclassing a Tapestry component here. To give you
> an
> > example, I wanted to subclass the Select component to override how
> > BlankOption.AUTO is interpreted. I wanted the logic to not just look at
> the
> > required property but also to consider how many options are available and
> > whether there is a current value. (I find the current logic lacking
> because,
> > for example, the first option will always be selected as default if
> required
> > is true, but there may not be a meaningful default for the field.) All I
> > needed to do was to override the showBlankOption() method, but I couldn't
> > because it's a private method. I ended up making a duplicate of the
> Select
> > component with a modified showBlankOption() method. It just didn't feel
> > right. I don't think all this talk about capturing common logic in a base
> > class or creating a service for it applies here.
> >
> > In my opinion, a good framework should provide the option for extending
> its
> > components easily. I believe that with proper design and careful
> > consideration, inheritance can still be very useful. Developers should
> > understand any potential risks involved in subclassing, but closing the
> door
> > to subclassing for the sake of backward-compatibility may be an overkill
> > IMHO. Everything has pros and cons, and the developer is ultimately
> > responsible for weighing them and choosing what's best for their
> situation.
> >
> > BTW, if anyone can think of a clean way to solve my problem with the
> Select
> > component, please let me know. Thanks.
> >
> > Benny
>
>


Re: Best way to extend a component?

2010-05-13 Thread Geoff Callender
Does this help at all?


http://jumpstart.doublenegative.com.au/jumpstart/examples/select/varied/$N/$N/$N/$N

Cheers,

Geoff

On 14/05/2010, at 12:11 AM, Benny Law wrote:

> We are talking about subclassing a Tapestry component here. To give you an
> example, I wanted to subclass the Select component to override how
> BlankOption.AUTO is interpreted. I wanted the logic to not just look at the
> required property but also to consider how many options are available and
> whether there is a current value. (I find the current logic lacking because,
> for example, the first option will always be selected as default if required
> is true, but there may not be a meaningful default for the field.) All I
> needed to do was to override the showBlankOption() method, but I couldn't
> because it's a private method. I ended up making a duplicate of the Select
> component with a modified showBlankOption() method. It just didn't feel
> right. I don't think all this talk about capturing common logic in a base
> class or creating a service for it applies here.
> 
> In my opinion, a good framework should provide the option for extending its
> components easily. I believe that with proper design and careful
> consideration, inheritance can still be very useful. Developers should
> understand any potential risks involved in subclassing, but closing the door
> to subclassing for the sake of backward-compatibility may be an overkill
> IMHO. Everything has pros and cons, and the developer is ultimately
> responsible for weighing them and choosing what's best for their situation.
> 
> BTW, if anyone can think of a clean way to solve my problem with the Select
> component, please let me know. Thanks.
> 
> Benny
> 
> 
> On Thu, May 13, 2010 at 8:58 AM, Christian Riedel
> wrote:
> 
>> Why should you have the same rendering code in two different components?
>> When I have common code for several components I create an abstract base
>> component and put it into the base package. The template is not mandatory
>> for components or abstract base components/pages btw. You can use
>> subclassing whenever you want but that doesn't always makes your code
>> better.
>> 
>> If you have common logic in different components you should move it into a
>> service...
>> 
>> Well, and I think tapestry can't free you from your dirtyness, you should
>> try soap :)
>> 
>> 
>> Am 13.05.2010 um 14:28 schrieb Benny Law:
>> 
>>> I also wish component subclassing was at least an option. What I don't
>> like
>>> about copying and pasting from a Tapestry component is that I end up
>> relying
>>> on some internal packages and classes. That makes me feel dirty.
>>> 
>>> Benny
>>> 
>>> 
>>> On Thu, May 13, 2010 at 7:47 AM, Andreas Bohnert 
>> wrote:
>>> 
 I agree.
 I'm upgrading a big project from tapestry 3 to 5.
 As I looked into the documentation and sources of tapestry 5 I thought:
 wow, this is really great. it could not be any better!
 
 But if components are no meant to be subclassed this seems like a
>> drawback
 for me. You have to copy and adjust the code which does not fit into the
 tapestry world (DRY principle)
 If you use embedded components to extend a component you need an
>> additional
 (more or less useless) template file and you come in trouble if you use
>> this
 component multiple times in a page (because of the embedded components
>> id
 binding)
 
 Anyway, even if there is way to get around these problems with embedded
 components I described, it would feel more natural for me if I just
>> could
 subclass a component.
 
 Andreas
 
 
 
 I ended up copying
 
 
>> 
>> -
>> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
>> For additional commands, e-mail: users-h...@tapestry.apache.org
>> 
>> 


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



Re: Best way to extend a component?

2010-05-13 Thread Benny Law
We are talking about subclassing a Tapestry component here. To give you an
example, I wanted to subclass the Select component to override how
BlankOption.AUTO is interpreted. I wanted the logic to not just look at the
required property but also to consider how many options are available and
whether there is a current value. (I find the current logic lacking because,
for example, the first option will always be selected as default if required
is true, but there may not be a meaningful default for the field.) All I
needed to do was to override the showBlankOption() method, but I couldn't
because it's a private method. I ended up making a duplicate of the Select
component with a modified showBlankOption() method. It just didn't feel
right. I don't think all this talk about capturing common logic in a base
class or creating a service for it applies here.

In my opinion, a good framework should provide the option for extending its
components easily. I believe that with proper design and careful
consideration, inheritance can still be very useful. Developers should
understand any potential risks involved in subclassing, but closing the door
to subclassing for the sake of backward-compatibility may be an overkill
IMHO. Everything has pros and cons, and the developer is ultimately
responsible for weighing them and choosing what's best for their situation.

BTW, if anyone can think of a clean way to solve my problem with the Select
component, please let me know. Thanks.

Benny


On Thu, May 13, 2010 at 8:58 AM, Christian Riedel
wrote:

> Why should you have the same rendering code in two different components?
> When I have common code for several components I create an abstract base
> component and put it into the base package. The template is not mandatory
> for components or abstract base components/pages btw. You can use
> subclassing whenever you want but that doesn't always makes your code
> better.
>
> If you have common logic in different components you should move it into a
> service...
>
> Well, and I think tapestry can't free you from your dirtyness, you should
> try soap :)
>
>
> Am 13.05.2010 um 14:28 schrieb Benny Law:
>
> > I also wish component subclassing was at least an option. What I don't
> like
> > about copying and pasting from a Tapestry component is that I end up
> relying
> > on some internal packages and classes. That makes me feel dirty.
> >
> > Benny
> >
> >
> > On Thu, May 13, 2010 at 7:47 AM, Andreas Bohnert 
> wrote:
> >
> >> I agree.
> >> I'm upgrading a big project from tapestry 3 to 5.
> >> As I looked into the documentation and sources of tapestry 5 I thought:
> >> wow, this is really great. it could not be any better!
> >>
> >> But if components are no meant to be subclassed this seems like a
> drawback
> >> for me. You have to copy and adjust the code which does not fit into the
> >> tapestry world (DRY principle)
> >> If you use embedded components to extend a component you need an
> additional
> >> (more or less useless) template file and you come in trouble if you use
> this
> >> component multiple times in a page (because of the embedded components
> id
> >> binding)
> >>
> >> Anyway, even if there is way to get around these problems with embedded
> >> components I described, it would feel more natural for me if I just
> could
> >> subclass a component.
> >>
> >> Andreas
> >>
> >>
> >>
> >> I ended up copying
> >>
> >>
>
> -
> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> For additional commands, e-mail: users-h...@tapestry.apache.org
>
>


Re: Best way to extend a component?

2010-05-13 Thread Andreas Bohnert


By the way, why that ? 


Compatibility. The more open to subclassing a component is, the harder 
it is to keep it backward-compatible.



Well, that's a good point. It's always about keeping the balance ...

Exactly. I was saying that components provided by Tapestry aren't 
meant to

be subclassed, but the ones you write can be. Tapestry's components use
subclassing too: AbstractField, AbstractTextField, etc. Maybe Tapestry
should have some more of them, just like an AbstractSelect.


That would nice!


If you have common logic in different components you should move it 
into a service... 


Of course! But I'm talking about common component logic like tapestry 
already provides like Select or Grid.

No application releated logic or components which are entirely new.
I have created an AbstractSelect which is the baseclass of many of my 
Subclasses now, but this (my) AbstractSelect is unnecessary and repeats 
just the code of Select with some minor changes.


Andreas



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



Re: Best way to extend a component?

2010-05-13 Thread Thiago H. de Paula Figueiredo
On Thu, 13 May 2010 06:35:44 -0300, Nicolas Bouillon   
wrote:



By the way, why that ?


Compatibility. The more open to subclassing a component is, the harder it  
is to keep it backward-compatible.


It's one thing I felt difficult, for example to change the way the  
GridPager is displayed (to display the number of pages, number of  
items), we had to do a big copy paste of the Grid component and the  
related components, instead of subclassing it.


In these cases, what about filing a JIRA about it?

--
Thiago H. de Paula Figueiredo
Independent Java, Apache Tapestry 5 and Hibernate consultant, developer,  
and instructor

Owner, Ars Machina Tecnologia da Informação Ltda.
http://www.arsmachina.com.br

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



Re: Best way to extend a component?

2010-05-13 Thread Thiago H. de Paula Figueiredo

On Thu, 13 May 2010 09:58:15 -0300, Christian Riedel
 wrote:


Why should you have the same rendering code in two different components?
When I have common code for several components I create an abstract base  
component and put it into the base package. The template is not  
mandatory for components or abstract base components/pages btw. You can  
use subclassing whenever you want but that doesn't always makes your  
code better.


Exactly. I was saying that components provided by Tapestry aren't meant to
be subclassed, but the ones you write can be. Tapestry's components use
subclassing too: AbstractField, AbstractTextField, etc. Maybe Tapestry
should have some more of them, just like an AbstractSelect.

If you have common logic in different components you should move it into  
a service...


Nice advice. :)

Well, and I think tapestry can't free you from your dirtyness, you  
should try soap :)


No, thank you. :P

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

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



Re: Best way to extend a component?

2010-05-13 Thread Christian Riedel
Why should you have the same rendering code in two different components?
When I have common code for several components I create an abstract base 
component and put it into the base package. The template is not mandatory for 
components or abstract base components/pages btw. You can use subclassing 
whenever you want but that doesn't always makes your code better. 

If you have common logic in different components you should move it into a 
service...

Well, and I think tapestry can't free you from your dirtyness, you should try 
soap :)


Am 13.05.2010 um 14:28 schrieb Benny Law:

> I also wish component subclassing was at least an option. What I don't like
> about copying and pasting from a Tapestry component is that I end up relying
> on some internal packages and classes. That makes me feel dirty.
> 
> Benny
> 
> 
> On Thu, May 13, 2010 at 7:47 AM, Andreas Bohnert  wrote:
> 
>> I agree.
>> I'm upgrading a big project from tapestry 3 to 5.
>> As I looked into the documentation and sources of tapestry 5 I thought:
>> wow, this is really great. it could not be any better!
>> 
>> But if components are no meant to be subclassed this seems like a drawback
>> for me. You have to copy and adjust the code which does not fit into the
>> tapestry world (DRY principle)
>> If you use embedded components to extend a component you need an additional
>> (more or less useless) template file and you come in trouble if you use this
>> component multiple times in a page (because of the embedded components id
>> binding)
>> 
>> Anyway, even if there is way to get around these problems with embedded
>> components I described, it would feel more natural for me if I just could
>> subclass a component.
>> 
>> Andreas
>> 
>> 
>> 
>> I ended up copying
>> 
>> 
>> Nicolas Bouillon wrote:
>> 
>>> Le 11/05/2010 21:34, Thiago H. de Paula Figueiredo a écrit :
>>> 
 1.) Extend MySelect from Select
> I found no way to assign my model to the selects privat model. There is
> a setModel in Select but it seems to be there only for unit tests.
> 
 
 Tapestry components weren't meant to be subclassed.
 
>>> By the way, why that ?
>>> 
>>> It's one thing I felt difficult, for example to change the way the
>>> GridPager is displayed (to display the number of pages, number of items), we
>>> had to do a big copy paste of the Grid component and the related components,
>>> instead of subclassing it.
>>> 
>>> 
>>> -
>>> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
>>> For additional commands, e-mail: users-h...@tapestry.apache.org
>>> 
>> 
>> 
>> -
>> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
>> For additional commands, e-mail: users-h...@tapestry.apache.org
>> 
>> 


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



Re: Best way to extend a component?

2010-05-13 Thread Benny Law
I also wish component subclassing was at least an option. What I don't like
about copying and pasting from a Tapestry component is that I end up relying
on some internal packages and classes. That makes me feel dirty.

Benny


On Thu, May 13, 2010 at 7:47 AM, Andreas Bohnert  wrote:

> I agree.
> I'm upgrading a big project from tapestry 3 to 5.
> As I looked into the documentation and sources of tapestry 5 I thought:
> wow, this is really great. it could not be any better!
>
> But if components are no meant to be subclassed this seems like a drawback
> for me. You have to copy and adjust the code which does not fit into the
> tapestry world (DRY principle)
> If you use embedded components to extend a component you need an additional
> (more or less useless) template file and you come in trouble if you use this
> component multiple times in a page (because of the embedded components id
> binding)
>
> Anyway, even if there is way to get around these problems with embedded
> components I described, it would feel more natural for me if I just could
> subclass a component.
>
> Andreas
>
>
>
> I ended up copying
>
>
> Nicolas Bouillon wrote:
>
>> Le 11/05/2010 21:34, Thiago H. de Paula Figueiredo a écrit :
>>
>>> 1.) Extend MySelect from Select
 I found no way to assign my model to the selects privat model. There is
 a setModel in Select but it seems to be there only for unit tests.

>>>
>>> Tapestry components weren't meant to be subclassed.
>>>
>> By the way, why that ?
>>
>> It's one thing I felt difficult, for example to change the way the
>> GridPager is displayed (to display the number of pages, number of items), we
>> had to do a big copy paste of the Grid component and the related components,
>> instead of subclassing it.
>>
>>
>> -
>> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
>> For additional commands, e-mail: users-h...@tapestry.apache.org
>>
>
>
> -
> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> For additional commands, e-mail: users-h...@tapestry.apache.org
>
>


Re: Best way to extend a component?

2010-05-13 Thread Andreas Bohnert

I agree.
I'm upgrading a big project from tapestry 3 to 5.
As I looked into the documentation and sources of tapestry 5 I thought: 
wow, this is really great. it could not be any better!


But if components are no meant to be subclassed this seems like a 
drawback for me. You have to copy and adjust the code which does not fit 
into the tapestry world (DRY principle)
If you use embedded components to extend a component you need an 
additional (more or less useless) template file and you come in trouble 
if you use this component multiple times in a page (because of the 
embedded components id binding)


Anyway, even if there is way to get around these problems with embedded 
components I described, it would feel more natural for me if I just 
could subclass a component.


Andreas





I ended up copying

Nicolas Bouillon wrote:

Le 11/05/2010 21:34, Thiago H. de Paula Figueiredo a écrit :

1.) Extend MySelect from Select
I found no way to assign my model to the selects privat model. There 
is a setModel in Select but it seems to be there only for unit tests. 


Tapestry components weren't meant to be subclassed. 

By the way, why that ?

It's one thing I felt difficult, for example to change the way the 
GridPager is displayed (to display the number of pages, number of 
items), we had to do a big copy paste of the Grid component and the 
related components, instead of subclassing it.



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



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



Re: Best way to extend a component?

2010-05-13 Thread Nicolas Bouillon

Le 11/05/2010 21:34, Thiago H. de Paula Figueiredo a écrit :

1.) Extend MySelect from Select
I found no way to assign my model to the selects privat model. There 
is a setModel in Select but it seems to be there only for unit tests.


Tapestry components weren't meant to be subclassed.

By the way, why that ?

It's one thing I felt difficult, for example to change the way the 
GridPager is displayed (to display the number of pages, number of 
items), we had to do a big copy paste of the Grid component and the 
related components, instead of subclassing it.



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



Re: Best way to extend a component?

2010-05-11 Thread Andreas Bohnert

ah, ok.

thanks!

Thiago H. de Paula Figueiredo wrote:
On Tue, 11 May 2010 17:47:46 -0300, Andreas Bohnert 
 wrote:



Thank you for that clarification!
But what am I supposed to put in that template, if I bound all the 
parameters already in the java class? 


Just the t:id.

 



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



Re: Best way to extend a component?

2010-05-11 Thread Thiago H. de Paula Figueiredo
On Tue, 11 May 2010 17:47:46 -0300, Andreas Bohnert   
wrote:



Thank you for that clarification!
But what am I supposed to put in that template, if I bound all the  
parameters already in the java class?


Just the t:id.



--
Thiago H. de Paula Figueiredo
Independent Java, Apache Tapestry 5 and Hibernate consultant, developer,  
and instructor

Owner, Ars Machina Tecnologia da Informação Ltda.
http://www.arsmachina.com.br

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



Re: Best way to extend a component?

2010-05-11 Thread Andreas Bohnert

Thank you for that clarification!
But what am I supposed to put in that template, if I bound all the 
parameters already in the java class?


java:
 @Component(parameters= { "model=myModel", "value=myValue" })
 private Select select;

and again(?) in the template:

On Tue, 11 May 2010 16:01:56 -0300, Andreas Bohnert 
 wrote:


Hi, 


Hi!


1.) Extend MySelect from Select
I found no way to assign my model to the selects privat model. There 
is a setModel in Select but it seems to be there only for unit tests. 


Tapestry components weren't meant to be subclassed.


2.) Embed Select in MySelect
It seems that I have to provide a template for this approach (I'm 
getting this error described at 
http://tapestry.apache.org/tapestry5/guide/component-classes.html).
I don't want to provide a template. I just want to pass my model to 
the component, which I did as described:


 @Component(parameters= { "model=myModel", "value=myValue" })
 private Select select;

Is there a way to do this without a template? 


No.

Is there a better way to do this at all? 


You could also create your own component extending AbstractField and 
taking some inspiration from the Select source. 



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



Re: Best way to extend a component?

2010-05-11 Thread Thiago H. de Paula Figueiredo
On Tue, 11 May 2010 16:01:56 -0300, Andreas Bohnert   
wrote:



Hi,


Hi!


1.) Extend MySelect from Select
I found no way to assign my model to the selects privat model. There is  
a setModel in Select but it seems to be there only for unit tests.


Tapestry components weren't meant to be subclassed.


2.) Embed Select in MySelect
It seems that I have to provide a template for this approach (I'm  
getting this error described at  
http://tapestry.apache.org/tapestry5/guide/component-classes.html).
I don't want to provide a template. I just want to pass my model to the  
component, which I did as described:


 @Component(parameters= { "model=myModel", "value=myValue" })
 private Select select;

Is there a way to do this without a template?


No.


Is there a better way to do this at all?


You could also create your own component extending AbstractField and  
taking some inspiration from the Select source.


--
Thiago H. de Paula Figueiredo
Independent Java, Apache Tapestry 5 and Hibernate consultant, developer,  
and instructor

Owner, Ars Machina Tecnologia da Informação Ltda.
http://www.arsmachina.com.br

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



Best way to extend a component?

2010-05-11 Thread Andreas Bohnert

Hi,

I want to write my own 'select' component with a build-in model and 
additional parameters.

I tried different ways to achieve this, but none of them worked out for me.

Basically I tried:

---

1.) Extend MySelect from Select
I found no way to assign my model to the selects privat model. There is 
a setModel in Select but it seems to be there only for unit tests.



2.) Embed Select in MySelect
It seems that I have to provide a template for this approach (I'm 
getting this error described at 
http://tapestry.apache.org/tapestry5/guide/component-classes.html).
I don't want to provide a template. I just want to pass my model to the 
component, which I did as described:


@Component(parameters= { "model=myModel", "value=myValue" })
private Select select;

Is there a way to do this without a template?

---

Is there a better way to do this at all?

Any help is very much appreciated,
Andreas



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