-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

I would like to break the hard-wired assumption in the forms / widgets
machinery that all schemas must be interfaces with fields;  in
particular, I would like to make the introspection of the fieldset from
a given schema pluggable.

My motivation here is to make it possible to use schemas defined outside
of filesystem Python code play with the forms framework:

 - RDBMS tables and views have introspectable schemas;

 - Applications like CPSSchemas allow the business user to define
   content schema in the CMF equivalent of a site manager;  such
   schemas are clearly introspectable.

 - RelaxNG, W3Schema, DTD, etc. *might* fit into the framework (but
   might require explicit registration of a helper component).

In particular, I would like to tweak zope.app.form.utility.setUpWidgets
such that it does an adapter lookup, in place of the current invocation
of '_fieldlist' (the default adapter would do what '_fieldlist' does now).

I'm attaching a diff which sketches what such a refactoring would look
like.  Comments?


Tres.
- --
===================================================================
Tres Seaver          +1 202-558-7113          [EMAIL PROTECTED]
Palladion Software   "Excellence by Design"    http://palladion.com
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.5 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

iD8DBQFC09tI+gerLs4ltQ4RAs0bAKC4LZ0C/7YQSOk5Kf0wE3b5anKM/wCgwR1l
KCGW5uaqI8z4Q++gz9SEV/E=
=/WH4
-----END PGP SIGNATURE-----
Index: src/zope/app/form/interfaces.py
===================================================================
--- src/zope/app/form/interfaces.py	(revision 33279)
+++ src/zope/app/form/interfaces.py	(working copy)
@@ -222,3 +222,16 @@
 
         Display widgets should never be required.
         """)
+
+class IFieldIntrospector(Interface):
+    """ Adapt a schema to a set of fields.
+    """
+    def __call__(names=None):
+        """Return a sequence fields for the adapted schema.
+
+        o If 'names' is not None, returned only those fields named, in the
+          given order.
+
+        o Raise ValueError if any name in 'names' does not correspond to
+          a field.
+        """
Index: src/zope/app/form/utility.py
===================================================================
--- src/zope/app/form/utility.py	(revision 33279)
+++ src/zope/app/form/utility.py	(working copy)
@@ -35,6 +35,7 @@
 __docformat__ = 'restructuredtext'
 
 from zope import security
+from zope.interface import implements
 from zope.security.proxy import Proxy
 from zope.proxy import isProxy
 from zope.interface.interfaces import IMethod
@@ -44,6 +45,7 @@
 from zope.app.form.interfaces import IWidget
 from zope.app.form.interfaces import WidgetsError, MissingInputError
 from zope.app.form.interfaces import InputErrors
+from zope.app.form.interfaces import IFieldIntrospector
 from zope.app.form.interfaces import IInputWidget, IDisplayWidget
 from zope.component.interfaces import IViewFactory
 
@@ -51,12 +53,19 @@
 # accept a 'value' argument.
 no_value = object()
 
-def _fieldlist(names, schema):
-    if not names:
-        fields = getFieldsInOrder(schema)
-    else:
-        fields = [ (name, schema[name]) for name in names ]
-    return fields
+class DefaultFieldIntrospector:
+    """ Adapter implementing IFieldIntrospector for "standard" Zope3 schemas
+    """
+    implements(IFieldIntrospector)
+    def __init__(self, schema):
+        self.schema = schema
+
+    def __call__(self, names=None):
+        if names is None:
+            fields = getFieldsInOrder(self.schema)
+        else:
+            fields = [ (name, self.schema[name]) for name in names ]
+        return fields
     
     
 def _createWidget(context, field, viewType, request):
@@ -145,7 +154,8 @@
 
     `context` provides an alternative context for acquisition.
     """
-    for (name, field) in _fieldlist(names, schema):
+    introspector = IFieldIntrospector(schema)
+    for (name, field) in introspector(names):
         setUpWidget(view, name, field, viewType, 
                     value=initial.get(name, no_value),
                     prefix=prefix,
@@ -182,7 +192,8 @@
         source = view.context
     security_proxied = isProxy(source, Proxy)
     res_names = []
-    for name, field in _fieldlist(names, schema):
+    introspector = IFieldIntrospector(schema)
+    for (name, field) in introspector(names):
         try:
             value = field.get(source)
         except ForbiddenAttribute:
@@ -249,7 +260,8 @@
     if source is None:
         source = view.context
     res_names = []
-    for name, field in _fieldlist(names, schema):
+    introspector = IFieldIntrospector(schema)
+    for (name, field) in introspector(names):
         try:
             value = field.get(source)
         except ForbiddenAttribute:
@@ -273,7 +285,8 @@
     
     `names` can be specified to provide a subset of these fields.
     """
-    for name, field in _fieldlist(names, schema):
+    introspector = IFieldIntrospector(schema)
+    for (name, field) in introspector(names):
         if  getattr(view, name + '_widget').hasInput():
             return True
     return False
@@ -296,7 +309,8 @@
     if target is None:
         target = view.context
 
-    for name, field in _fieldlist(names, schema):
+    introspector = IFieldIntrospector(schema)
+    for (name, field) in introspector(names):
         widget = getattr(view, name + '_widget')
         if IInputWidget.providedBy(widget) and widget.hasInput():
             try:
@@ -340,7 +354,8 @@
     result = {}
     errors = []
 
-    for name, field in _fieldlist(names, schema):
+    introspector = IFieldIntrospector(schema)
+    for (name, field) in introspector(names):
         widget = getattr(view, name + '_widget')
         if IInputWidget.providedBy(widget):
             if widget.hasInput():
_______________________________________________
Zope3-dev mailing list
Zope3-dev@zope.org
Unsub: http://mail.zope.org/mailman/options/zope3-dev/archive%40mail-archive.com

Reply via email to