[Checkins] SVN: z3c.form/branches/zagy-sources/src/z3c/form/ added support for choices with sources -- no tests yet though

Christian Zagrodnick cz at gocept.com
Mon Oct 8 11:09:57 EDT 2007


Log message for revision 80717:
  added support for choices with sources -- no tests yet though

Changed:
  U   z3c.form/branches/zagy-sources/src/z3c/form/browser/checkbox.txt
  U   z3c.form/branches/zagy-sources/src/z3c/form/browser/radio.txt
  U   z3c.form/branches/zagy-sources/src/z3c/form/configure.zcml
  U   z3c.form/branches/zagy-sources/src/z3c/form/converter.txt
  U   z3c.form/branches/zagy-sources/src/z3c/form/term.py
  U   z3c.form/branches/zagy-sources/src/z3c/form/term.txt
  U   z3c.form/branches/zagy-sources/src/z3c/form/testing.py
  U   z3c.form/branches/zagy-sources/src/z3c/form/widget.txt

-=-
Modified: z3c.form/branches/zagy-sources/src/z3c/form/browser/checkbox.txt
===================================================================
--- z3c.form/branches/zagy-sources/src/z3c/form/browser/checkbox.txt	2007-10-08 14:38:20 UTC (rev 80716)
+++ z3c.form/branches/zagy-sources/src/z3c/form/browser/checkbox.txt	2007-10-08 15:09:56 UTC (rev 80717)
@@ -62,7 +62,7 @@
   >>> import zope.schema.interfaces
   >>> from zope.schema.vocabulary import SimpleVocabulary
   >>> import z3c.form.term
-  >>> class MyTerms(z3c.form.term.ChoiceTerms):
+  >>> class MyTerms(z3c.form.term.ChoiceTermsVocabulary):
   ...     def __init__(self, context, request, form, field, widget):
   ...         self.terms = SimpleVocabulary.fromValues(['yes', 'no'])
   >>> zope.component.provideAdapter(z3c.form.term.BoolTerms,

Modified: z3c.form/branches/zagy-sources/src/z3c/form/browser/radio.txt
===================================================================
--- z3c.form/branches/zagy-sources/src/z3c/form/browser/radio.txt	2007-10-08 14:38:20 UTC (rev 80716)
+++ z3c.form/branches/zagy-sources/src/z3c/form/browser/radio.txt	2007-10-08 15:09:56 UTC (rev 80717)
@@ -56,7 +56,7 @@
   >>> import zope.schema.interfaces
   >>> from zope.schema.vocabulary import SimpleVocabulary
   >>> import z3c.form.term
-  >>> class MyTerms(z3c.form.term.ChoiceTerms):
+  >>> class MyTerms(z3c.form.term.ChoiceTermsVocabulary):
   ...     def __init__(self, context, request, form, field, widget):
   ...         self.terms = SimpleVocabulary.fromValues(['yes', 'no'])
   >>> zope.component.provideAdapter(z3c.form.term.BoolTerms,

Modified: z3c.form/branches/zagy-sources/src/z3c/form/configure.zcml
===================================================================
--- z3c.form/branches/zagy-sources/src/z3c/form/configure.zcml	2007-10-08 14:38:20 UTC (rev 80716)
+++ z3c.form/branches/zagy-sources/src/z3c/form/configure.zcml	2007-10-08 15:09:56 UTC (rev 80717)
@@ -72,9 +72,15 @@
 
   <!-- ITerms -->
   <adapter
-      factory=".term.ChoiceTerms"
+      factory=".term.choice_terms_multiplexer"
       />
   <adapter
+      factory=".term.ChoiceTermsVocabulary"
+      />
+  <adapter
+      factory=".term.ChoiceTermsSource"
+      />
+  <adapter
       factory=".term.CollectionTerms"
       />
   <adapter

Modified: z3c.form/branches/zagy-sources/src/z3c/form/converter.txt
===================================================================
--- z3c.form/branches/zagy-sources/src/z3c/form/converter.txt	2007-10-08 14:38:20 UTC (rev 80716)
+++ z3c.form/branches/zagy-sources/src/z3c/form/converter.txt	2007-10-08 15:09:56 UTC (rev 80717)
@@ -466,7 +466,8 @@
 field. Before we can use the converter, we have to register the terms adapter:
 
   >>> from z3c.form import term
-  >>> zope.component.provideAdapter(term.ChoiceTerms)
+  >>> zope.component.provideAdapter(term.ChoiceTermsVocabulary)
+  >>> zope.component.provideAdapter(term.choice_terms_multiplexer)
 
 Let's now create a choice field and a widget:
 

Modified: z3c.form/branches/zagy-sources/src/z3c/form/term.py
===================================================================
--- z3c.form/branches/zagy-sources/src/z3c/form/term.py	2007-10-08 14:38:20 UTC (rev 80716)
+++ z3c.form/branches/zagy-sources/src/z3c/form/term.py	2007-10-08 15:09:56 UTC (rev 80717)
@@ -15,9 +15,13 @@
 
 $Id$
 """
+
+import zope.component
 import zope.schema
 from zope.schema import vocabulary
 
+import zope.app.form.browser.interfaces
+
 from z3c.form import interfaces
 from z3c.form.i18n import MessageFactory as _
 
@@ -46,7 +50,23 @@
         return self.terms.__contains__(value)
 
 
-class ChoiceTerms(Terms):
+ at zope.interface.implementer(interfaces.ITerms)
+ at zope.component.adapter(
+    zope.interface.Interface,
+    interfaces.IFormLayer,
+    zope.interface.Interface,
+    zope.schema.interfaces.IChoice,
+    interfaces.IWidget)
+def choice_terms_multiplexer(context, request, form, field, widget):
+    if field.vocabulary is None:
+        field = field.bind(context)
+    terms = field.vocabulary
+    return zope.component.queryMultiAdapter(
+        (context, request, form, field, terms, widget),
+        interfaces.ITerms)
+
+
+class ChoiceTermsVocabulary(Terms):
     """ITerms adapter for zope.schema.IChoice based implementations."""
 
     zope.component.adapts(
@@ -54,19 +74,71 @@
         interfaces.IFormLayer,
         zope.interface.Interface,
         zope.schema.interfaces.IChoice,
+        zope.schema.interfaces.IBaseVocabulary,
         interfaces.IWidget)
 
-    def __init__(self, context, request, form, field, widget):
+    zope.interface.implements(interfaces.ITerms)
+
+    def __init__(self, context, request, form, field, vocabulary, widget):
         self.context = context
         self.request = request
         self.form = form
         self.field = field
         self.widget = widget
-        if field.vocabulary is None:
-            field = field.bind(context)
-        self.terms = field.vocabulary
+        self.terms = vocabulary
 
 
+class ChoiceTermsSource(object):
+
+    zope.component.adapts(
+        zope.interface.Interface,
+        interfaces.IFormLayer,
+        zope.interface.Interface,
+        zope.schema.interfaces.IChoice,
+        zope.schema.interfaces.IIterableSource,
+        interfaces.IWidget)
+
+    zope.interface.implements(interfaces.ITerms)
+
+    def __init__(self, context, request, form, field, source, widget):
+        self.context = context
+        self.request = request
+        self.form = form
+        self.field = field
+        self.widget = widget
+        self.source = source
+        self.terms = zope.component.getMultiAdapter(
+            (self.source, self.request),
+            zope.app.form.browser.interfaces.ITerms)
+
+    def getTerm(self, value):
+        return self.terms.getTerm(value)
+
+    def getTermByToken(self, token):
+        # This is rather expensive
+        for value in self.source:
+            term = self.getTerm(value)
+            if term.token == token:
+                return term
+
+    def getValue(self, token):
+        return self.terms.getValue(token)
+
+    def __iter__(self):
+        # XXX Not defined in interface
+        for value in self.source:
+            yield self.terms.getTerm(value)
+
+    def __len__(self):
+        # XXX Not defined in interface
+        return len(self.source)
+
+    def __contains__(self, value):
+        # XXX Not defined in interface
+        # XXX value or term?
+        return value in self.source
+
+
 class BoolTerms(Terms):
     """Default yes and no terms are used by default for IBool fields."""
 

Modified: z3c.form/branches/zagy-sources/src/z3c/form/term.txt
===================================================================
--- z3c.form/branches/zagy-sources/src/z3c/form/term.txt	2007-10-08 14:38:20 UTC (rev 80716)
+++ z3c.form/branches/zagy-sources/src/z3c/form/term.txt	2007-10-08 15:09:56 UTC (rev 80717)
@@ -72,15 +72,25 @@
 fields. Within the framework, terms are used as adapters with the follwoing
 discriminators: context, request, form, field, and widget.
 
-The first terms implementation is for ``Choice`` fields:
+The first terms implementation is for ``Choice`` fields. Choice fields
+unfortunately can have a vocabulary and a source which behave differently.
+Let's have a look a the vocabulary first:
 
+  >>> import zope.component
+  >>> zope.component.provideAdapter(term.ChoiceTermsVocabulary)
+  >>> import z3c.form.testing
+  >>> request = z3c.form.testing.TestRequest()
+  >>> import z3c.form.widget
+  >>> widget = z3c.form.widget.Widget(request)
+
   >>> import zope.schema
 
   >>> ratingField = zope.schema.Choice(
   ...     title=u'Rating',
   ...     vocabulary=ratings)
 
-  >>> terms = term.ChoiceTerms(None, None, None, ratingField, None)
+  >>> terms = term.choice_terms_multiplexer(
+  ...     None, request, None, ratingField, widget)
   >>> [entry.title for entry in terms]
   [u'bad', u'okay', u'good']
 
@@ -93,7 +103,8 @@
 
 Initially we get an error because the "Ratings" vocabulary is not defined:
 
-  >>> terms = term.ChoiceTerms(None, None, None, ratingField2, None)
+  >>> terms = term.choice_terms_multiplexer(
+  ...     None, request, None, ratingField2, widget)
   Traceback (most recent call last):
   ...
   VocabularyRegistryError: unknown vocabulary: 'Ratings'
@@ -109,7 +120,8 @@
 
 We should now be able to get all terms as before:
 
-  >>> terms = term.ChoiceTerms(None, None, None, ratingField2, None)
+  >>> terms = term.choice_terms_multiplexer(
+  ...     None, request, None, ratingField, widget)
   >>> [entry.title for entry in terms]
   [u'bad', u'okay', u'good']
 

Modified: z3c.form/branches/zagy-sources/src/z3c/form/testing.py
===================================================================
--- z3c.form/branches/zagy-sources/src/z3c/form/testing.py	2007-10-08 14:38:20 UTC (rev 80716)
+++ z3c.form/branches/zagy-sources/src/z3c/form/testing.py	2007-10-08 15:09:56 UTC (rev 80717)
@@ -134,7 +134,8 @@
     zope.component.provideAdapter(converter.SequenceDataConverter)
     zope.component.provideAdapter(converter.FieldWidgetDataConverter)
     # Adapter for providing terms to radio list and other widgets
-    zope.component.provideAdapter(term.ChoiceTerms)
+    zope.component.provideAdapter(term.choice_terms_multiplexer)
+    zope.component.provideAdapter(term.ChoiceTermsVocabulary)
     zope.component.provideAdapter(term.BoolTerms)
     # Adapter to create an action from a button
     zope.component.provideAdapter(

Modified: z3c.form/branches/zagy-sources/src/z3c/form/widget.txt
===================================================================
--- z3c.form/branches/zagy-sources/src/z3c/form/widget.txt	2007-10-08 14:38:20 UTC (rev 80716)
+++ z3c.form/branches/zagy-sources/src/z3c/form/widget.txt	2007-10-08 15:09:56 UTC (rev 80717)
@@ -469,11 +469,12 @@
 the adapter is registered, everything should work as expected:
 
   >>> from z3c.form import term
-  >>> zope.component.provideAdapter(term.ChoiceTerms)
+  >>> zope.component.provideAdapter(term.ChoiceTermsVocabulary)
+  >>> zope.component.provideAdapter(term.choice_terms_multiplexer)
 
   >>> seqWidget.update()
   >>> seqWidget.terms
-  <z3c.form.term.ChoiceTerms object at ...>
+  <z3c.form.term.ChoiceTermsVocabulary object at ...>
 
 So that's it. Everything else is the same from then on.
 



More information about the Checkins mailing list