z3c.formui-2.3.0/ 0000775 0001750 0001750 00000000000 11730447640 013753 5 ustar srichter srichter z3c.formui-2.3.0/bootstrap.py 0000664 0001750 0001750 00000003373 11730354336 016347 0 ustar srichter srichter ##############################################################################
#
# 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.
#
##############################################################################
"""Bootstrap a buildout-based project
Simply run this script in a directory containing a buildout.cfg.
The script accepts buildout command-line options, so you can
use the -c option to specify an alternate configuration file.
$Id: bootstrap.py 113341 2010-06-11 07:34:44Z ctheune $
"""
import os, shutil, sys, tempfile, urllib2
tmpeggs = tempfile.mkdtemp()
ez = {}
exec urllib2.urlopen('http://peak.telecommunity.com/dist/ez_setup.py'
).read() in ez
ez['use_setuptools'](to_dir=tmpeggs, download_delay=0)
import pkg_resources
cmd = 'from setuptools.command.easy_install import main; main()'
if sys.platform == 'win32':
cmd = '"%s"' % cmd # work around spawn lamosity on windows
ws = pkg_resources.working_set
assert os.spawnle(
os.P_WAIT, sys.executable, sys.executable,
'-c', cmd, '-mqNxd', tmpeggs, 'zc.buildout',
dict(os.environ,
PYTHONPATH=
ws.find(pkg_resources.Requirement.parse('setuptools')).location
),
) == 0
ws.add_entry(tmpeggs)
ws.require('zc.buildout')
import zc.buildout.buildout
zc.buildout.buildout.main(sys.argv[1:] + ['bootstrap'])
shutil.rmtree(tmpeggs)
z3c.formui-2.3.0/PKG-INFO 0000664 0001750 0001750 00000124526 11730447640 015062 0 ustar srichter srichter Metadata-Version: 1.0
Name: z3c.formui
Version: 2.3.0
Summary: A set of initial UI components for z3c.form.
Home-page: http://pypi.python.org/pypi/z3c.formui
Author: Stephan Richter, Roger Ineichen and the Zope Community
Author-email: zope-dev@zope.org
License: ZPL 2.1
Description: This package provides a set of default layouts for the ``z3c.form``
framework. In particular it provides a DIV-based and a TABLE-based layout. The
developer can use either layout by inheriting from a different base layer.
The package also has some support for layout/pagelet templates.
.. contents::
====================
Form User Interfaces
====================
This package provides several useful templates to get a quick start with the
``z3c.form`` package. Previous form frameworks always included default
templates that were implemented in a particular user-interface development
pattern. If you wanted to use an alternative strategy to develop user
interfaces, it was often tedious to do so. This package aims to provide some
options without requiring them for the basic framework.
Layout Template Support
-----------------------
One common pattern in Zope 3 user interface development is the use of layout
templates (see z3c.template). This package provides some mixin classes to the
regular form classes to support layout-based templating.
>>> from z3c.form import testing
>>> testing.setupFormDefaults()
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 advanced 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('''
...
...
... content
...
...
... ''')
>>> 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.__class__.__name__
'ViewPageTemplateFile'
>>> os.path.basename(layout.filename)
'myLayout.pt'
DIV-based Layout
----------------
Let's now render the page. Note the output doesn't contain the layout template:
>>> addForm.update()
>>> print addForm.render()
But we can call our form which uses the new layout template which renders
the form within the div-form content template:
>>> print addForm()
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()
`AddForm` rendering for `IAdding`
---------------------------------
The `z3c.formui` package also provides a layout-aware version of
`z3c.form.adding.AddForm` which can be used for creating forms for the
`zope.app.container.interfaces.IAdding` mechanism.
Let's check its template support. First, create the form for an `Adding`
instance. We just need to define the ``create()`` method, because the default
``add()`` and ``nextURL()`` methods are already defined using the `Adding`
object.
>>> from z3c.formui import adding
>>> class AddingPersonAddForm(adding.AddForm):
...
... fields = field.Fields(IPerson)
...
... def create(self, data):
... return Person(**data)
Let's now instantiate the adding component and the add form:
>>> from zope.app.container.browser.adding import Adding
>>> rootAdding = Adding(root, divRequest)
>>> addForm = AddingPersonAddForm(rootAdding, divRequest)
First, let's ensure that we can lookup a layout template for the form:
>>> layout = zope.component.getMultiAdapter(
... (addForm, divRequest), ILayoutTemplate)
>>> layout.__class__.__name__
'ViewPageTemplateFile'
Okay, that worked. Let's now render the div-based addform:
>>> print addForm()
Okay, now we are going to check table layout support.
>>> rootAdding = Adding(root, tableRequest)
>>> addForm = AddingPersonAddForm(rootAdding, tableRequest)
Again, the layout should be available:
>>> layout = zope.component.getMultiAdapter((addForm, tableRequest),
... ILayoutTemplate)
>>> layout.__class__.__name__
'ViewPageTemplateFile'
Let's now render the form:
>>> print addForm()
Form Macros
-----------
Load the configuration, which will make sure that all macros get registered
correctly:
>>> from zope.configuration import xmlconfig
>>> import zope.component
>>> import zope.viewlet
>>> import zope.app.component
>>> import zope.app.publisher.browser
>>> import z3c.macro
>>> import z3c.template
>>> import z3c.formui
>>> xmlconfig.XMLConfig('meta.zcml', zope.component)()
>>> xmlconfig.XMLConfig('meta.zcml', zope.viewlet)()
>>> xmlconfig.XMLConfig('meta.zcml', zope.app.component)()
>>> xmlconfig.XMLConfig('meta.zcml', zope.app.publisher.browser)()
>>> xmlconfig.XMLConfig('meta.zcml', z3c.macro)()
>>> xmlconfig.XMLConfig('meta.zcml', z3c.template)()
>>> xmlconfig.XMLConfig('configure.zcml', z3c.formui)()
Div IContentTemplate
--------------------
Create some dummy form discriminators for calling div layout templates and
macros and check the div IContentTemplates:
>>> objects = (addForm, divRequest)
>>> zope.component.getMultiAdapter(objects, IContentTemplate).filename
'...div-form.pt'
>>> objects = (form.DisplayForm(None, None), divRequest)
>>> zope.component.getMultiAdapter(objects, IContentTemplate, '').filename
'...div-form-display.pt'
We offer the following named IContentTemplate:
>>> objects = (form.DisplayForm(None, None), divRequest)
>>> zope.component.getMultiAdapter(objects, IContentTemplate,
... 'display').filename
'...div-form-display.pt'
>>> objects = (form.DisplayForm(None, None), divRequest)
>>> zope.component.getMultiAdapter(objects, IContentTemplate,
... 'subform').filename
'...subform.pt'
Table ILayoutTemplate
---------------------
There is one generic layout template to build sub forms:
>>> objects = (form.DisplayForm(None, None), divRequest)
>>> zope.component.getMultiAdapter(objects, ILayoutTemplate,
... 'subform').filename
'...subform-layout.pt'
Div layout macros
-----------------
We have different form macros available for IInputForm:
>>> from z3c.macro.interfaces import IMacroTemplate
>>> objects = (None, addForm, divRequest)
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form')
[...div-form.pt'), ...metal:define-macro': u'form'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'subform')
[...div-form.pt'), ...define-macro': u'subform'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form-label')
[...div-form.pt'), ...define-macro': u'label'...
>>> zope.component.getMultiAdapter(
... objects, IMacroTemplate, 'form-required-info')
[...div-form.pt'), ...define-macro', u'required-info'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form-header')
[...div-form.pt'), ...define-macro': u'header'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form-errors')
[...div-form.pt'), ...define-macro': u'errors'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'widget-rows')
[...div-form.pt'), ...define-macro': u'widget-rows'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'widget-row')
[...div-form.pt'), ...define-macro': u'widget-row'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form-groups')
[...div-form.pt'), ...define-macro': u'groups'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form-buttons')
[...div-form.pt'), ...define-macro', u'buttons'...
And we have different form macros available for IDisplayForm:
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'subform-display')
[...div-form-display.pt'), ...define-macro': u'subform-display'...
Table IContentTemplate
----------------------
Create some dummy form discriminators for calling table layout templates and
macros and check the div IContentTemplates:
>>> objects = (addForm, tableRequest)
>>> zope.component.getMultiAdapter(objects, IContentTemplate, '').filename
'...table-form.pt'
>>> objects = (form.DisplayForm(None, None), tableRequest)
>>> zope.component.getMultiAdapter(objects, IContentTemplate, '').filename
'...table-form-display.pt'
We offer the following named IContentTemplate:
>>> objects = (form.DisplayForm(None, None), tableRequest)
>>> zope.component.getMultiAdapter(objects, IContentTemplate,
... 'display').filename
'...table-form-display.pt'
>>> objects = (form.DisplayForm(None, None), tableRequest)
>>> zope.component.getMultiAdapter(objects, IContentTemplate,
... 'subform').filename
'...subform.pt'
Table ILayoutTemplate
---------------------
There is one generic layout template to build sub forms:
>>> objects = (form.DisplayForm(None, None), tableRequest)
>>> zope.component.getMultiAdapter(objects, ILayoutTemplate,
... 'subform').filename
'...subform-layout.pt'
Table layout macros
-------------------
We have different form macros available for IInputForm:
>>> objects = (None, addForm, tableRequest)
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form')
[...table-form.pt'), ...metal:define-macro': u'form'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'subform')
[...table-form.pt'), ...define-macro': u'subform'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form-label')
[...table-form.pt'), ...define-macro': u'label'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form-required-info')
[...table-form.pt'), ...define-macro', u'required-info'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form-header')
[...table-form.pt'), ...define-macro': u'header'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form-errors')
[...table-form.pt'), ...define-macro': u'errors'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form-table')
[...table-form.pt'), ...define-macro', u'formtable'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form-row')
[...table-form.pt'), ...define-macro': u'formrow'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form-label-cell')
[...table-form.pt'), ...define-macro', u'labelcell'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form-widget-cell')
[...table-form.pt'), ...define-macro', u'widgetcell'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form-groups')
[...table-form.pt'), ...define-macro': u'groups'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form-buttons')
[...table-form.pt'), ...define-macro', u'buttons'...
And we have different form macros available for IDisplayForm:
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'subform-display')
[...table-form-display.pt'), ...define-macro': u'subform-display'...
Subform
-------
Let's give a quick overview how subform content and layout templates get used:
First define a new form which uses the template getter methods offered
from z3.template
>>> from z3c.template.template import getPageTemplate
>>> from z3c.template.template import getLayoutTemplate
The ``provider`` TALES expression which is a part of the lookup concept
was already registered by the testing setup, so we don't need to do it
here.
and the TALES expression called ``macro`` which can lookup our macro adapters.
Yes, macros are adapters in our content/layout template concept. See z3c.macro
for more information about the implementation. However, we already registered
the ``macro`` type in the testing setup, as it's needed for rendering form
templates.
and at least we need a pagelet
renderer. By default we use the provider called ``PageletRenderer`` defined
in the z3c.pagelet package. But right now, we don't have a dependency on
this package. So let's implement a simple renderer and use them as a
IContentProvider:
>>> class PageletRenderer(object):
... zope.component.adapts(zope.interface.Interface,
... zope.publisher.interfaces.browser.IBrowserRequest,
... zope.interface.Interface)
...
... def __init__(self, context, request, pagelet):
... self.__updated = False
... self.__parent__ = pagelet
... self.context = context
... self.request = request
...
... def update(self):
... pass
...
... def render(self):
... return self.__parent__.render()
>>> from zope.contentprovider.interfaces import IContentProvider
>>> zope.component.provideAdapter(PageletRenderer,
... provides=IContentProvider, name='pagelet')
Now define the form:
>>> class PersonEditForm(form.EditForm):
... """Edit form including layout support. See z3c.formui.form."""
...
... template = getPageTemplate('subform')
... layout = getLayoutTemplate('subform')
...
... fields = field.Fields(IPerson)
Now we can render the form with our previous created person instance:
>>> person = Person(u'Jessy', 6)
>>> editForm = PersonEditForm(person, divRequest)
Now we call the form which will update and render it:
>>> print editForm()
You can see that the form above is a real subform. It doesn't define the form
tag which makes it usable as a subform in parent forms.
Of course this works with table layout based forms too. Let's use our table
request and render the form again:
>>> editForm = PersonEditForm(person, tableRequest)
>>> print editForm()
Redirection
-----------
The form doesn't bother rendering itself and its layout when
request is a redirection as the rendering doesn't make any sense with
browser requests in that case. Let's create a view that does a
redirection in its update method:
>>> class RedirectingView(PersonEditForm):
... def update(self):
... super(RedirectingView, self).update()
... self.request.response.redirect('.')
It will return an empty string when called as a browser page.
>>> redirectView = RedirectingView(person, divRequest)
>>> redirectView() == ''
True
However, the ``render`` method will render form's template as usual:
>>> '' in redirectView.render()
True
The same thing should work for AddForms:
>>> class RedirectingAddView(PersonAddForm):
... def update(self):
... super(RedirectingAddView, self).update()
... self.request.response.redirect('.')
>>> redirectView = RedirectingAddView(person, divRequest)
>>> redirectView() == ''
True
No required fields
------------------
If there no required fields in the form, standard templates won't render
the "required-info" hint.
>>> class IAdditionalInfo(zope.interface.Interface):
...
... location = zope.schema.TextLine(title=u'Location', required=False)
... about = zope.schema.Text(title=u'About', required=False)
>>> class AdditionalInfoForm(form.AddForm):
...
... fields = field.Fields(IAdditionalInfo)
>>> additionalInfoForm = AdditionalInfoForm(root, divRequest)
>>> additionalInfoForm.update()
>>> '
' in additionalInfoForm.render()
False
>>> additionalInfoForm = AdditionalInfoForm(root, tableRequest)
>>> additionalInfoForm.update()
>>> '
' in additionalInfoForm.render()
False
Cleanup
-------
>>> import shutil
>>> shutil.rmtree(temp_dir)
=======
CHANGES
=======
2.3.0 (2012-03-15)
------------------
- Feature: Mark a widget row with the "required" class when the widget is
required. Similarly, when the widget has an error attached, add the "error"
class to the widget row. That allows you to change the styles of the label
and the widget if it is reuqired.
2.2.1 (2012-01-09)
------------------
- No longer using deprecated ``zope.testing.doctest`` but built-in
``doctest`` instead.
- Fixed tests so they do not break for `z3c.form` 2.5.0.
2.2.0 (2009-12-28)
------------------
- Fixed tests so they do not break for `z3c.form` 2.2.0.
- Using ``requiredInfo`` property (introduced in `z3c.form` 2.0.0) to
render the information about required fields. This property returns
an i18n message id making the information translateable.
- Added support for groups containing groups: They get displayed now.
2.1.0 (2009-09-01)
------------------
- Feature: Don't show required info hint if there's no required fields.
- Bug: Don't render add forms when redirecting as well.
- Bug: Fix redirection tests with newer zope.publisher that restricts
untrusted redirects to different domains.
2.0.0 (2009-06-14)
------------------
- Feature: Added support for context-specific template lookup, introduced in
`z3c.template` 1.2.0 - templates can now be registered using (view, request,
context) discriminator.
- Feature: Added support for `z3c.pt` templates using `z3c.ptcompat`
compatibility package.
- Feature: Added layout support for `IAdding` component based add forms.
- Feature: Added CSS for multi-widget which was added in `z3c.form` 2.0.0.
- Bug: Changed usage of ``template/macros/*`` to ``macro:*``, because the
first one doesn't work when we override a form template and use the form
macro, registered with this package.
- Bug: Don't do rendering in form's `__call__` method when request is a
redirection.
- Bug: Reformatted long-description to render properly on pypi.
1.4.2 (2008-08-26)
------------------
- Bug: Corrected typos and unwanted unicode characters.
1.4.1 (2008-01-23)
------------------
- Bug: Fixed up meta-data and the release.
1.4.0 (2008-01-21)
------------------
- Feature: Added subform content and layout template. This allows you to
configure real sub forms which do not render the form tag.
- Feature: Improve layout implementation, support built-in layout templates.
- Feature: Use ``IContentTemplate`` instead of ``IPageTemplate`` in layout
base classes. This will help to prevent running into recursion errors if
there is a missing layout template.
- Feature: Added form module which offers built-in layout support.
- Bug: Added missing display ``IContentTemplate``, otherwise we can run into a
recursion in some cases.
- Bug: Renamed table macro argument from ``form-required-info`` to
``required-info``. The macro ``form-required-info`` did not exist.
- Bug: Added unit tests for layout support.
- Bug: Added tests for layout macros.
- Bug: Added tests for layout templates.
1.3.0 (2007-08-24)
------------------
- Refactoring: Update CSS classes to reflect latest changes to the widget
classes in ``z3c.form``.
- Bug: Error view snippets may have a empty ``widget`` attribute values, so we
cannot rely on accessing the label of the widget. This is the case, if the
error view sniipet was created from an invariants validation error.
- Bug: The table-form template did not properly render the error at the
widget, because the ``render()`` method was not called. Thanks to Markus
Leist for the report.
1.2.0 (2007-07-18)
------------------
- Feature: The row div element now also has an id of the form
"
-row".
1.1.1 (2007-07-04)
------------------
- Refactoring: Split up registrations for simpler management of UI
components. This also makes it easier to see for developers how to create a
new template for forms.
1.1.0 (2007-06-29)
------------------
- Feature: Registered all defined macros for each form template. Also, added
more slots to the templates providing more hooks for customization.
- Feature: Added a macro/slot for the "required info", which explains how
required fields are marked.
- Feature: Added support for form labels.
- Feature: Added support for groups to templates.
1.0.1 (2007-06-22)
------------------
- Bug: Make sure we use the id for the "for" attribute of the "label"
element and not the name. This has worked until recently, because the
name and id were the same, but they are different now.
1.0.0 (2007-05-24)
------------------
- Initial Release
Keywords: zope3 form widget
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Web Environment
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Zope Public License
Classifier: Programming Language :: Python
Classifier: Natural Language :: English
Classifier: Operating System :: OS Independent
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Framework :: Zope3
z3c.formui-2.3.0/setup.cfg 0000664 0001750 0001750 00000000073 11730447640 015574 0 ustar srichter srichter [egg_info]
tag_build =
tag_date = 0
tag_svn_revision = 0
z3c.formui-2.3.0/CHANGES.txt 0000664 0001750 0001750 00000010773 11730447217 015574 0 ustar srichter srichter =======
CHANGES
=======
2.3.0 (2012-03-15)
------------------
- Feature: Mark a widget row with the "required" class when the widget is
required. Similarly, when the widget has an error attached, add the "error"
class to the widget row. That allows you to change the styles of the label
and the widget if it is reuqired.
2.2.1 (2012-01-09)
------------------
- No longer using deprecated ``zope.testing.doctest`` but built-in
``doctest`` instead.
- Fixed tests so they do not break for `z3c.form` 2.5.0.
2.2.0 (2009-12-28)
------------------
- Fixed tests so they do not break for `z3c.form` 2.2.0.
- Using ``requiredInfo`` property (introduced in `z3c.form` 2.0.0) to
render the information about required fields. This property returns
an i18n message id making the information translateable.
- Added support for groups containing groups: They get displayed now.
2.1.0 (2009-09-01)
------------------
- Feature: Don't show required info hint if there's no required fields.
- Bug: Don't render add forms when redirecting as well.
- Bug: Fix redirection tests with newer zope.publisher that restricts
untrusted redirects to different domains.
2.0.0 (2009-06-14)
------------------
- Feature: Added support for context-specific template lookup, introduced in
`z3c.template` 1.2.0 - templates can now be registered using (view, request,
context) discriminator.
- Feature: Added support for `z3c.pt` templates using `z3c.ptcompat`
compatibility package.
- Feature: Added layout support for `IAdding` component based add forms.
- Feature: Added CSS for multi-widget which was added in `z3c.form` 2.0.0.
- Bug: Changed usage of ``template/macros/*`` to ``macro:*``, because the
first one doesn't work when we override a form template and use the form
macro, registered with this package.
- Bug: Don't do rendering in form's `__call__` method when request is a
redirection.
- Bug: Reformatted long-description to render properly on pypi.
1.4.2 (2008-08-26)
------------------
- Bug: Corrected typos and unwanted unicode characters.
1.4.1 (2008-01-23)
------------------
- Bug: Fixed up meta-data and the release.
1.4.0 (2008-01-21)
------------------
- Feature: Added subform content and layout template. This allows you to
configure real sub forms which do not render the form tag.
- Feature: Improve layout implementation, support built-in layout templates.
- Feature: Use ``IContentTemplate`` instead of ``IPageTemplate`` in layout
base classes. This will help to prevent running into recursion errors if
there is a missing layout template.
- Feature: Added form module which offers built-in layout support.
- Bug: Added missing display ``IContentTemplate``, otherwise we can run into a
recursion in some cases.
- Bug: Renamed table macro argument from ``form-required-info`` to
``required-info``. The macro ``form-required-info`` did not exist.
- Bug: Added unit tests for layout support.
- Bug: Added tests for layout macros.
- Bug: Added tests for layout templates.
1.3.0 (2007-08-24)
------------------
- Refactoring: Update CSS classes to reflect latest changes to the widget
classes in ``z3c.form``.
- Bug: Error view snippets may have a empty ``widget`` attribute values, so we
cannot rely on accessing the label of the widget. This is the case, if the
error view sniipet was created from an invariants validation error.
- Bug: The table-form template did not properly render the error at the
widget, because the ``render()`` method was not called. Thanks to Markus
Leist for the report.
1.2.0 (2007-07-18)
------------------
- Feature: The row div element now also has an id of the form
"-row".
1.1.1 (2007-07-04)
------------------
- Refactoring: Split up registrations for simpler management of UI
components. This also makes it easier to see for developers how to create a
new template for forms.
1.1.0 (2007-06-29)
------------------
- Feature: Registered all defined macros for each form template. Also, added
more slots to the templates providing more hooks for customization.
- Feature: Added a macro/slot for the "required info", which explains how
required fields are marked.
- Feature: Added support for form labels.
- Feature: Added support for groups to templates.
1.0.1 (2007-06-22)
------------------
- Bug: Make sure we use the id for the "for" attribute of the "label"
element and not the name. This has worked until recently, because the
name and id were the same, but they are different now.
1.0.0 (2007-05-24)
------------------
- Initial Release
z3c.formui-2.3.0/LICENSE.txt 0000664 0001750 0001750 00000004026 11730354336 015577 0 ustar srichter srichter Zope Public License (ZPL) Version 2.1
A copyright notice accompanies this license document that identifies the
copyright holders.
This license has been certified as open source. It has also been designated as
GPL compatible by the Free Software Foundation (FSF).
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions in source code must retain the accompanying copyright
notice, this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the accompanying copyright
notice, this list of conditions, and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Names of the copyright holders must not be used to endorse or promote
products derived from this software without prior written permission from the
copyright holders.
4. The right to distribute this software or to use it for any purpose does not
give you the right to use Servicemarks (sm) or Trademarks (tm) of the
copyright
holders. Use of them is covered by separate agreement with the copyright
holders.
5. If any files are modified, you must cause the modified files to carry
prominent notices stating that you changed the files and the date of any
change.
Disclaimer
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESSED
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
z3c.formui-2.3.0/setup.py 0000664 0001750 0001750 00000004343 11730447626 015475 0 ustar srichter srichter ##############################################################################
#
# 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.
#
##############################################################################
"""Setup
$Id: setup.py 124626 2012-03-15 20:22:41Z srichter $
"""
import os
from setuptools import setup, find_packages
def read(*rnames):
return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
setup (
name='z3c.formui',
version='2.3.0',
author = "Stephan Richter, Roger Ineichen and the Zope Community",
author_email = "zope-dev@zope.org",
description = "A set of initial UI components for z3c.form.",
long_description=(
read('README.txt')
+ '\n\n' +
'.. contents::'
+ '\n\n' +
read('src', 'z3c', 'formui', 'README.txt')
+ '\n\n' +
read('CHANGES.txt')
),
license = "ZPL 2.1",
keywords = "zope3 form widget",
classifiers = [
'Development Status :: 5 - Production/Stable',
'Environment :: Web Environment',
'Intended Audience :: Developers',
'License :: OSI Approved :: Zope Public License',
'Programming Language :: Python',
'Natural Language :: English',
'Operating System :: OS Independent',
'Topic :: Internet :: WWW/HTTP',
'Framework :: Zope3'],
url = 'http://pypi.python.org/pypi/z3c.formui',
packages = find_packages('src'),
include_package_data = True,
package_dir = {'':'src'},
namespace_packages = ['z3c'],
extras_require = dict(
test = ['z3c.form [test]'],
),
install_requires = [
'setuptools',
'z3c.form >= 2.2.0',
'z3c.macro',
'z3c.template',
'zope.component',
'zope.publisher',
'zope.viewlet',
],
zip_safe = False,
)
z3c.formui-2.3.0/README.txt 0000644 0001750 0001750 00000000437 11221106762 015443 0 ustar srichter srichter This package provides a set of default layouts for the ``z3c.form``
framework. In particular it provides a DIV-based and a TABLE-based layout. The
developer can use either layout by inheriting from a different base layer.
The package also has some support for layout/pagelet templates.
z3c.formui-2.3.0/buildout.cfg 0000644 0001750 0001750 00000001004 11221106762 016244 0 ustar srichter srichter [buildout]
develop = .
parts = test coverage-test coverage-report
[test]
recipe = zc.recipe.testrunner
eggs = z3c.formui [test]
environment = test-environment
[test-environment]
CHAMELEON_DEBUG = False
CHAMELEON_CACHE = False
[coverage-test]
recipe = zc.recipe.testrunner
eggs = z3c.formui [test]
defaults = ['--coverage', '../../coverage']
environment = test-environment
[coverage-report]
recipe = zc.recipe.egg
eggs = z3c.coverage
scripts = coverage=coverage-report
arguments = ('coverage', 'coverage/report')
z3c.formui-2.3.0/COPYRIGHT.txt 0000664 0001750 0001750 00000000040 11730354336 016055 0 ustar srichter srichter Zope Foundation and Contributors z3c.formui-2.3.0/AUTHOR.txt 0000644 0001750 0001750 00000000132 11221106762 015500 0 ustar srichter srichter Stephan Richter (stephan.richter gmail.com)
Roger Ineichen (roger projekt01.ch)
z3c.formui-2.3.0/src/ 0000775 0001750 0001750 00000000000 11730447640 014542 5 ustar srichter srichter z3c.formui-2.3.0/src/z3c.formui.egg-info/ 0000775 0001750 0001750 00000000000 11730447640 020233 5 ustar srichter srichter z3c.formui-2.3.0/src/z3c.formui.egg-info/PKG-INFO 0000644 0001750 0001750 00000124526 11730447640 021340 0 ustar srichter srichter Metadata-Version: 1.0
Name: z3c.formui
Version: 2.3.0
Summary: A set of initial UI components for z3c.form.
Home-page: http://pypi.python.org/pypi/z3c.formui
Author: Stephan Richter, Roger Ineichen and the Zope Community
Author-email: zope-dev@zope.org
License: ZPL 2.1
Description: This package provides a set of default layouts for the ``z3c.form``
framework. In particular it provides a DIV-based and a TABLE-based layout. The
developer can use either layout by inheriting from a different base layer.
The package also has some support for layout/pagelet templates.
.. contents::
====================
Form User Interfaces
====================
This package provides several useful templates to get a quick start with the
``z3c.form`` package. Previous form frameworks always included default
templates that were implemented in a particular user-interface development
pattern. If you wanted to use an alternative strategy to develop user
interfaces, it was often tedious to do so. This package aims to provide some
options without requiring them for the basic framework.
Layout Template Support
-----------------------
One common pattern in Zope 3 user interface development is the use of layout
templates (see z3c.template). This package provides some mixin classes to the
regular form classes to support layout-based templating.
>>> from z3c.form import testing
>>> testing.setupFormDefaults()
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 advanced 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('''
...
...
... content
...
...
... ''')
>>> 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.__class__.__name__
'ViewPageTemplateFile'
>>> os.path.basename(layout.filename)
'myLayout.pt'
DIV-based Layout
----------------
Let's now render the page. Note the output doesn't contain the layout template:
>>> addForm.update()
>>> print addForm.render()
But we can call our form which uses the new layout template which renders
the form within the div-form content template:
>>> print addForm()
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()
`AddForm` rendering for `IAdding`
---------------------------------
The `z3c.formui` package also provides a layout-aware version of
`z3c.form.adding.AddForm` which can be used for creating forms for the
`zope.app.container.interfaces.IAdding` mechanism.
Let's check its template support. First, create the form for an `Adding`
instance. We just need to define the ``create()`` method, because the default
``add()`` and ``nextURL()`` methods are already defined using the `Adding`
object.
>>> from z3c.formui import adding
>>> class AddingPersonAddForm(adding.AddForm):
...
... fields = field.Fields(IPerson)
...
... def create(self, data):
... return Person(**data)
Let's now instantiate the adding component and the add form:
>>> from zope.app.container.browser.adding import Adding
>>> rootAdding = Adding(root, divRequest)
>>> addForm = AddingPersonAddForm(rootAdding, divRequest)
First, let's ensure that we can lookup a layout template for the form:
>>> layout = zope.component.getMultiAdapter(
... (addForm, divRequest), ILayoutTemplate)
>>> layout.__class__.__name__
'ViewPageTemplateFile'
Okay, that worked. Let's now render the div-based addform:
>>> print addForm()
Okay, now we are going to check table layout support.
>>> rootAdding = Adding(root, tableRequest)
>>> addForm = AddingPersonAddForm(rootAdding, tableRequest)
Again, the layout should be available:
>>> layout = zope.component.getMultiAdapter((addForm, tableRequest),
... ILayoutTemplate)
>>> layout.__class__.__name__
'ViewPageTemplateFile'
Let's now render the form:
>>> print addForm()
Form Macros
-----------
Load the configuration, which will make sure that all macros get registered
correctly:
>>> from zope.configuration import xmlconfig
>>> import zope.component
>>> import zope.viewlet
>>> import zope.app.component
>>> import zope.app.publisher.browser
>>> import z3c.macro
>>> import z3c.template
>>> import z3c.formui
>>> xmlconfig.XMLConfig('meta.zcml', zope.component)()
>>> xmlconfig.XMLConfig('meta.zcml', zope.viewlet)()
>>> xmlconfig.XMLConfig('meta.zcml', zope.app.component)()
>>> xmlconfig.XMLConfig('meta.zcml', zope.app.publisher.browser)()
>>> xmlconfig.XMLConfig('meta.zcml', z3c.macro)()
>>> xmlconfig.XMLConfig('meta.zcml', z3c.template)()
>>> xmlconfig.XMLConfig('configure.zcml', z3c.formui)()
Div IContentTemplate
--------------------
Create some dummy form discriminators for calling div layout templates and
macros and check the div IContentTemplates:
>>> objects = (addForm, divRequest)
>>> zope.component.getMultiAdapter(objects, IContentTemplate).filename
'...div-form.pt'
>>> objects = (form.DisplayForm(None, None), divRequest)
>>> zope.component.getMultiAdapter(objects, IContentTemplate, '').filename
'...div-form-display.pt'
We offer the following named IContentTemplate:
>>> objects = (form.DisplayForm(None, None), divRequest)
>>> zope.component.getMultiAdapter(objects, IContentTemplate,
... 'display').filename
'...div-form-display.pt'
>>> objects = (form.DisplayForm(None, None), divRequest)
>>> zope.component.getMultiAdapter(objects, IContentTemplate,
... 'subform').filename
'...subform.pt'
Table ILayoutTemplate
---------------------
There is one generic layout template to build sub forms:
>>> objects = (form.DisplayForm(None, None), divRequest)
>>> zope.component.getMultiAdapter(objects, ILayoutTemplate,
... 'subform').filename
'...subform-layout.pt'
Div layout macros
-----------------
We have different form macros available for IInputForm:
>>> from z3c.macro.interfaces import IMacroTemplate
>>> objects = (None, addForm, divRequest)
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form')
[...div-form.pt'), ...metal:define-macro': u'form'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'subform')
[...div-form.pt'), ...define-macro': u'subform'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form-label')
[...div-form.pt'), ...define-macro': u'label'...
>>> zope.component.getMultiAdapter(
... objects, IMacroTemplate, 'form-required-info')
[...div-form.pt'), ...define-macro', u'required-info'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form-header')
[...div-form.pt'), ...define-macro': u'header'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form-errors')
[...div-form.pt'), ...define-macro': u'errors'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'widget-rows')
[...div-form.pt'), ...define-macro': u'widget-rows'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'widget-row')
[...div-form.pt'), ...define-macro': u'widget-row'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form-groups')
[...div-form.pt'), ...define-macro': u'groups'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form-buttons')
[...div-form.pt'), ...define-macro', u'buttons'...
And we have different form macros available for IDisplayForm:
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'subform-display')
[...div-form-display.pt'), ...define-macro': u'subform-display'...
Table IContentTemplate
----------------------
Create some dummy form discriminators for calling table layout templates and
macros and check the div IContentTemplates:
>>> objects = (addForm, tableRequest)
>>> zope.component.getMultiAdapter(objects, IContentTemplate, '').filename
'...table-form.pt'
>>> objects = (form.DisplayForm(None, None), tableRequest)
>>> zope.component.getMultiAdapter(objects, IContentTemplate, '').filename
'...table-form-display.pt'
We offer the following named IContentTemplate:
>>> objects = (form.DisplayForm(None, None), tableRequest)
>>> zope.component.getMultiAdapter(objects, IContentTemplate,
... 'display').filename
'...table-form-display.pt'
>>> objects = (form.DisplayForm(None, None), tableRequest)
>>> zope.component.getMultiAdapter(objects, IContentTemplate,
... 'subform').filename
'...subform.pt'
Table ILayoutTemplate
---------------------
There is one generic layout template to build sub forms:
>>> objects = (form.DisplayForm(None, None), tableRequest)
>>> zope.component.getMultiAdapter(objects, ILayoutTemplate,
... 'subform').filename
'...subform-layout.pt'
Table layout macros
-------------------
We have different form macros available for IInputForm:
>>> objects = (None, addForm, tableRequest)
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form')
[...table-form.pt'), ...metal:define-macro': u'form'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'subform')
[...table-form.pt'), ...define-macro': u'subform'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form-label')
[...table-form.pt'), ...define-macro': u'label'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form-required-info')
[...table-form.pt'), ...define-macro', u'required-info'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form-header')
[...table-form.pt'), ...define-macro': u'header'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form-errors')
[...table-form.pt'), ...define-macro': u'errors'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form-table')
[...table-form.pt'), ...define-macro', u'formtable'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form-row')
[...table-form.pt'), ...define-macro': u'formrow'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form-label-cell')
[...table-form.pt'), ...define-macro', u'labelcell'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form-widget-cell')
[...table-form.pt'), ...define-macro', u'widgetcell'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form-groups')
[...table-form.pt'), ...define-macro': u'groups'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form-buttons')
[...table-form.pt'), ...define-macro', u'buttons'...
And we have different form macros available for IDisplayForm:
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'subform-display')
[...table-form-display.pt'), ...define-macro': u'subform-display'...
Subform
-------
Let's give a quick overview how subform content and layout templates get used:
First define a new form which uses the template getter methods offered
from z3.template
>>> from z3c.template.template import getPageTemplate
>>> from z3c.template.template import getLayoutTemplate
The ``provider`` TALES expression which is a part of the lookup concept
was already registered by the testing setup, so we don't need to do it
here.
and the TALES expression called ``macro`` which can lookup our macro adapters.
Yes, macros are adapters in our content/layout template concept. See z3c.macro
for more information about the implementation. However, we already registered
the ``macro`` type in the testing setup, as it's needed for rendering form
templates.
and at least we need a pagelet
renderer. By default we use the provider called ``PageletRenderer`` defined
in the z3c.pagelet package. But right now, we don't have a dependency on
this package. So let's implement a simple renderer and use them as a
IContentProvider:
>>> class PageletRenderer(object):
... zope.component.adapts(zope.interface.Interface,
... zope.publisher.interfaces.browser.IBrowserRequest,
... zope.interface.Interface)
...
... def __init__(self, context, request, pagelet):
... self.__updated = False
... self.__parent__ = pagelet
... self.context = context
... self.request = request
...
... def update(self):
... pass
...
... def render(self):
... return self.__parent__.render()
>>> from zope.contentprovider.interfaces import IContentProvider
>>> zope.component.provideAdapter(PageletRenderer,
... provides=IContentProvider, name='pagelet')
Now define the form:
>>> class PersonEditForm(form.EditForm):
... """Edit form including layout support. See z3c.formui.form."""
...
... template = getPageTemplate('subform')
... layout = getLayoutTemplate('subform')
...
... fields = field.Fields(IPerson)
Now we can render the form with our previous created person instance:
>>> person = Person(u'Jessy', 6)
>>> editForm = PersonEditForm(person, divRequest)
Now we call the form which will update and render it:
>>> print editForm()
You can see that the form above is a real subform. It doesn't define the form
tag which makes it usable as a subform in parent forms.
Of course this works with table layout based forms too. Let's use our table
request and render the form again:
>>> editForm = PersonEditForm(person, tableRequest)
>>> print editForm()
Redirection
-----------
The form doesn't bother rendering itself and its layout when
request is a redirection as the rendering doesn't make any sense with
browser requests in that case. Let's create a view that does a
redirection in its update method:
>>> class RedirectingView(PersonEditForm):
... def update(self):
... super(RedirectingView, self).update()
... self.request.response.redirect('.')
It will return an empty string when called as a browser page.
>>> redirectView = RedirectingView(person, divRequest)
>>> redirectView() == ''
True
However, the ``render`` method will render form's template as usual:
>>> '' in redirectView.render()
True
The same thing should work for AddForms:
>>> class RedirectingAddView(PersonAddForm):
... def update(self):
... super(RedirectingAddView, self).update()
... self.request.response.redirect('.')
>>> redirectView = RedirectingAddView(person, divRequest)
>>> redirectView() == ''
True
No required fields
------------------
If there no required fields in the form, standard templates won't render
the "required-info" hint.
>>> class IAdditionalInfo(zope.interface.Interface):
...
... location = zope.schema.TextLine(title=u'Location', required=False)
... about = zope.schema.Text(title=u'About', required=False)
>>> class AdditionalInfoForm(form.AddForm):
...
... fields = field.Fields(IAdditionalInfo)
>>> additionalInfoForm = AdditionalInfoForm(root, divRequest)
>>> additionalInfoForm.update()
>>> '
' in additionalInfoForm.render()
False
>>> additionalInfoForm = AdditionalInfoForm(root, tableRequest)
>>> additionalInfoForm.update()
>>> '
' in additionalInfoForm.render()
False
Cleanup
-------
>>> import shutil
>>> shutil.rmtree(temp_dir)
=======
CHANGES
=======
2.3.0 (2012-03-15)
------------------
- Feature: Mark a widget row with the "required" class when the widget is
required. Similarly, when the widget has an error attached, add the "error"
class to the widget row. That allows you to change the styles of the label
and the widget if it is reuqired.
2.2.1 (2012-01-09)
------------------
- No longer using deprecated ``zope.testing.doctest`` but built-in
``doctest`` instead.
- Fixed tests so they do not break for `z3c.form` 2.5.0.
2.2.0 (2009-12-28)
------------------
- Fixed tests so they do not break for `z3c.form` 2.2.0.
- Using ``requiredInfo`` property (introduced in `z3c.form` 2.0.0) to
render the information about required fields. This property returns
an i18n message id making the information translateable.
- Added support for groups containing groups: They get displayed now.
2.1.0 (2009-09-01)
------------------
- Feature: Don't show required info hint if there's no required fields.
- Bug: Don't render add forms when redirecting as well.
- Bug: Fix redirection tests with newer zope.publisher that restricts
untrusted redirects to different domains.
2.0.0 (2009-06-14)
------------------
- Feature: Added support for context-specific template lookup, introduced in
`z3c.template` 1.2.0 - templates can now be registered using (view, request,
context) discriminator.
- Feature: Added support for `z3c.pt` templates using `z3c.ptcompat`
compatibility package.
- Feature: Added layout support for `IAdding` component based add forms.
- Feature: Added CSS for multi-widget which was added in `z3c.form` 2.0.0.
- Bug: Changed usage of ``template/macros/*`` to ``macro:*``, because the
first one doesn't work when we override a form template and use the form
macro, registered with this package.
- Bug: Don't do rendering in form's `__call__` method when request is a
redirection.
- Bug: Reformatted long-description to render properly on pypi.
1.4.2 (2008-08-26)
------------------
- Bug: Corrected typos and unwanted unicode characters.
1.4.1 (2008-01-23)
------------------
- Bug: Fixed up meta-data and the release.
1.4.0 (2008-01-21)
------------------
- Feature: Added subform content and layout template. This allows you to
configure real sub forms which do not render the form tag.
- Feature: Improve layout implementation, support built-in layout templates.
- Feature: Use ``IContentTemplate`` instead of ``IPageTemplate`` in layout
base classes. This will help to prevent running into recursion errors if
there is a missing layout template.
- Feature: Added form module which offers built-in layout support.
- Bug: Added missing display ``IContentTemplate``, otherwise we can run into a
recursion in some cases.
- Bug: Renamed table macro argument from ``form-required-info`` to
``required-info``. The macro ``form-required-info`` did not exist.
- Bug: Added unit tests for layout support.
- Bug: Added tests for layout macros.
- Bug: Added tests for layout templates.
1.3.0 (2007-08-24)
------------------
- Refactoring: Update CSS classes to reflect latest changes to the widget
classes in ``z3c.form``.
- Bug: Error view snippets may have a empty ``widget`` attribute values, so we
cannot rely on accessing the label of the widget. This is the case, if the
error view sniipet was created from an invariants validation error.
- Bug: The table-form template did not properly render the error at the
widget, because the ``render()`` method was not called. Thanks to Markus
Leist for the report.
1.2.0 (2007-07-18)
------------------
- Feature: The row div element now also has an id of the form
"
-row".
1.1.1 (2007-07-04)
------------------
- Refactoring: Split up registrations for simpler management of UI
components. This also makes it easier to see for developers how to create a
new template for forms.
1.1.0 (2007-06-29)
------------------
- Feature: Registered all defined macros for each form template. Also, added
more slots to the templates providing more hooks for customization.
- Feature: Added a macro/slot for the "required info", which explains how
required fields are marked.
- Feature: Added support for form labels.
- Feature: Added support for groups to templates.
1.0.1 (2007-06-22)
------------------
- Bug: Make sure we use the id for the "for" attribute of the "label"
element and not the name. This has worked until recently, because the
name and id were the same, but they are different now.
1.0.0 (2007-05-24)
------------------
- Initial Release
Keywords: zope3 form widget
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Web Environment
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Zope Public License
Classifier: Programming Language :: Python
Classifier: Natural Language :: English
Classifier: Operating System :: OS Independent
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Framework :: Zope3
z3c.formui-2.3.0/src/z3c.formui.egg-info/dependency_links.txt 0000644 0001750 0001750 00000000001 11730447640 024277 0 ustar srichter srichter
z3c.formui-2.3.0/src/z3c.formui.egg-info/namespace_packages.txt 0000644 0001750 0001750 00000000004 11730447640 024556 0 ustar srichter srichter z3c
z3c.formui-2.3.0/src/z3c.formui.egg-info/not-zip-safe 0000644 0001750 0001750 00000000001 11221106762 022447 0 ustar srichter srichter
z3c.formui-2.3.0/src/z3c.formui.egg-info/SOURCES.txt 0000644 0001750 0001750 00000001637 11730447640 022124 0 ustar srichter srichter AUTHOR.txt
CHANGES.txt
COPYRIGHT.txt
LICENSE.txt
README.txt
bootstrap.py
buildout.cfg
setup.py
src/z3c/__init__.py
src/z3c.formui.egg-info/PKG-INFO
src/z3c.formui.egg-info/SOURCES.txt
src/z3c.formui.egg-info/dependency_links.txt
src/z3c.formui.egg-info/namespace_packages.txt
src/z3c.formui.egg-info/not-zip-safe
src/z3c.formui.egg-info/requires.txt
src/z3c.formui.egg-info/top_level.txt
src/z3c/formui/README.txt
src/z3c/formui/__init__.py
src/z3c/formui/adding.py
src/z3c/formui/browser.py
src/z3c/formui/configure.zcml
src/z3c/formui/div-form-display.pt
src/z3c/formui/div-form.css
src/z3c/formui/div-form.pt
src/z3c/formui/div-form.zcml
src/z3c/formui/form.py
src/z3c/formui/interfaces.py
src/z3c/formui/layout.py
src/z3c/formui/subform-layout.pt
src/z3c/formui/subform.pt
src/z3c/formui/table-form-display.pt
src/z3c/formui/table-form.css
src/z3c/formui/table-form.pt
src/z3c/formui/table-form.zcml
src/z3c/formui/tests.py z3c.formui-2.3.0/src/z3c.formui.egg-info/requires.txt 0000644 0001750 0001750 00000000166 11730447640 022634 0 ustar srichter srichter setuptools
z3c.form >= 2.2.0
z3c.macro
z3c.template
zope.component
zope.publisher
zope.viewlet
[test]
z3c.form [test] z3c.formui-2.3.0/src/z3c.formui.egg-info/top_level.txt 0000644 0001750 0001750 00000000004 11730447640 022755 0 ustar srichter srichter z3c
z3c.formui-2.3.0/src/z3c/ 0000775 0001750 0001750 00000000000 11730447640 015241 5 ustar srichter srichter z3c.formui-2.3.0/src/z3c/__init__.py 0000644 0001750 0001750 00000000254 11221106762 017341 0 ustar srichter srichter try:
# Declare this a namespace package if pkg_resources is available.
import pkg_resources
pkg_resources.declare_namespace('z3c')
except ImportError:
pass
z3c.formui-2.3.0/src/z3c/formui/ 0000775 0001750 0001750 00000000000 11730447640 016542 5 ustar srichter srichter z3c.formui-2.3.0/src/z3c/formui/__init__.py 0000644 0001750 0001750 00000000022 11221106762 020633 0 ustar srichter srichter # Make a package.
z3c.formui-2.3.0/src/z3c/formui/adding.py 0000664 0001750 0001750 00000002001 11730356271 020332 0 ustar srichter srichter ##############################################################################
#
# Copyright (c) 2008 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.
#
##############################################################################
"""Implementation of layout-aware addform for IAdding
$Id: adding.py 90626 2008-08-31 05:08:26Z srichter $
"""
__docformat__ = "reStructuredText"
from z3c.form import adding
from z3c.formui import form, layout
class AddForm(form.ContentTemplateMixin, layout.AddFormLayoutSupport,
adding.AddForm):
"""Layout aware add form for zope.app.container.interfaces.IAdding."""
z3c.formui-2.3.0/src/z3c/formui/form.py 0000644 0001750 0001750 00000004411 11221106762 020045 0 ustar srichter srichter ##############################################################################
#
# 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"
import zope.component
from z3c.form import form
from z3c.formui import layout
from z3c.template.interfaces import IContentTemplate
# offer built in layout support
extends = form.extends
applyChanges = form.applyChanges
class ContentTemplateMixin(object):
"""Use IContentTemplate instead of IPageTemplate.
This prevents us running into a recusrion because of mess up layout and
content templates. This is the default template interface if you use the
z3c.template directive.
"""
def render(self):
'''See interfaces.IForm'''
# render content template
if self.template is None:
template = zope.component.queryMultiAdapter(
(self, self.request, self.context),
IContentTemplate)
if template is None:
template = zope.component.getMultiAdapter(
(self, self.request), IContentTemplate)
return template(self)
return self.template()
class BaseForm(ContentTemplateMixin, layout.FormLayoutSupport, form.BaseForm):
"""Layout aware base form."""
class DisplayForm(ContentTemplateMixin, layout.FormLayoutSupport,
form.DisplayForm):
"""Layout aware display form."""
class Form(ContentTemplateMixin, layout.FormLayoutSupport, form.Form):
"""Layout aware form."""
class AddForm(ContentTemplateMixin, layout.AddFormLayoutSupport, form.AddForm):
"""Layout aware add form."""
class EditForm(ContentTemplateMixin, layout.FormLayoutSupport, form.EditForm):
"""Layout aware edit form."""
z3c.formui-2.3.0/src/z3c/formui/table-form.css 0000644 0001750 0001750 00000003224 11221106762 021273 0 ustar srichter srichter /*----[ table based form tags ]----------------------------------------------*/
form.edit-form {
margin: 0px;
padding: 0px;
}
form.edit-form td {
vertical-align: top;
padding-bottom: 10px;
}
form.edit-form td.label {
margin: 0px;
padding-top: 5px;
}
div.viewspace {
margin: 0px;
padding: 0px;
}
div.status {
padding-bottom: 10px;
}
div.summary {
margin: 0px;
padding: 0px;
}
ul.errors {
padding: 0px;
color: red;
margin-left: 20px;
}
div.error {
margin: 0px;
padding: 0px;
}
div.required-info span.required, td.label span.required {
color: red;
}
div.widget {
margin: 0px;
padding: 0px;
}
input, textarea, select {
margin: 0px;
padding: 0px;
border: 1px solid gray;
}
input.file-widget {
width: 300px;
}
input.checkbox-widget {
border: none;
}
input.password-widget {
width: 300px;
}
input.radio-widget {
border: none;
}
select.select-widget {
width: 300px;
border: 1px solid gray;
}
input.text-widget {
width: 300px;
}
textarea.textarea-widget {
width: 300px;
height: 100px;
}
div.buttons {
padding: 10px 0px 10px 0px;
}
/*---[ multi widget ]--------------------------------------------------------*/
div.multi-widget div.multi-widget-checkbox {
float: left
}
div.multi-widget div.label {
margin: 0px;
padding: 0px;
padding: 0px 0px 00px 20px;
}
div.multi-widget input.password-widget {
width: 280px;
}
div.multi-widget input.text-widget {
width: 280px;
}
div.multi-widget textarea.textarea-widget {
width: 280px;
height: 100px;
}
div.multi-widget div.buttons {
padding: 0px 0px 10px 20px;
}
z3c.formui-2.3.0/src/z3c/formui/interfaces.py 0000644 0001750 0001750 00000002306 11221106762 021226 0 ustar srichter srichter ##############################################################################
#
# 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 Interfaces
$Id: interfaces.py 75941 2007-05-24 14:48:22Z srichter $
"""
__docformat__ = "reStructuredText"
from zope.publisher.interfaces.browser import IBrowserRequest
from zope.viewlet.interfaces import IViewletManager
class IFormUILayer(IBrowserRequest):
"""A basic layer for the Form UI package."""
class IDivFormLayer(IFormUILayer):
"""A layer that supports forms created only using DIV elements."""
class ITableFormLayer(IFormUILayer):
"""A layer that supports forms created using tables."""
class ICSS(IViewletManager):
"""CSS viewlet manager."""
z3c.formui-2.3.0/src/z3c/formui/div-form.zcml 0000644 0001750 0001750 00000005645 11221106762 021154 0 ustar srichter srichter
z3c.formui-2.3.0/src/z3c/formui/layout.py 0000664 0001750 0001750 00000004453 11730354336 020436 0 ustar srichter srichter ##############################################################################
#
# Copyright (c) 2007-2009 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.
#
##############################################################################
"""Support for Layout Templates
$Id: layout.py 103001 2009-08-20 11:38:09Z nadako $
"""
__docformat__ = "reStructuredText"
import zope.component
from z3c.template.interfaces import ILayoutTemplate
REDIRECT_STATUS_CODES = (301, 302, 303)
class FormLayoutSupport(object):
"""Layout support for forms except IAddForm."""
layout = None
def __call__(self):
self.update()
if self.request.response.getStatus() in REDIRECT_STATUS_CODES:
# don't bother rendering when redirecting
return ''
if self.layout is None:
layout = zope.component.queryMultiAdapter(
(self, self.request, self.context),
ILayoutTemplate)
if 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 ''
if self.request.response.getStatus() in REDIRECT_STATUS_CODES:
# don't bother rendering when redirecting
return ''
if self.layout is None:
layout = zope.component.queryMultiAdapter(
(self, self.request, self.context),
ILayoutTemplate)
if layout is None:
layout = zope.component.getMultiAdapter(
(self, self.request), ILayoutTemplate)
return layout(self)
return self.layout()
z3c.formui-2.3.0/src/z3c/formui/div-form-display.pt 0000644 0001750 0001750 00000004202 11221106762 022261 0 ustar srichter srichter
z3c.formui-2.3.0/src/z3c/formui/div-form.pt 0000664 0001750 0001750 00000010634 11730446751 020640 0 ustar srichter srichter
z3c.formui-2.3.0/src/z3c/formui/subform.pt 0000644 0001750 0001750 00000000050 11221106762 020545 0 ustar srichter srichter
z3c.formui-2.3.0/src/z3c/formui/README.txt 0000664 0001750 0001750 00000070562 11730356216 020250 0 ustar srichter srichter ====================
Form User Interfaces
====================
This package provides several useful templates to get a quick start with the
``z3c.form`` package. Previous form frameworks always included default
templates that were implemented in a particular user-interface development
pattern. If you wanted to use an alternative strategy to develop user
interfaces, it was often tedious to do so. This package aims to provide some
options without requiring them for the basic framework.
Layout Template Support
-----------------------
One common pattern in Zope 3 user interface development is the use of layout
templates (see z3c.template). This package provides some mixin classes to the
regular form classes to support layout-based templating.
>>> from z3c.form import testing
>>> testing.setupFormDefaults()
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 advanced 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('''
...
...
... content
...
...
... ''')
>>> 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.__class__.__name__
'ViewPageTemplateFile'
>>> os.path.basename(layout.filename)
'myLayout.pt'
DIV-based Layout
----------------
Let's now render the page. Note the output doesn't contain the layout template:
>>> addForm.update()
>>> print addForm.render()
But we can call our form which uses the new layout template which renders
the form within the div-form content template:
>>> print addForm()
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()
`AddForm` rendering for `IAdding`
---------------------------------
The `z3c.formui` package also provides a layout-aware version of
`z3c.form.adding.AddForm` which can be used for creating forms for the
`zope.app.container.interfaces.IAdding` mechanism.
Let's check its template support. First, create the form for an `Adding`
instance. We just need to define the ``create()`` method, because the default
``add()`` and ``nextURL()`` methods are already defined using the `Adding`
object.
>>> from z3c.formui import adding
>>> class AddingPersonAddForm(adding.AddForm):
...
... fields = field.Fields(IPerson)
...
... def create(self, data):
... return Person(**data)
Let's now instantiate the adding component and the add form:
>>> from zope.app.container.browser.adding import Adding
>>> rootAdding = Adding(root, divRequest)
>>> addForm = AddingPersonAddForm(rootAdding, divRequest)
First, let's ensure that we can lookup a layout template for the form:
>>> layout = zope.component.getMultiAdapter(
... (addForm, divRequest), ILayoutTemplate)
>>> layout.__class__.__name__
'ViewPageTemplateFile'
Okay, that worked. Let's now render the div-based addform:
>>> print addForm()
Okay, now we are going to check table layout support.
>>> rootAdding = Adding(root, tableRequest)
>>> addForm = AddingPersonAddForm(rootAdding, tableRequest)
Again, the layout should be available:
>>> layout = zope.component.getMultiAdapter((addForm, tableRequest),
... ILayoutTemplate)
>>> layout.__class__.__name__
'ViewPageTemplateFile'
Let's now render the form:
>>> print addForm()
Form Macros
-----------
Load the configuration, which will make sure that all macros get registered
correctly:
>>> from zope.configuration import xmlconfig
>>> import zope.component
>>> import zope.viewlet
>>> import zope.app.component
>>> import zope.app.publisher.browser
>>> import z3c.macro
>>> import z3c.template
>>> import z3c.formui
>>> xmlconfig.XMLConfig('meta.zcml', zope.component)()
>>> xmlconfig.XMLConfig('meta.zcml', zope.viewlet)()
>>> xmlconfig.XMLConfig('meta.zcml', zope.app.component)()
>>> xmlconfig.XMLConfig('meta.zcml', zope.app.publisher.browser)()
>>> xmlconfig.XMLConfig('meta.zcml', z3c.macro)()
>>> xmlconfig.XMLConfig('meta.zcml', z3c.template)()
>>> xmlconfig.XMLConfig('configure.zcml', z3c.formui)()
Div IContentTemplate
--------------------
Create some dummy form discriminators for calling div layout templates and
macros and check the div IContentTemplates:
>>> objects = (addForm, divRequest)
>>> zope.component.getMultiAdapter(objects, IContentTemplate).filename
'...div-form.pt'
>>> objects = (form.DisplayForm(None, None), divRequest)
>>> zope.component.getMultiAdapter(objects, IContentTemplate, '').filename
'...div-form-display.pt'
We offer the following named IContentTemplate:
>>> objects = (form.DisplayForm(None, None), divRequest)
>>> zope.component.getMultiAdapter(objects, IContentTemplate,
... 'display').filename
'...div-form-display.pt'
>>> objects = (form.DisplayForm(None, None), divRequest)
>>> zope.component.getMultiAdapter(objects, IContentTemplate,
... 'subform').filename
'...subform.pt'
Table ILayoutTemplate
---------------------
There is one generic layout template to build sub forms:
>>> objects = (form.DisplayForm(None, None), divRequest)
>>> zope.component.getMultiAdapter(objects, ILayoutTemplate,
... 'subform').filename
'...subform-layout.pt'
Div layout macros
-----------------
We have different form macros available for IInputForm:
>>> from z3c.macro.interfaces import IMacroTemplate
>>> objects = (None, addForm, divRequest)
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form')
[...div-form.pt'), ...metal:define-macro': u'form'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'subform')
[...div-form.pt'), ...define-macro': u'subform'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form-label')
[...div-form.pt'), ...define-macro': u'label'...
>>> zope.component.getMultiAdapter(
... objects, IMacroTemplate, 'form-required-info')
[...div-form.pt'), ...define-macro', u'required-info'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form-header')
[...div-form.pt'), ...define-macro': u'header'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form-errors')
[...div-form.pt'), ...define-macro': u'errors'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'widget-rows')
[...div-form.pt'), ...define-macro': u'widget-rows'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'widget-row')
[...div-form.pt'), ...define-macro': u'widget-row'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form-groups')
[...div-form.pt'), ...define-macro': u'groups'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form-buttons')
[...div-form.pt'), ...define-macro', u'buttons'...
And we have different form macros available for IDisplayForm:
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'subform-display')
[...div-form-display.pt'), ...define-macro': u'subform-display'...
Table IContentTemplate
----------------------
Create some dummy form discriminators for calling table layout templates and
macros and check the div IContentTemplates:
>>> objects = (addForm, tableRequest)
>>> zope.component.getMultiAdapter(objects, IContentTemplate, '').filename
'...table-form.pt'
>>> objects = (form.DisplayForm(None, None), tableRequest)
>>> zope.component.getMultiAdapter(objects, IContentTemplate, '').filename
'...table-form-display.pt'
We offer the following named IContentTemplate:
>>> objects = (form.DisplayForm(None, None), tableRequest)
>>> zope.component.getMultiAdapter(objects, IContentTemplate,
... 'display').filename
'...table-form-display.pt'
>>> objects = (form.DisplayForm(None, None), tableRequest)
>>> zope.component.getMultiAdapter(objects, IContentTemplate,
... 'subform').filename
'...subform.pt'
Table ILayoutTemplate
---------------------
There is one generic layout template to build sub forms:
>>> objects = (form.DisplayForm(None, None), tableRequest)
>>> zope.component.getMultiAdapter(objects, ILayoutTemplate,
... 'subform').filename
'...subform-layout.pt'
Table layout macros
-------------------
We have different form macros available for IInputForm:
>>> objects = (None, addForm, tableRequest)
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form')
[...table-form.pt'), ...metal:define-macro': u'form'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'subform')
[...table-form.pt'), ...define-macro': u'subform'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form-label')
[...table-form.pt'), ...define-macro': u'label'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form-required-info')
[...table-form.pt'), ...define-macro', u'required-info'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form-header')
[...table-form.pt'), ...define-macro': u'header'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form-errors')
[...table-form.pt'), ...define-macro': u'errors'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form-table')
[...table-form.pt'), ...define-macro', u'formtable'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form-row')
[...table-form.pt'), ...define-macro': u'formrow'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form-label-cell')
[...table-form.pt'), ...define-macro', u'labelcell'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form-widget-cell')
[...table-form.pt'), ...define-macro', u'widgetcell'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form-groups')
[...table-form.pt'), ...define-macro': u'groups'...
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form-buttons')
[...table-form.pt'), ...define-macro', u'buttons'...
And we have different form macros available for IDisplayForm:
>>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'subform-display')
[...table-form-display.pt'), ...define-macro': u'subform-display'...
Subform
-------
Let's give a quick overview how subform content and layout templates get used:
First define a new form which uses the template getter methods offered
from z3.template
>>> from z3c.template.template import getPageTemplate
>>> from z3c.template.template import getLayoutTemplate
The ``provider`` TALES expression which is a part of the lookup concept
was already registered by the testing setup, so we don't need to do it
here.
and the TALES expression called ``macro`` which can lookup our macro adapters.
Yes, macros are adapters in our content/layout template concept. See z3c.macro
for more information about the implementation. However, we already registered
the ``macro`` type in the testing setup, as it's needed for rendering form
templates.
and at least we need a pagelet
renderer. By default we use the provider called ``PageletRenderer`` defined
in the z3c.pagelet package. But right now, we don't have a dependency on
this package. So let's implement a simple renderer and use them as a
IContentProvider:
>>> class PageletRenderer(object):
... zope.component.adapts(zope.interface.Interface,
... zope.publisher.interfaces.browser.IBrowserRequest,
... zope.interface.Interface)
...
... def __init__(self, context, request, pagelet):
... self.__updated = False
... self.__parent__ = pagelet
... self.context = context
... self.request = request
...
... def update(self):
... pass
...
... def render(self):
... return self.__parent__.render()
>>> from zope.contentprovider.interfaces import IContentProvider
>>> zope.component.provideAdapter(PageletRenderer,
... provides=IContentProvider, name='pagelet')
Now define the form:
>>> class PersonEditForm(form.EditForm):
... """Edit form including layout support. See z3c.formui.form."""
...
... template = getPageTemplate('subform')
... layout = getLayoutTemplate('subform')
...
... fields = field.Fields(IPerson)
Now we can render the form with our previous created person instance:
>>> person = Person(u'Jessy', 6)
>>> editForm = PersonEditForm(person, divRequest)
Now we call the form which will update and render it:
>>> print editForm()
You can see that the form above is a real subform. It doesn't define the form
tag which makes it usable as a subform in parent forms.
Of course this works with table layout based forms too. Let's use our table
request and render the form again:
>>> editForm = PersonEditForm(person, tableRequest)
>>> print editForm()
Redirection
-----------
The form doesn't bother rendering itself and its layout when
request is a redirection as the rendering doesn't make any sense with
browser requests in that case. Let's create a view that does a
redirection in its update method:
>>> class RedirectingView(PersonEditForm):
... def update(self):
... super(RedirectingView, self).update()
... self.request.response.redirect('.')
It will return an empty string when called as a browser page.
>>> redirectView = RedirectingView(person, divRequest)
>>> redirectView() == ''
True
However, the ``render`` method will render form's template as usual:
>>> '' in redirectView.render()
True
The same thing should work for AddForms:
>>> class RedirectingAddView(PersonAddForm):
... def update(self):
... super(RedirectingAddView, self).update()
... self.request.response.redirect('.')
>>> redirectView = RedirectingAddView(person, divRequest)
>>> redirectView() == ''
True
No required fields
------------------
If there no required fields in the form, standard templates won't render
the "required-info" hint.
>>> class IAdditionalInfo(zope.interface.Interface):
...
... location = zope.schema.TextLine(title=u'Location', required=False)
... about = zope.schema.Text(title=u'About', required=False)
>>> class AdditionalInfoForm(form.AddForm):
...
... fields = field.Fields(IAdditionalInfo)
>>> additionalInfoForm = AdditionalInfoForm(root, divRequest)
>>> additionalInfoForm.update()
>>> '
' in additionalInfoForm.render()
False
>>> additionalInfoForm = AdditionalInfoForm(root, tableRequest)
>>> additionalInfoForm.update()
>>> '
' in additionalInfoForm.render()
False
Cleanup
-------
>>> import shutil
>>> shutil.rmtree(temp_dir)
z3c.formui-2.3.0/src/z3c/formui/configure.zcml 0000644 0001750 0001750 00000000624 11221106762 021402 0 ustar srichter srichter
z3c.formui-2.3.0/src/z3c/formui/table-form.pt 0000664 0001750 0001750 00000012132 11730447045 021135 0 ustar srichter srichter
z3c.formui-2.3.0/src/z3c/formui/table-form.zcml 0000644 0001750 0001750 00000006421 11221106762 021452 0 ustar srichter srichter
z3c.formui-2.3.0/src/z3c/formui/table-form-display.pt 0000644 0001750 0001750 00000005147 11221106762 022577 0 ustar srichter srichter
z3c.formui-2.3.0/src/z3c/formui/tests.py 0000664 0001750 0001750 00000003422 11730354336 020256 0 ustar srichter srichter ##############################################################################
#
# Copyright (c) 2005-2009 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 doctest
import unittest
import z3c.form.outputchecker
import z3c.form.testing
def setUpZPT(test):
z3c.form.testing.setUpZPT(test)
from zope.app.pagetemplate.metaconfigure import registerType
from zope.contentprovider.tales import TALESProviderExpression
from z3c.macro.tales import MacroExpression
registerType('macro', MacroExpression)
registerType('provider', TALESProviderExpression)
def setUpZ3CPT(test):
z3c.form.testing.setUpZ3CPT(test)
from zope.component import provideUtility
from z3c.macro.tales import z3cpt_macro_expression
provideUtility(z3cpt_macro_expression, name='macro')
def test_suite():
return unittest.TestSuite([
doctest.DocFileSuite(
'README.txt',
setUp=setUp,
tearDown=z3c.form.testing.tearDown,
optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
checker=z3c.form.outputchecker.OutputChecker(doctest))
#for setUp in (setUpZPT, setUpZ3CPT)]) # XXX: broken macro tests
for setUp in (setUpZPT, )])
z3c.formui-2.3.0/src/z3c/formui/browser.py 0000644 0001750 0001750 00000001574 11221106762 020574 0 ustar srichter srichter ##############################################################################
#
# 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 zope.viewlet.viewlet import CSSViewlet
TableFormCSSViewlet = CSSViewlet('table-form.css')
DivFormCSSViewlet = CSSViewlet('div-form.css')
z3c.formui-2.3.0/src/z3c/formui/subform-layout.pt 0000644 0001750 0001750 00000000107 11221106762 022063 0 ustar srichter srichter
content