[Checkins] SVN: grok/trunk/src/grok/ Patch from JW to add AddForm support.

Martijn Faassen faassen at infrae.com
Thu Dec 7 15:45:55 EST 2006


Log message for revision 71495:
  Patch from JW to add AddForm support.
  

Changed:
  U   grok/trunk/src/grok/__init__.py
  U   grok/trunk/src/grok/_grok.py
  U   grok/trunk/src/grok/components.py
  U   grok/trunk/src/grok/formlib.py
  A   grok/trunk/src/grok/ftests/form/addform.py

-=-
Modified: grok/trunk/src/grok/__init__.py
===================================================================
--- grok/trunk/src/grok/__init__.py	2006-12-07 20:36:29 UTC (rev 71494)
+++ grok/trunk/src/grok/__init__.py	2006-12-07 20:45:55 UTC (rev 71495)
@@ -32,7 +32,7 @@
 
 from grok.components import Model, Adapter, MultiAdapter, View, XMLRPC
 from grok.components import PageTemplate, Utility, Container, Traverser, Site
-from grok.components import EditForm, DisplayForm
+from grok.components import EditForm, DisplayForm, AddForm
 from grok.directive import context, name, template, templatedir
 from grok._grok import do_grok as grok  # Avoid name clash within _grok
 from grok._grok import SubscribeDecorator as subscribe

Modified: grok/trunk/src/grok/_grok.py
===================================================================
--- grok/trunk/src/grok/_grok.py	2006-12-07 20:36:29 UTC (rev 71494)
+++ grok/trunk/src/grok/_grok.py	2006-12-07 20:45:55 UTC (rev 71495)
@@ -144,10 +144,10 @@
         obj = getattr(module, name)
         # we don't care about picking up module-level annotations from grok
         if name.startswith('__grok_'):
-            continue        
+            continue
         if not util.defined_locally(obj, module_info.dotted_name):
             continue
-        
+
         if isinstance(obj, grok.PageTemplate):
             templates.register(name, obj)
             obj._annotateGrokInfo(name, module_info.dotted_name)
@@ -259,7 +259,9 @@
             formlib.setup_editform(factory, view_context)
         elif util.check_subclass(factory, components.DisplayForm):
             formlib.setup_displayform(factory, view_context)
-            
+        elif util.check_subclass(factory, components.AddForm):
+            formlib.setup_addform(factory, view_context)
+
         factory_name = factory.__name__.lower()
 
         # find templates
@@ -275,7 +277,7 @@
                                 "a template called '%s'."
                                 % (factory, template_name, factory_name),
                                 factory)
-            
+
         # we never accept a 'render' method for forms
         if util.check_subclass(factory, components.Form):
             if getattr(factory, 'render', None):
@@ -304,6 +306,9 @@
                 elif util.check_subclass(factory, components.DisplayForm):
                     # we have a display form without template
                     factory.template = formlib.defaultDisplayTemplate
+                elif util.check_subclass(factory, components.AddForm):
+                    # we have an add form without template
+                    factory.template = formlib.defaultEditTemplate
                 else:
                     # we do not accept a view without any way to render it
                     raise GrokError("View %r has no associated template or "
@@ -317,7 +322,7 @@
                                  adapts=(view_context, IDefaultBrowserLayer),
                                  provides=interface.Interface,
                                  name=view_name)
-        
+
         # TODO minimal security here (read: everything is public)
         defineChecker(factory, NoProxy)
 

Modified: grok/trunk/src/grok/components.py
===================================================================
--- grok/trunk/src/grok/components.py	2006-12-07 20:36:29 UTC (rev 71494)
+++ grok/trunk/src/grok/components.py	2006-12-07 20:45:55 UTC (rev 71495)
@@ -229,7 +229,7 @@
             item = self.context.get(name)
             if item:
                 return item
-    
+
         raise NotFound(self.context, name, request)
 
     def traverse(self, name):
@@ -272,7 +272,7 @@
         form.update()
 
         # this code is extracted and modified from form.render
-        
+
         # if the form has been updated, it may already have a result
         if form.form_result is None:
             # we reset, in case data has changed in a way that
@@ -284,11 +284,11 @@
             form.form_result = super(Form, self).__call__()
 
         return form.form_result
-    
+
 class EditForm(Form):
     label = ''
     status = ''
-    
+
     def applyChanges(self, **data):
         if form.applyChanges(self.context, self.form.form_fields, data,
                              self.form.adapters):
@@ -297,6 +297,10 @@
         else:
             self.status = "No changes"
 
+class AddForm(Form):
+    label = ''
+    status = ''
+
 class DisplayForm(Form):
     label = ''
     status = ''

Modified: grok/trunk/src/grok/formlib.py
===================================================================
--- grok/trunk/src/grok/formlib.py	2006-12-07 20:36:29 UTC (rev 71494)
+++ grok/trunk/src/grok/formlib.py	2006-12-07 20:45:55 UTC (rev 71495)
@@ -38,7 +38,7 @@
     """
     # get actions; by default no actions at all
     actions_ = getattr(factory, 'actions', form.Actions())
-    
+
     class RealDisplayForm(form.DisplayForm):
         form_fields = get_form_fields(factory, context)
         actions = actions_
@@ -46,6 +46,19 @@
     # this information during *runtime* not groktime.
     factory.__real_form__ = RealDisplayForm
 
+def setup_addform(factory, context):
+    """Construct the real add form, taking needed information from factory.
+    """
+    # get actions; by default no actions at all
+    actions_ = getattr(factory, 'actions', form.Actions())
+
+    class RealAddForm(form.AddForm):
+        form_fields = get_form_fields(factory, context)
+        actions = actions_
+    # we do not use the class annotation infrastructure as we use
+    # this information during *runtime* not groktime.
+    factory.__real_form__ = RealAddForm
+
 def initialize_schema(models):
     """Set the default values as class attributes to make formlib work
     """
@@ -110,7 +123,7 @@
     result = f.read()
     f.close()
     return result
-    
+
 defaultEditTemplate = components.PageTemplate(load_template(
     'default_edit_form.pt'))
 

Added: grok/trunk/src/grok/ftests/form/addform.py
===================================================================
--- grok/trunk/src/grok/ftests/form/addform.py	2006-12-07 20:36:29 UTC (rev 71494)
+++ grok/trunk/src/grok/ftests/form/addform.py	2006-12-07 20:45:55 UTC (rev 71495)
@@ -0,0 +1,50 @@
+"""
+A grok.AddForm is a special grok.View that renders an add form.
+
+  >>> import grok
+  >>> from grok.ftests.form.addform import Zoo, Mammoth
+  >>> grok.grok('grok.ftests.form.addform')
+  >>> getRootFolder()["zoo"] = Zoo()
+
+  >>> from zope.testbrowser.testing import Browser
+  >>> browser = Browser()
+  >>> browser.handleErrors = False
+  >>> browser.open("http://localhost/zoo/@@addmammoth")
+  >>> browser.getControl(name="form.name").value = "Manfred the Mammoth"
+  >>> browser.getControl(name="form.size").value = "Really big"
+  >>> browser.getControl("Add entry").click()
+  >>> print browser.contents
+  Hi, my name is Manfred the Mammoth, and I\'m "Really big"
+
+"""
+import grok
+from zope import schema
+
+class Zoo(grok.Container):
+    pass
+
+class Mammoth(grok.Model):
+    class fields:
+        name = schema.TextLine(title=u"Name")
+        size = schema.TextLine(title=u"Size")
+
+    def __init__(self, name, size):
+        self.name = name
+        self.size = size
+
+class Index(grok.View):
+    grok.context(Mammoth)
+    def render(self):
+        return 'Hi, my name is %s, and I\'m "%s"' % (self.context.name,
+                                                     self.context.size)
+
+class AddMammoth(grok.AddForm):
+    grok.context(Zoo)
+
+    form_fields = grok.AutoFields(Mammoth)
+
+    @grok.action('Add entry')
+    def add(self, **data):
+        self.context['manfred'] = Mammoth(data['name'], data['size'])
+        self.redirect(self.url(self.context['manfred']))
+



More information about the Checkins mailing list