Tim Larson wrote:
On Sun, Nov 07, 2004 at 09:29:56PM +0100, Sylvain Wallez wrote:
Tim Larson wrote:
Preliminary notice: don't get me wrong with all these questions and remarks. I'm shaking the concept so that it solidifies and we all agree on how it should behave before starting to write down some code.On Fri, Nov 05, 2004 at 09:58:43PM +0100, Sylvain Wallez wrote:
Ok. Does this mean choose/when will replace union/case? Also, the wiki [1] shows several alternatives for choose/when, and unless I missed something we have not decided which approach to use.Yes, choose/when is intended to replace union/case (following
with any deprecation pattern that is needed). There are two
alternatives, with the intention to have *both*, to service
different usecases.
Thanks for providing feedback :)
So, why do we need *both* versions? Isn't it FS? Can you give some examples that justify this need? Up to now, I personally never had the need for evaluated conditions. I sometimes would like to use types other than String, and that can easily be done by associating adding a convertor that defines how values for the different cases are to be converted to typed values.
Your converter idea for handling other datatypes sounds good.
I personally only need the simple switch version that references
a widget (via a path passed to lookupWidget()) for the switch
value and selects the case which has the id matching the value.
Others requested the expression-on-every-case version, so they
would have to supply usecases for that version.
Good. So people, if you need expression on every case, please speak up!
Also, if that need is because the case values are computed and not only a single widget's values, that can be modelled by a <fd:output> widget. And the initialize() stuff Tim added will allow to finish the on-create event handler I started to implement, thus allowing computed widgets to register themselves as change-listeners on widgets their value depends on.
Furthermore, what expression language will be used? This leads us back to the discussion about expressions in JXTG, and the necessary unification of expression evaluation within Cocoon as a whole. I'm also not a fan of xReporter's expression language which is really specific to CForms.
I got stuck on this point also. Perhaps someone with a usecase
for the e-o-e-case version could comment?
:-)
Also, there are some points I'd like us to to formalize.
1/ The wiki uses "choice" and "case" for the definition and "choose" and "when" for the template. IMO, this is confusing and we should have the same wording in the definition and in the template.
I would use the same names in template, model, and binding.
"choose/when" seemed to me to be the closest to consensus.
Anyone have a different opinion?
"choose" is a verb whereas "widget", "repeater", "field" are nouns. Using a noun therefore seems more consistent to me and that would be therefore "choice". But I've been also thinking lately about "select" or "variant". Naming is a difficult but important subject, as it conveys the underlying semantics.
1/ Is it a container? Looking at the wiki, the "valued expression selects case" version has no id. Also, are each fd:case also containers? My opinion is that fd:when should be a container, but not fd:case. This is enforced by the reuse of widgets between cases.
Choose and when would both be *implemented* as containers, but
they would not affect the paths/namespaces of the widgets they
"contain". Think of it as a control structure rather than as
a real container "widget". Also the id on the "choose" should
be optional.
IMO, the choice widget is "something", i.e. a structural unit like other widgets, whereas the various alternatives are more variants of what's in that thing. That means that choice would have an id and therefore affect the path, but not the cases which define what widgets are children of the choice depending on the case value.
Consider the following example (datatypes ommited for brevety) where we define the connection setting to a datasource (for example a CVS server):
<fd:choice id="datasource" case="datasource-type"> <fd:widgets> <fd:field id="server"/> <fd:field id="path"/> <fd:field id="login"/> <fd:field id="password"/> <fd:widgets> <fd:when case="local"> <fd:widget ref="path"/> </fd:when> <fd:when case="remote"> <fd:widget ref="server"/> <fd:widget ref="path"/> <fd:widget ref="login"/> <fd:widget ref="password"/> </fd:when> <fd:choice>
The "datasource" is an entity and threfore should appear in the path, whereas "local" and "remote" are just test values. So we have "datasource/path" (always) and "datasource/login", "datasource/server" etc (when case is "remote").
For example, this would allow the model to choose between two widgets with the same id but with different datatypes without having to modify the corresponding template to recognize that a choice is even being made. In this example there is no need for "choose" to have an id, because the choice does not need to be referenced.
Sorry, but I find having the same id for different widgets depending on the choice condition very confusing. IMO, an id should designate one thing only, without ambiguity.
The choice condition should define _which_ widgets (and therefore ids) are available, not _how_ these widgets are defined. Also, it's very likely that a choice in the definition also leads to a choice in the view and in the binding.
For a "choose" that picks between different
sets of widgets, or whenever you want the template or binding
to be able to react to the selected choice, then the "choose"
control structure will need an id.
And if it's got an id, it's no more a control structure, but a widget, hence the naming with a noun rather than a verb as outlined above.
2/ Widgets for a case: do we allow inline widgets to be defined in a fd:case, or only have references with fd:ref? Allowing both may cause some naming problems (this is also related to the previous question about containment), as an inline widget's name may conflict with a widget defined in fd:when. Similarily, if fd:case is not a container, widgets having the same name in different fd:cases will conflict.
Allow widget definitions in the "choose" for cherry-picking
in the "when"'s (refered to as fd:case's above,) and also
allow widget definitions in the "when"'s. This allows for
the type of example I described above.
... which I found confusing :-)
IMO, inline widget definitions in the "when" can be considered as shortcuts for defining a widget in the choice and then referencing it when that widget only applies to one particular case, i.e. :
<fd:choice id="foo"> <fd:when case="bar"> <fd:field id="baz"/> </fd:when> </fd:choice>
Should be strictly equivalent to writing :
<fd:choice id="foo"> <fd:widgets> <fd:field id="baz"/> </fd:widgets> <fd:when case="bar"> <fd:widget ref="baz"/> </fd:when> </fd:choice>
That also means that child ids must be unique throughout the various cases.
WDYT?
Sylvain
-- Sylvain Wallez Anyware Technologies http://www.apache.org/~sylvain http://www.anyware-tech.com { XML, Java, Cocoon, OpenSource }*{ Training, Consulting, Projects }
