[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> – 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>
+ – 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>
+ – 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