[Zope3-dev] Proposal: Vocabulary Fields

Martijn Faassen faassen@vet.uu.nl
Tue, 29 Apr 2003 12:05:48 +0200


Fred L. Drake, Jr. wrote:
> 
> I've posted a new proposal in the Zope 3 wiki:
> 
>         http://dev.zope.org/Zope3/VocabularyFields
> 
> >From the proposal:
> 
>   Zope schema provide support for an "Enumerated" flavor of many basic
>   types.  The Enumerated fields provide a way to specify a field which
>   may have any value or, more interestingly, one from a list of
>   possible values hard-coded in the schema.

I still disagree with this multiplication of entities; we now have 
fields and enumerated fields while before we just had one kind.
I still haven't seen a motivation for this.

>   Vocabulary fields provide a conceptually similar field type for
>   situations in which the set of options may be highly dynamic or
>   otherwise by decoupled from the schema definition itself.

First I thought you were introducing a third category of field next to
non-enumerated and enumerated, but if I understand the proposal correctly 
there would just be one new field, the VocabularyField.

>   A vocabulary may be provided by some object in the ZODB, a query to an
>   external database, the contents of a file maintained by another
>   process, or static data provided by a separately maintained piece of
>   code.

Why such a restricted dynamism? Are we going to introduce a new set of
classes if people want 'required' state to be dynamic?

The approach I took in Formualtor is to allow (on any field) a way to call a 
method to get the value of a field property, instead of getting it
statically from the field itself. That way you allow the dynamism of
*everything*, when the user so requires. Fields already have a way to get
bound to objects which can be used this way (see the bind() method).
The form code does this for you.

Arbitrary dynamism:

class IMySchema(Interface):
 
    def getTitle():
       pass

    def getDescription():
       pass

    foo = TextLine(
       title=getTitle,
       description=getDescription,
       default=u"",
       required=False)

and for the case where I do want a vocabulary:

class IAnotherSchema(Interface):
    def getAllowedValuesForFoo():
        pass

    foo = TextLine(
       title="Foo",
       description="Foo desc",
       default=u"",
       required=False,
       allowed_values=getAllowedValuesForFoo)

class Something:
    __implements__ = IAnotherSchema

    def getAllowedValuesForFoo(self):
        return self.somethingVeryDynamic()

This approach is simple to use, it allows other field properties to
behave dynamically as well, and the interface actually states clearly
that a field is going to be dynamic.

>   A vocabulary field in a schema contains either a vocabulary object
>   (IAbstractVocabulary) or a name of a vocabulary.  If a name is used,
>   the specific vocabulary to use will be supplied by a registry when
>   the schema field is bound to an instance of a content object.

Worrisome in the proposal as well is the inclusion of presentation 
information in the field. Now I understand this is only presentation of
the vocabulary data and not the field itself, but this still seems the
responsibility of the widget displaying the field, not the field itself.
One question would be how to accomplish some of the same functionality
you propose in the presentation components in my proposal. Then again,
you punt on how this is going to hooked up to forms as well. :)
 
Two new registries (one for vocabularies and one for presentations) added
to the system for this functionality also seems worrying.. This requires
quite a few registrations of things before you can actually start to use
a VocabularyField, which may be a usability issue.  

Regards,

Martijn