Moving fields with plone.directives.form

68 views
Skip to first unread message

Thomas Buchberger

unread,
Dec 7, 2009, 7:34:44 PM12/7/09
to Dexterity development
Hi.

In my opinion the ordering of fields and changing fieldsets with
plone.directives.form should be more flexible.

As an example, let's assume we have a type with the schema IMyType and
the behavior IRelatedItems. Now I would like to move the
'relatedItems' field into another fieldset. I would do that by
defining a form.fieldset directive on IMyType because I only want to
change the fieldset for my type and not for every type having the
IRelatedItems behavior. However this doesn't work because
plone.autoform only changes fieldsets for fields that are defined in
the same schema as the directive.

Another problem arises when I want to move the 'relatedItems' field
before some field in IMyType.
The directive (on IMyType) would be something like form.order_before
(IRelatedItems.relatedItems='someField') but thats not possible
because 'IRelatedItems.relatedItems' is not an allowed keyword in
python.
However I can do it by directly setting IMyType.setTaggedValue
(ORDER_KEY, [('IRelatedItems.relatedItems', 'before', 'someField')])

What do you think?

--
Thomas

Martin Aspeli

unread,
Dec 7, 2009, 7:50:02 PM12/7/09
to dexterity-development
2009/12/8 Thomas Buchberger <thomas.b...@gmail.com>:
> Hi.
>
> In my opinion the ordering of fields and changing fieldsets with
> plone.directives.form should be more flexible.
>
> As an example, let's assume we have a type with the schema IMyType and
> the behavior IRelatedItems. Now I would like to move the
> 'relatedItems' field into another fieldset. I would do that by
> defining a form.fieldset directive on IMyType because I only want to
> change the fieldset for my type and not for every type having the
> IRelatedItems behavior. However this doesn't work because
> plone.autoform only changes fieldsets for fields that are defined in
> the same schema as the directive.

That seems like a reasonable thing to fix, but only for fieldsets (see below)

> Another problem arises when I want to move the 'relatedItems' field
> before some field in IMyType.
> The directive (on IMyType) would be something like form.order_before
> (IRelatedItems.relatedItems='someField') but thats not possible
> because 'IRelatedItems.relatedItems' is not an allowed keyword in
> python.
> However I can do it by directly setting IMyType.setTaggedValue
> (ORDER_KEY, [('IRelatedItems.relatedItems', 'before', 'someField')])

I wouldn't recommend it, but you could probably do this:

form.order_before(**{'IRelatedItems.relatedItems': 'someField})

> What do you think?

For this use case, I'd probably suggest you use a custom form (see
below). You can always do the reverse - put your field after
IRelatedItems.relatedItems, instead of moving it before yours.

In general, I think both the syntax and implications of moving things
from *other* schemata (so, IFoo has directives that affect fields in
IBar) are a bit dangerous. It's far too easy then to come up with
scenarios where it's hard to understand what's going on. I think
declaring fieldsets may be an exception, in that you typically
enumerate all the fields in a fieldset anyway, so overriding that with
a more-specific interface is fine. But for the other directives, I'm
not sure we should allow hints that apply to something not in the
interface.

To illustrate this, the syntax I would've liked would be something like:

class IFoo(form.Schema):

@form.order_before('IRelatedItems.relatedItems')
usefulItems = RelationList(title=u"Useful items")

(Of course, this isn't valid Python, and I couldn't find an emulation
that would work any better.)

That is, the way you now have to specify the field name in a kwarg is
an annoyance. I think the hints belong next to the fields they apply
to.

More broadly, I am quite worried that the plone.autoform "process
schema hints" algorithm is becoming by some distance the most
complicated part of Dexterity. I have a nagging feeling that we should
re-thinking this to make it easier to maintain and understand.
However, I don't have any great ideas about what "simpler" would look
like. I think the feature set we have now is important, and I wouldn't
want to lose it. On the other hand, we need to make sure the results
of various types of hints are predictable and easily documentable.

There is always the "fallback" option: create your own form and
manipulate the fields manually by overriding updateFields(). For the
more complex use cases, that's always going to be the way to go, and
it's not that hard. I just want to be able to cover the 80% use cases
with plone.autoform, not at least because that is all we can hope to
allow people to do TTW (the form:* attributes in plone.supermodel are
the same as the form.* directives from plone.directives.form).

Martin

Thomas Buchberger

unread,
Dec 8, 2009, 4:54:43 AM12/8/09
to Dexterity development
On 8 Dez., 01:50, Martin Aspeli <optil...@gmail.com> wrote:

> > As an example, let's assume we have a type with the schema IMyType and
> > the behavior IRelatedItems. Now I would like to move the
> > 'relatedItems' field into another fieldset. I would do that by
> > defining a form.fieldset directive on IMyType because I only want to
> > change the fieldset for my type and not for every type having the
> > IRelatedItems behavior. However this doesn't work because
> > plone.autoform only changes fieldsets for fields that are defined in
> > the same schema as the directive.
>
> That seems like a reasonable thing to fix, but only for fieldsets (see below)

I'd really appreciate it, if that could be fixed.
I could try to do this, but as you already said, the algorithm for
processing the schema hints in plone.autoform is quite complex.
Currently the primary schema is processed first.
I think it would be necessary to first process additional schemas and
then process the primary schema at last to make sure fieldset
directives on a types schema win over fieldset directives from
behavior schemas.

> > Another problem arises when I want to move the 'relatedItems' field
> > before some field in IMyType.
> > The directive (on IMyType) would be something like form.order_before
> > (IRelatedItems.relatedItems='someField') but thats not possible
> > because 'IRelatedItems.relatedItems' is not an allowed keyword in
> > python.
> > However I can do it by directly setting IMyType.setTaggedValue
> > (ORDER_KEY, [('IRelatedItems.relatedItems', 'before', 'someField')])
>
> I wouldn't recommend it, but you could probably do this:
>
> form.order_before(**{'IRelatedItems.relatedItems': 'someField})

ah cool, this works.

> For this use case, I'd probably suggest you use a custom form (see
> below). You can always do the reverse - put your field after
> IRelatedItems.relatedItems, instead of moving it before yours.

Doing the reverse would be an option if I can change the fieldset of
IRelatedItems.relatedItems before.
If not, my fields get moved into the fieldset of the relatedItems
field.
(when changing the order of a field relative to another field, it is
always moved into the fieldset of the relative field.)

To summarize, making the fieldset directive work with fields not in
the schema where the directive is defined would be adequate.

Martin Aspeli

unread,
Dec 8, 2009, 6:17:30 AM12/8/09
to dexterity-...@googlegroups.com
2009/12/8 Thomas Buchberger <thomas.b...@gmail.com>:
> On 8 Dez., 01:50, Martin Aspeli <optil...@gmail.com> wrote:
>
>> > As an example, let's assume we have a type with the schema IMyType and
>> > the behavior IRelatedItems. Now I would like to move the
>> > 'relatedItems' field into another fieldset. I would do that by
>> > defining a form.fieldset directive on IMyType because I only want to
>> > change the fieldset for my type and not for every type having the
>> > IRelatedItems behavior. However this doesn't work because
>> > plone.autoform only changes fieldsets for fields that are defined in
>> > the same schema as the directive.
>>
>> That seems like a reasonable thing to fix, but only for fieldsets (see below)
>
> I'd really appreciate it, if that could be fixed.
> I could try to do this, but as you already said, the algorithm for
> processing the schema hints in plone.autoform is quite complex.
> Currently the primary schema is processed first.
> I think it would be necessary to first process additional schemas and
> then process the primary schema at last to make sure fieldset
> directives on a types schema win over fieldset directives from
> behavior schemas.

I'm sure you're right. I'd need to look at the code again.

> Doing the reverse would be an option if I can change the fieldset of
> IRelatedItems.relatedItems before.
> If not, my fields get moved into the fieldset of the relatedItems
> field.
> (when changing the order of a field relative to another field, it is
> always moved into the fieldset of the relative field.)

Yes, but that's http://code.google.com/p/dexterity/issues/detail?id=98
right? If we fix that, then this should work for you.

> To summarize, making the fieldset directive work with fields not in
> the schema where the directive is defined would be adequate.

Agree, and that's reasonable, I think, since the fieldset stuff is
normally going to be an "enumerate" type directive rather than a "per
field" directive.

Martin

Thomas Buchberger

unread,
Dec 8, 2009, 9:30:13 AM12/8/09
to Dexterity development
On 8 Dez., 12:17, Martin Aspeli <optil...@gmail.com> wrote:

> > Doing the reverse would be an option if I can change the fieldset of
> > IRelatedItems.relatedItems before.
> > If not, my fields get moved into the fieldset of the relatedItems
> > field.
> > (when changing the order of a field relative to another field, it is
> > always moved into the fieldset of the relative field.)
>
> Yes, but that'shttp://code.google.com/p/dexterity/issues/detail?id=98
> right? If we fix that, then this should work for you.

yes, this fixes the problem for my use case.
actually it makes work this:
form.order_before(**{'IRelatedItems.relatedItems': 'someField})

--
Thomas
Reply all
Reply to author
Forward
0 new messages