[Zope3-Users] thoughts about z3c.form-package

Roger Ineichen dev at projekt01.ch
Wed Oct 8 00:25:33 EDT 2008

Hi Garz

> Betreff: [Zope3-Users] thoughts about z3c.form-package
> hey,
> while using z3c.form-package i reach its limits here and 
> there. thats why i started to think about how a more general 
> implemention should look like. my intention of writing this 
> is that i want to know what you are thinking about it and i 
> want to know the design-decisions that led to the different 
> aspects of z3c.form.
> in the first part i try to give definitions of the concepts 
> of z3c.form as would understand them.
> 1.) what are the parts of a form-description?
> forms are composed of widgets, actions and other forms. these 
> elements are rendered into the template and are therefor the 
> forms elements. a form doesnt consist of anything else.

No, forms are composed with fields. The widget is just an adapter
which knows how to render a HTML representation.

You can also use z3c.form for other things like ReportLab
templates, there you don't need a HTML presentation given
from a HTML widget. You can write widgets for the same 
form with the same fields for such PDF templates.

The widget is an adapter which decorates the form within the
right output format. (or something like that)

> 2.) what are fields?
> if one is using widgets, the task of assigning the extracted 
> values of the widgets to an attribute of the context arises. 
> if you dont want to do this by hand, you can use fields. they 
> additionaly provide standard-values, constraints and validations.

the value from a input form get stored within a data manager. 
Fields and widget do not store anything. And a context is not 
needed in a form in general.

> as those fields provide the validation, they always want to 
> be used in combination with a widget. this stands in conflict 
> with what fields are expect to be, the connection between 
> attributes of a context and the widgets. for me it feels like 
> they are doing a little too much. two concepts which should 
> have been separated are unified in one object.

No fields are not the bridge between the context and the widget.
the field is only a object of the form which makes it possible
to get the right widget.

Data converter will convert the input from and to form values.
Data manager are responsible for dispatch the values to the
context or to anything else e.g. SQL DB or a session.

> now the button comes into play. the button is a field too. 
> needs a button validation? is a button conntected to a form 
> attribute? in my opinion, a button isnt a field at all.

A button as a field makes sense since a button is a part of 
the form. A button is also a form component like a input or 
textarea widget is.

Let's say a field is an item which defines an element of a form
which uses a own HTML representation (widget). e.g. button, input, 
textarea etc.

The widget is more like a output format for a given field.

But note, the form framework is incredible powerful. It's
also possible to use widgets without a form or a field.

We use z3c.form in other projects for totaly different things. 
e.g. we use an implementation of widgets which are inherited 
from Persistent. This widget can define a question and store
the answer value wihout any context or schema fields.

> at least this is very confusing. i cant detect a clear 
> concept behind a field. as i tried to show, the field as it 
> is used now mixes at least 3 different concepts. so i'm 
> asking, what is the definition of a field?
> from the z3c.form.field.txt: "The formlib uses form fields, 
> to describe how the form should be put together." this isnt 
> true, the fields describe, which attributes will be presented 
> through which widget. the form itself consists of widgets. a 
> field is only a little helper.

It depends in the definition of the term *form*. Stephan
and I where allways talking about the python class if we 
used the term *form*. I think you are talking about the
HTML page which the form produces if you render them, right?

> 3.) managers (fields, fieldwidgets, buttons, actions) if you 
> have a group of widgets, fields, buttons or actions that 
> belong to one concern, you can use a manager to collect them. 
> in templates you can iterate through widget-managers and 
> display all of its widgets or let it extract all data at once.
> in z3c.form in contrast, all those little elements cant be 
> used without their managers. the using of a single field 
> requires the fields-manager because only it is consulted by 
> the fieldwidgets-manager which in turn is the only one that 
> knows how to create a fieldwidget. fields should be able to 
> create their fieldwidgets on their own. managers shouldnt in 
> fact don't really be needed. they only should be a nice 
> addition if you want to group something of the same concern. 
> so why was it done this way?

The manager allows you to do some wired but very useful things.
You can join two set of fields etc, etc. See the manager API


fields = Field(interfaces.IFoo).select('foo')
fields += Field(interface.IBar)

> summary:
> z3c.form is all about this one use-case where the user 
> describes a context with the help of a schema. you define 
> fields, those fields are used to create fieldwidgets and 
> those are rendered in the standard-forms from z3c.formui. its 
> very nice to have this use-case well supported, but this 
> support should be based on more general implementations. this 
> would enable the user to create any kind of form.

Can you give an example what you can't do with z3c.form?

> some general words about object orientation:
> z3c.form isnt object oriented in all parts. for example the 
> field which connects context-attributes to widgets. it should 
> be the fields responsibility to apply those values extracted 
> from the widget to the attribute. instead it is done by an 
> external method z3c.form.applyChanges that is called by 
> EditForm. in this case i can imagine that this was done for 
> performance reasons. but if you had want to save method-calls 
> (calling an apply-method of every field), then the 
> fields-manager should be the guy to do this task. instead the 
> field-manager is iterated from the outside and the values are 
> assigned from this external method. this is clearly 
> functional programming with objects as datacontainers.

The applyChanges method is a hook. The EditForm provides a
method applyChanges which call this hook. This is explicit
done for custom implementations.

The data container concept was explicit choosen. You are right 
that's functional programming style. But that's an explicit 
pattern we where choosing. We explict expose the applyChanges 
because if you like to do something else for storing your 
extracted widget values is very easy to implement what you 
need in applyChanges.

> this has several disadvantages:
> 1.) in my case i want to introduce a new field-type that is 
> able to handle subforms (for the loved and hated 
> objectwidget). 

Adam Groszer is working on a ObjectWidget implementation.

> applying a value to a subobject isnt the same 
> as applying a value to a primitve attribute like an integer 
> or string. the solution as it is implemented in z3c.form 
> would be to rewrite the applyChanges-function to add an 
> if-statement that devides between the different field-types. 
> polymorphism was developed to handle those use-cases.
> 2.) the field is a connector to an attribute. only the field 
> should know, which attribute it is connected to. by 
> implementing it the way it was done in EditForm, it is 
> assumed, that the name of the attribute of the context, the 
> name the field and the name the widget uses are all the same. 
> its not really an issue because that's the way it is, but 
> this is not clean, because it could be different or something 
> could be changed and then it would be different.

I have some ideas how I think a subform should be implemented.
THe existing implementation doesn't fit. It at least has some
issues if you write complex forms with complex action and handlers.

The update order of a form and subform is an important part
which doesn't fit in the existing implementation.

object widget:
I think if a Object field get used a widget should be able to
offer widgets which defines more then one widget in it's widget.
But that's not a subform. I think a sub form should not be the 
standard for objects stored as attributes. I thkn an ObjectWidget
is the better solution.

A subform should be used to write forms with totaly different objects
as context. A sub form can probably used for write a form for items 
in a container etc.

> some little things
> 1.) fieldwidget
> this should be a subclass of widget, instead a widget and a 
> fieldwidget are the same and differences are if-ed. this is 
> not a big issue as well, but it also isnt clean as well.
> 2.) prefixes
> prefixes could be generated by joining every name of every 
> parent of an element. instead they are created by hand and 
> assigned directly. should this result in a better performance 
> too? otherwise its cumbersome, import util, expandPrefix... 
> its not necessary.
> now i'm interested in your points of view. nobody should feel 
> offended. its just that i'm coming to the conclusions i 
> presented and that i now want to know, if they are wrong or right. 
> for explanation: all these thoughts came from my plan to 
> write a general
> list- and dictionary-form. for this i already started to 
> write a new implementation of a form-package based z3c.form, 
> but at some points i'm not sure if i'm right. thats why i 
> want to discuss the basic thoughts of my approach. i feel 
> that in the existing implementation a lot of stuff is 
> optimized for speed, but sometimes i'm not sure about this, 
> as i explained in the object orientation-part. there it feels 
> to me like the principles of object orientation were not 
> used. i'm not sure, give me explanation. :) and not only 
> about this, about fields and the managers too.

I implemented a generic sequence widget at the last sprint.
You can use this widget for a sequence of any widget if you 
use IList or ITuple fields.

Whould be cool to see a dict base widget class which offers
some kind of key, value field support.

In general I see your point, z3c.form provides many, many hooks
which looks like a little or big overhead. But remember you can
use z3c.form for write forms for PDF generation if you provide
other widgets. The base form with the same fields can be used 
for PDF and HTML. (with PDF widgets or display widgets)

Or you can use z3c.form without any context and store the values
in a session or in SQL. Both use case can be done within the same 
python class without any changes. You only need a different 
data manager or in the first sample you need different widgets 
for PDF rendering. This is what z3c.form makes it so powerful.

Let's see what Adam Groszer is doing with the ObjectWidget
implementation, probably this could be used for your use cases.

But I still agree that we need to re-implement the sub form part.

Roger Ineichen

More information about the Zope3-users mailing list