[Checkins] SVN: z3c.formui/trunk/ - set version to 1.4.0dev

Roger Ineichen roger at projekt01.ch
Fri Dec 28 09:59:23 EST 2007


Log message for revision 82497:
  - set version to 1.4.0dev
  - Improve layout implementation, support built in layout templates
  - Added subform macro for sub form layout support
  - Added form module which offers built in layout support.
  - Added unittests for layout support

Changed:
  U   z3c.formui/trunk/CHANGES.txt
  U   z3c.formui/trunk/setup.py
  U   z3c.formui/trunk/src/z3c/formui/README.txt
  U   z3c.formui/trunk/src/z3c/formui/div-form.pt
  U   z3c.formui/trunk/src/z3c/formui/div-form.zcml
  A   z3c.formui/trunk/src/z3c/formui/form.py
  U   z3c.formui/trunk/src/z3c/formui/layout.py
  U   z3c.formui/trunk/src/z3c/formui/table-form.pt
  U   z3c.formui/trunk/src/z3c/formui/table-form.zcml
  A   z3c.formui/trunk/src/z3c/formui/tests.py

-=-
Modified: z3c.formui/trunk/CHANGES.txt
===================================================================
--- z3c.formui/trunk/CHANGES.txt	2007-12-28 14:56:25 UTC (rev 82496)
+++ z3c.formui/trunk/CHANGES.txt	2007-12-28 14:59:22 UTC (rev 82497)
@@ -2,6 +2,16 @@
 CHANGES
 =======
 
+Version 1.4.0 (unreleased)
+-------------------------
+
+- Improve layout implementation, support built in layout templates
+
+- Added form module which offers built in layout support.
+
+- Added unittests for layout support
+
+
 Version 1.3.0 (8/24/2007)
 -------------------------
 

Modified: z3c.formui/trunk/setup.py
===================================================================
--- z3c.formui/trunk/setup.py	2007-12-28 14:56:25 UTC (rev 82496)
+++ z3c.formui/trunk/setup.py	2007-12-28 14:59:22 UTC (rev 82497)
@@ -23,7 +23,7 @@
 
 setup (
     name='z3c.formui',
-    version='1.3.0',
+    version='1.4.0dev',
     author = "Stephan Richter, Roger Ineichen and the Zope Community",
     author_email = "zope3-dev at zope.org",
     description = "A set of initial UI components for z3c.form.",

Modified: z3c.formui/trunk/src/z3c/formui/README.txt
===================================================================
--- z3c.formui/trunk/src/z3c/formui/README.txt	2007-12-28 14:56:25 UTC (rev 82496)
+++ z3c.formui/trunk/src/z3c/formui/README.txt	2007-12-28 14:59:22 UTC (rev 82497)
@@ -17,10 +17,304 @@
 templates. This package provides some mixin classes to the regular form
 classes to support layout-based templating.
 
+  >>> from z3c.form import testing
+  >>> testing.setupFormDefaults()
 
-DIV-based Forms
----------------
+Before we can start writing forms, we must have the content to work with:
 
+  >>> import zope.interface
+  >>> import zope.schema
+  >>> class IPerson(zope.interface.Interface):
+  ...
+  ...     name = zope.schema.TextLine(
+  ...         title=u'Name',
+  ...         required=True)
+  ...
+  ...     age = zope.schema.Int(
+  ...         title=u'Age',
+  ...         description=u"The person's age.",
+  ...         min=0,
+  ...         default=20,
+  ...         required=False)
 
+  >>> from zope.schema.fieldproperty import FieldProperty
+  >>> class Person(object):
+  ...     zope.interface.implements(IPerson)
+  ... 
+  ...     name = FieldProperty(IPerson['name'])
+  ...     age = FieldProperty(IPerson['age'])
+  ...
+  ...     def __init__(self, name, age):
+  ...         self.name = name
+  ...         self.age = age
+  ...
+  ...     def __repr__(self):
+  ...         return '<%s %r>' % (self.__class__.__name__, self.name)
+
+Okay, that should suffice for now. Let's now create a working add form:
+
+  >>> from z3c.form import field
+  >>> from z3c.formui import form, layout
+  >>> class PersonAddForm(form.AddForm):
+  ...
+  ...     fields = field.Fields(IPerson)
+  ...
+  ...     def create(self, data):
+  ...         return Person(**data)
+  ...
+  ...     def add(self, object):
+  ...         self.context[object.id] = object
+  ...
+  ...     def nextURL(self):
+  ...         return 'index.html'
+
+Let's create a request:
+
+  >>> from z3c.form.testing import TestRequest
+  >>> from zope.interface import alsoProvides
+  >>> divRequest = TestRequest()
+
+And support the div form layer for our request:
+
+  >>> from z3c.formui.interfaces import IDivFormLayer
+  >>> alsoProvides(divRequest, IDivFormLayer)
+
+Now create the form:
+
+  >>> addForm = PersonAddForm(root, divRequest)
+
+Since we have not specified a template yet, we have to do this now. We use our 
+div based form template:
+
+  >>> import os
+  >>> import z3c.formui
+  >>> divFormTemplate = os.path.join(os.path.dirname(z3c.formui.__file__),
+  ...     'div-form.pt')
+
+  >>> from z3c.template.template import TemplateFactory
+  >>> divFormFactory = TemplateFactory(divFormTemplate, 'text/html')
+
+Now register the form (content) template:
+
+  >>> import zope.interface
+  >>> import zope.component
+  >>> from z3c.template.interfaces import IContentTemplate
+  >>> zope.component.provideAdapter(divFormFactory,
+  ...     (zope.interface.Interface, IDivFormLayer),
+  ...     IContentTemplate)
+
+And let's define a layout template which simply calls the render method. For a 
+more adavanced content/layout render concept see z3c.pagelet.
+
+  >>> import tempfile
+  >>> temp_dir = tempfile.mkdtemp()
+
+  >>> myLayout = os.path.join(temp_dir, 'myLayout.pt')
+  >>> open(myLayout, 'w').write('''<html>
+  ...   <body>
+  ...     <tal:block content="structure view/render">
+  ...       content
+  ...     </tal:block>
+  ...   </body>
+  ... </html>''')
+  >>> myLayoutFactory = TemplateFactory(myLayout, 'text/html')
+
+  >>> from z3c.template.interfaces import ILayoutTemplate
+  >>> zope.component.provideAdapter(myLayoutFactory,
+  ...     (zope.interface.Interface, zope.interface.Interface), ILayoutTemplate)
+
+Now we can get our layout template:
+
+  >>> layout = zope.component.getMultiAdapter((addForm, divRequest),
+  ...     ILayoutTemplate)
+
+  >>> layout
+  <zope.app.pagetemplate.viewpagetemplatefile.ViewPageTemplateFile object at ...>
+
+
+DIV-based Layout
+----------------
+
+Let's now render the page. Note the output doesn't contain the layout template:
+
+  >>> addForm.update()
+  >>> print addForm.render()
+  <form action="http://127.0.0.1" method="post"
+          enctype="multipart/form-data" class="edit-form"
+          name="form" id="form">
+    <div class="viewspace">
+      <div class="required-info">
+        <span class="required">*</span> &ndash; required
+      </div>
+      <div>
+        <div id="form-widgets-name-row" class="row">
+          <div class="label">
+            <label for="form-widgets-name">
+              <span>Name</span>
+              <span class="required">*</span>
+            </label>
+          </div>
+          <div class="widget"><input type="text" id="form-widgets-name"
+                   name="form.widgets.name"
+                   class="text-widget required textline-field" value="" />
+          </div>
+        </div>
+        <div id="form-widgets-age-row" class="row">
+          <div class="label">
+            <label for="form-widgets-age">
+              <span>Age</span>
+            </label>
+          </div>
+          <div class="widget"><input type="text" id="form-widgets-age"
+                   name="form.widgets.age" class="text-widget int-field"
+                   value="20" />
+          </div>
+        </div>
+      </div>
+    </div>
+    <div>
+      <div class="buttons">
+        <input type="submit" id="form-buttons-add"
+               name="form.buttons.add"
+               class="submit-widget button-field" value="Add" />
+      </div>
+    </div>
+  </form>
+
+But we can call our form which uses the new layout template which renders
+the form within the div-form content template:
+
+  >>> print addForm()
+  <html>
+    <body>
+      <form action="http://127.0.0.1" method="post"
+        enctype="multipart/form-data" class="edit-form"
+        name="form" id="form">
+        <div class="viewspace">
+          <div class="required-info">
+            <span class="required">*</span>
+            &ndash; required
+          </div>
+          <div>
+            <div id="form-widgets-name-row" class="row">
+              <div class="label">
+                <label for="form-widgets-name">
+                  <span>Name</span>
+                  <span class="required">*</span>
+                </label>
+              </div>
+              <div class="widget"><input type="text" id="form-widgets-name"
+                   name="form.widgets.name"
+                   class="text-widget required textline-field" value="" />
+              </div>
+            </div>
+            <div id="form-widgets-age-row" class="row">
+              <div class="label">
+                <label for="form-widgets-age">
+                  <span>Age</span>
+                </label>
+              </div>
+              <div class="widget"><input type="text" id="form-widgets-age"
+                   name="form.widgets.age" class="text-widget int-field"
+                   value="20" />
+              </div>
+            </div>
+          </div>
+        </div>
+        <div>
+          <div class="buttons">
+            <input type="submit" id="form-buttons-add"
+             name="form.buttons.add"
+             class="submit-widget button-field" value="Add" />
+          </div>
+        </div>
+      </form>
+    </body>
+  </html>
+
+
 Table-based Forms
 -----------------
+
+There is a table based layout too. Let's define the template and use them:
+
+  >>> from z3c.formui.interfaces import ITableFormLayer
+  >>> tableFormTemplate = os.path.join(os.path.dirname(z3c.formui.__file__),
+  ...     'table-form.pt')
+
+  >>> from z3c.template.template import TemplateFactory
+  >>> tableFormFactory = TemplateFactory(tableFormTemplate, 'text/html')
+
+Now register the form (content) template:
+
+  >>> zope.component.provideAdapter(tableFormFactory,
+  ...     (zope.interface.Interface, ITableFormLayer), IContentTemplate)
+
+Patch the request and call the form again:
+
+  >>> tableRequest = TestRequest()
+  >>> alsoProvides(tableRequest, ITableFormLayer)
+
+Now our new request should know the table based form template:
+
+  >>> addForm = PersonAddForm(root, tableRequest)
+  >>> print addForm()
+  <html>
+    <body>
+      <form action="http://127.0.0.1" method="post"
+        enctype="multipart/form-data" class="edit-form"
+        name="form" id="form">
+        <div class="viewspace">
+          <div class="required-info">
+            <span class="required">*</span>
+            &ndash; required
+          </div>
+          <div>
+          <table class="form-fields">
+                <tr class="row">
+                  <td class="label">
+                    <label for="form-widgets-name">
+                      <span>Name</span>
+                      <span class="required"> * </span>
+                    </label>
+                  </td>
+                  <td class="field">
+                    <div class="widget"><input type="text" id="form-widgets-name"
+                         name="form.widgets.name"
+                         class="text-widget required textline-field" value="" />
+                    </div>
+                  </td>
+                </tr>
+                <tr class="row">
+                  <td class="label">
+                    <label for="form-widgets-age">
+                      <span>Age</span>
+                    </label>
+                  </td>
+                  <td class="field">
+                    <div class="widget"><input type="text" id="form-widgets-age"
+                         name="form.widgets.age" class="text-widget int-field"
+                         value="20" />
+                    </div>
+                  </td>
+                </tr>
+          </table>
+        </div>
+      </div>
+      <div>
+        <div class="buttons">
+          <input type="submit" id="form-buttons-add"
+         name="form.buttons.add"
+         class="submit-widget button-field" value="Add" />
+        </div>
+      </div>
+      </form>
+    </body>
+  </html>
+
+
+Cleanup
+-------
+
+  >>> import shutil
+  >>> shutil.rmtree(temp_dir)

Modified: z3c.formui/trunk/src/z3c/formui/div-form.pt
===================================================================
--- z3c.formui/trunk/src/z3c/formui/div-form.pt	2007-12-28 14:56:25 UTC (rev 82496)
+++ z3c.formui/trunk/src/z3c/formui/div-form.pt	2007-12-28 14:59:22 UTC (rev 82497)
@@ -7,6 +7,7 @@
                       action view/action;
                       name view/name;
                       id view/id">
+  <metal:block define-macro="subform">
   <div class="viewspace" metal:define-slot="viewspace">
     <metal:block define-slot="label">
       <h1 metal:define-macro="label"
@@ -104,4 +105,7 @@
     </div>
   </div>
   </metal:block>
+  <metal:block define-slot="bottom">
+  </metal:block>
+  </metal:block>
 </form>

Modified: z3c.formui/trunk/src/z3c/formui/div-form.zcml
===================================================================
--- z3c.formui/trunk/src/z3c/formui/div-form.zcml	2007-12-28 14:56:25 UTC (rev 82496)
+++ z3c.formui/trunk/src/z3c/formui/div-form.zcml	2007-12-28 14:59:22 UTC (rev 82497)
@@ -27,6 +27,11 @@
       layer=".interfaces.IDivFormLayer"
       />
   <z3c:macro
+      name="subform"
+      template="div-form.pt"
+      layer=".interfaces.IDivFormLayer"
+      />
+  <z3c:macro
       name="form-label"
       macro="label"
       template="div-form.pt"

Added: z3c.formui/trunk/src/z3c/formui/form.py
===================================================================
--- z3c.formui/trunk/src/z3c/formui/form.py	                        (rev 0)
+++ z3c.formui/trunk/src/z3c/formui/form.py	2007-12-28 14:59:22 UTC (rev 82497)
@@ -0,0 +1,45 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Form UI Browser
+
+$Id: browser.py 75941 2007-05-24 14:48:22Z srichter $
+"""
+__docformat__ = "reStructuredText"
+
+from z3c.form import form
+from z3c.formui import layout
+
+# offer built in layout support
+extends = form.extends
+applyChanges = form.applyChanges
+
+
+class BaseForm(layout.FormLayoutSupport, form.BaseForm):
+    """Layout aware base form."""
+
+
+class DisplayForm(layout.FormLayoutSupport, form.DisplayForm):
+    """Layout aware display form."""
+
+
+class Form(layout.FormLayoutSupport, form.Form):
+    """Layout aware form."""
+
+
+class AddForm(layout.AddFormLayoutSupport, form.AddForm):
+    """Layout aware add form."""
+
+
+class EditForm(layout.FormLayoutSupport, form.EditForm):
+    """Layout aware edit form."""


Property changes on: z3c.formui/trunk/src/z3c/formui/form.py
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: z3c.formui/trunk/src/z3c/formui/layout.py
===================================================================
--- z3c.formui/trunk/src/z3c/formui/layout.py	2007-12-28 14:56:25 UTC (rev 82496)
+++ z3c.formui/trunk/src/z3c/formui/layout.py	2007-12-28 14:59:22 UTC (rev 82497)
@@ -16,25 +16,37 @@
 $Id$
 """
 __docformat__ = "reStructuredText"
+
 import zope.component
 from z3c.template.interfaces import ILayoutTemplate
 
+
 class FormLayoutSupport(object):
+    """Layout support for forms except IAddForm."""
 
+    layout = None
+
     def __call__(self):
         self.update()
-        layout = zope.component.getMultiAdapter((self, self.request),
-            ILayoutTemplate)
-        return layout(self)
+        if self.layout is None:
+            layout = zope.component.getMultiAdapter((self, self.request),
+                ILayoutTemplate)
+            return layout(self)
+        return self.layout()
 
 
 class AddFormLayoutSupport(object):
+    """Layout support for IAddForm."""
 
+    layout = None
+
     def __call__(self):
         self.update()
         if self._finishedAdd:
             self.request.response.redirect(self.nextURL())
             return ''
-        layout = zope.component.getMultiAdapter((self, self.request),
-            ILayoutTemplate)
-        return layout(self)
+        if self.layout is None:
+            layout = zope.component.getMultiAdapter((self, self.request),
+                ILayoutTemplate)
+            return layout(self)
+        return self.layout()

Modified: z3c.formui/trunk/src/z3c/formui/table-form.pt
===================================================================
--- z3c.formui/trunk/src/z3c/formui/table-form.pt	2007-12-28 14:56:25 UTC (rev 82496)
+++ z3c.formui/trunk/src/z3c/formui/table-form.pt	2007-12-28 14:59:22 UTC (rev 82497)
@@ -7,6 +7,7 @@
                       action view/action;
                       name view/name;
                       id view/id">
+  <metal:block define-macro="subform">
   <div class="viewspace" metal:define-slot="viewspace">
     <metal:block define-slot="label">
       <h1 metal:define-macro="label"
@@ -121,4 +122,7 @@
       </div>
     </div>
   </metal:block>
+  <metal:block define-slot="bottom">
+  </metal:block>
+  </metal:block>
 </form>

Modified: z3c.formui/trunk/src/z3c/formui/table-form.zcml
===================================================================
--- z3c.formui/trunk/src/z3c/formui/table-form.zcml	2007-12-28 14:56:25 UTC (rev 82496)
+++ z3c.formui/trunk/src/z3c/formui/table-form.zcml	2007-12-28 14:59:22 UTC (rev 82497)
@@ -27,6 +27,11 @@
       layer=".interfaces.ITableFormLayer"
       />
   <z3c:macro
+      name="subform"
+      template="table-form.pt"
+      layer=".interfaces.ITableFormLayer"
+      />
+  <z3c:macro
       name="form-label"
       macro="label"
       template="table-form.pt"

Added: z3c.formui/trunk/src/z3c/formui/tests.py
===================================================================
--- z3c.formui/trunk/src/z3c/formui/tests.py	                        (rev 0)
+++ z3c.formui/trunk/src/z3c/formui/tests.py	2007-12-28 14:59:22 UTC (rev 82497)
@@ -0,0 +1,34 @@
+##############################################################################
+#
+# Copyright (c) 2005 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+$Id: tests.py 72087 2007-01-18 01:03:33Z rogerineichen $
+"""
+__docformat__ = "reStructuredText"
+
+import unittest
+from zope.testing import doctest
+
+from z3c.form import testing
+
+
+def test_suite():
+    return unittest.TestSuite((
+        doctest.DocFileSuite('README.txt',
+            setUp=testing.setUp, tearDown=testing.tearDown,
+            optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS),
+        ))
+
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')


Property changes on: z3c.formui/trunk/src/z3c/formui/tests.py
___________________________________________________________________
Name: svn:eol-style
   + native



More information about the Checkins mailing list