[z3-checkins] r7602 - in z3/Five/branch/regebro-forms_support: . tests/products/FiveTest

regebro at codespeak.net regebro at codespeak.net
Tue Nov 23 12:27:19 MET 2004


Author: regebro
Date: Tue Nov 23 12:27:19 2004
New Revision: 7602

Modified:
   z3/Five/branch/regebro-forms_support/browserconfigure.py
   z3/Five/branch/regebro-forms_support/meta.zcml
   z3/Five/branch/regebro-forms_support/tests/products/FiveTest/configure.zcml
Log:
First half-assed try. Almost works, but there are no templates to use...

Modified: z3/Five/branch/regebro-forms_support/browserconfigure.py
==============================================================================
--- z3/Five/branch/regebro-forms_support/browserconfigure.py	(original)
+++ z3/Five/branch/regebro-forms_support/browserconfigure.py	Tue Nov 23 12:27:19 2004
@@ -288,6 +288,147 @@
             args = (new_class,)
             )
 
+
+#
+# Form generation from schema
+#
+from zope.app.form.browser.metaconfigure import BaseFormDirective
+from zope.app.location.interfaces import ILocation
+from zope.app.form.utility import setUpEditWidgets, applyWidgetsChanges
+from zope.app.form.browser.submit import Update
+
+class EditView(BrowserView):
+    """Simple edit-view base class
+
+    Subclasses should provide a schema attribute defining the schema
+    to be edited.
+    """
+
+    errors = ()
+    update_status = None
+    label = ''
+
+    # Fall-back field names computes from schema
+    fieldNames = property(lambda self: getFieldNamesInOrder(self.schema))
+    # Fall-back template
+    generated_form = ViewPageTemplateFile('edit.pt')
+
+    def __init__(self, context, request):
+        BrowserView.__init__(self, context, request)
+        self._setUpWidgets()
+
+    def _setUpWidgets(self):
+        adapted = self.schema(self.context)
+        if adapted is not self.context:
+            if not ILocation.providedBy(adapted):
+                adapted = LocationProxy(adapted)
+            adapted.__parent__ = self.context
+        self.adapted = adapted
+        setUpEditWidgets(self, self.schema, source=self.adapted, 
+                         names=self.fieldNames)
+
+    def setPrefix(self, prefix):
+        for widget in self.widgets():
+            widget.setPrefix(prefix)
+
+    def widgets(self):
+        return [getattr(self, name+'_widget')
+                for name in self.fieldNames]
+
+    def changed(self):
+        # This method is overridden to execute logic *after* changes
+        # have been made.
+        pass
+
+    def update(self):
+        if self.update_status is not None:
+            # We've been called before. Just return the status we previously
+            # computed.
+            return self.update_status
+
+        status = ''
+
+        content = self.adapted
+
+        if Update in self.request.form.keys():
+            changed = False
+            try:
+                changed = applyWidgetsChanges(self, self.schema,
+                    target=content, names=self.fieldNames)
+                # We should not generate events when an adapter is used.
+                # That's the adapter's job.
+                if changed and self.context is self.adapted:
+                    notify(ObjectModifiedEvent(content))
+            except WidgetsError, errors:
+                self.errors = errors
+                status = _("An error occured.")
+                get_transaction().abort()
+            else:
+                setUpEditWidgets(self, self.schema, source=self.adapted,
+                                 ignoreStickyValues=True, 
+                                 names=self.fieldNames)
+                if changed:
+                    self.changed()
+                    formatter = self.request.locale.dates.getFormatter(
+                        'dateTime', 'medium')
+                    status = _("Updated on ${date_time}")
+                    status.mapping = {'date_time': formatter.format(
+                        datetime.utcnow())}
+
+        self.update_status = status
+        return status
+
+        
+def EditViewFactory(name, schema, label, permission, layer,
+                    template, default_template, bases, for_, fields,
+                    fulledit_path=None, fulledit_label=None, menu=u''):
+    s = getGlobalService(Presentation)
+    class_ = makeClassForTemplate(template, used_for=schema, bases=bases)
+    class_.schema = schema
+    class_.label = label
+    class_.fieldNames = fields
+
+    class_.fulledit_path = fulledit_path
+    if fulledit_path and (fulledit_label is None):
+        fulledit_label = "Full edit"
+
+    class_.fulledit_label = fulledit_label
+
+    class_.generated_form = ViewPageTemplateFile(default_template)
+
+    # Not the prettiest solution, but the only one i can think of now:
+    class_.__init__ = EditView.__init__
+#     replace with proper checks
+#     defineChecker(class_,
+#                   NamesChecker(("__call__", "__getitem__",
+#                                 "browserDefault", "publishTraverse"),
+#                                permission))
+
+    s.provideView(for_, name, IBrowserRequest, class_, layer)
+
+                    
+class EditFormDirective(BaseFormDirective):
+
+    view = EditView
+    default_template = 'edit.pt'
+    title = 'Edit'
+
+    def _handle_menu(self):
+        if self.menu:
+            menuItemDirective(
+                self._context, self.menu, self.for_ or self.schema,
+                '@@' + self.name, self.title, permission=self.permission)
+
+    def __call__(self):
+        self._processWidgets()
+        self._handle_menu()
+        self._context.action(
+            discriminator=self._discriminator(),
+            callable=EditViewFactory,
+            args=self._args(),
+            kw={'menu': self.menu},
+        )
+                    
 #
 # mixin classes / class factories
 #
@@ -329,3 +470,5 @@
         class_.__used_for__ = used_for
 
     return class_
+
+    
\ No newline at end of file

Modified: z3/Five/branch/regebro-forms_support/meta.zcml
==============================================================================
--- z3/Five/branch/regebro-forms_support/meta.zcml	(original)
+++ z3/Five/branch/regebro-forms_support/meta.zcml	Tue Nov 23 12:27:19 2004
@@ -140,6 +140,21 @@
         handler=".browserconfigure.resourceDirectory"
         />
 
+<!--    forms-->
+            
+    <meta:complexDirective
+        name="editform"
+        schema="zope.app.form.browser.metadirectives.IEditFormDirective"
+        handler=".browserconfigure.EditFormDirective"
+        >
+
+      <meta:subdirective
+          name="widget"
+          schema="zope.app.form.browser.metadirectives.IWidgetSubdirective"
+          />
+
+    </meta:complexDirective>
+
   </meta:directives>
 
   <meta:directives namespace="http://namespaces.zope.org/five">

Modified: z3/Five/branch/regebro-forms_support/tests/products/FiveTest/configure.zcml
==============================================================================
--- z3/Five/branch/regebro-forms_support/tests/products/FiveTest/configure.zcml	(original)
+++ z3/Five/branch/regebro-forms_support/tests/products/FiveTest/configure.zcml	Tue Nov 23 12:27:19 2004
@@ -275,6 +275,21 @@
       permission="zope2.ViewManagementScreens"
       />
 
+  <!-- browser forms -->
+  
+  <browser:editform
+      schema=".interfaces.ISimpleContent"
+      for=".interfaces.ISimpleContent"
+      name="edit2.html"
+      permission="zope2.Public"
+      />
+<!--
+      class=".wikipage.WikiPageFormView"
+      label="Change Schema Page"
+      fields="title description"
+      menu="zmi_views" title="Edit" />
+-->
+  
   <!-- stuff that we'll override in overrides.zcml -->
 
   <browser:page


More information about the z3-checkins mailing list