zope.app.form-4.0.2/0000755000175000017500000000000011340453341013521 5ustar sidneisidneizope.app.form-4.0.2/PKG-INFO0000644000175000017500000001641011340453341014620 0ustar sidneisidneiMetadata-Version: 1.0 Name: zope.app.form Version: 4.0.2 Summary: The Original Zope 3 Form Framework Home-page: http://pypi.python.org/pypi/zope.app.form Author: Zope Corporation and Contributors Author-email: zope-dev@zope.org License: ZPL 2.1 Description: This package provides the old form framework for Zope 3. It also implements a few high-level ZCML directives for declaring forms. More advanced alternatives are implemented in ``zope.formlib`` and ``z3c.form``. The widgets that were defined in here were moved to ``zope.formlib``. Version 4.0 and newer are maintained for backwards compatibility reasons only. Detailed documentation: ======= CHANGES ======= 4.0.2 (2010-01-22) ================== - Seems like 4.0.1 was released already. Brown bag. 4.0.1 (2010-01-08) ================== - Import 'escape' for backwards compatibility as packages turn out to be importing this too, even though it's actually from the Python standard library. - Widget documentation is now on PyPI too. 4.0 (2010-01-08) ================ - The widget implementations have been moved to zope.formlib. This makes this package depend on zope.formlib. The dependency of zope.formlib on this package has been broken. 3.12.1 (2009-12-22) =================== - Added missing zope.datetime dependency. 3.12.0 (2009-12-22) =================== - Use zope.browserpage in favor of zope.app.pagetemplate. 3.11.1 (2009-12-22) =================== - Prefer zope.testing.doctest over doctestunit and adjust test output to newer zope.schema release. 3.11.0 (2009-12-18) =================== - Use zope.component.testing in favor of zope.app.testing where possible. - Define dummy standard_macros for test purposes. This reduces the test dependencies by zope.app.basicskin and zope.browserresource. - Removed the zope.app.container and zope.app.publisher testing dependencies. - Refactored code to remove zope.app.component dependency. - Made the tests independent of zope.app.locales. - Reduce zope.app test dependencies by avoiding zope.app.securitypolicy and zope.app.zcmlfiles. 3.10.0 (2009-12-17) =================== - Avoid the ``zope.app.basicskin`` dependency, by defining our own FormMacros. 3.9.0 (2009-10-08) ================== - Internationalized 'Invalid value' used with ConversionError - Added dependency on transaction and test dependency on zope.app.component. - Moved dependencies on ZODB3 and zope.location to the test extra. - Reduced the dependency on zope.app.publisher to a dependency on zope.browsermenu plus a test dependency on zope.browserpage. 3.8.1 (2009-07-23) ================== - Fix unittest failure due to translation update. 3.8.0 (2009-05-24) ================== - Use standard properties instead of `zope.cachedescriptors`. - Require `zope.browser` 1.1 instead of `zope.app.container` for IAdding. 3.7.3 (2009-05-11) ================== - Fixed invalid markup. 3.7.2 (2009-03-12) ================== - Fixed bug where OrderedMultiSelectWidget did not respect the widgets size attribute. - Fixed bug in SequenceWidget where it crashed while trying to iterate a missing_value (None in most of cases) on _getRenderedValue. - Adapt to removal of deprecated interfaces from zope.component.interfaces. The IView was moved to zope.publisher and we use our custom IWidgetFactory interface instead of removed zope.component.interfaces.IViewFactory. - Fix tests to work on Python 2.6. 3.7.1 (2009-01-31) ================== - Adapt to the upcoming zope.schema release 3.5.1 which will also silence the spurious `set` failures. 3.7.0 (2008-12-11) ================== - use zope.browser.interfaces.ITerms instead of zope.app.form.browser.interfaces - Depending on zope.schema>=3.5a1 which uses the builtin ``set`` instead of the ``sets`` module. 3.6.4 (2008-11-26) ================== - The URIDisplayWidget doesn't render an anchor for empty/None values. 3.6.3 (2008-10-15) ================== - Get rid of deprecated usage of LayerField from zope.app.component.back35, replaced by zope.configuration.fields.GlobalInterface. 3.6.2 (2008-09-08) ================== - Fixed restructured text in doc tests to unbreak the PyPI page. (3.6.1 skipped due to a typo) 3.6.0 (2008-08-22) ================== - Dropdown widgets display an item for the missing value even if the field is required when no value is selected. See zope/app/form/browser/README.txt on how to switch this off for BBB. - Source select widgets for required fields are now required as well. They used not to be required on the assumption that some value would be selected by the browser, which had always been wrong except for dropdown widgets. 3.5.0 (2008-06-05) ================== - Translate the title on SequenceWidget's "Add " button. - No longer uses zapi. 3.4.2 (2008-02-07) ================== - Made display widgets for sources translate message IDs correctly. 3.4.1 (2007-10-31) ================== - Resolve ``ZopeSecurityPolicy`` deprecation warning. 3.4.0 (2007-10-24) ================== - ``zope.app.form`` now supports Python2.5 - Initial release independent of the main Zope tree. Before 3.4 ========== This package was part of the Zope 3 distribution and did not have its own CHANGES.txt. For earlier changes please refer to either our subversion log or the CHANGES.txt of earlier Zope 3 releases. Keywords: zope3 form widget zcml 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 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zope.app.form-4.0.2/setup.py������������������������������������������������������������������������0000644�0001750�0001750�00000006113�11340453312�015232� 0����������������������������������������������������������������������������������������������������ustar �sidnei��������������������������sidnei�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������############################################################################## # # Copyright (c) 2006 Zope Corporation 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. # ############################################################################## # This package is developed by the Zope Toolkit project, documented here: # http://docs.zope.org/zopetoolkit # When developing and releasing this package, please follow the documented # Zope Toolkit policies as described by this documentation. ############################################################################## """Setup for zope.app.form package $Id: setup.py 81002 2007-10-24 01:19:47Z 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='zope.app.form', version = '4.0.2', author='Zope Corporation and Contributors', author_email='zope-dev@zope.org', description='The Original Zope 3 Form Framework', long_description=( read('README.txt') + '\n\n' + 'Detailed documentation:\n' + '\n\n' + read('CHANGES.txt') ), keywords = "zope3 form widget zcml", 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/zope.app.form', license='ZPL 2.1', packages=find_packages('src'), package_dir = {'': 'src'}, namespace_packages=['zope', 'zope.app'], extras_require={'test': [ 'ZODB3', 'zc.sourcefactory', 'zope.container', 'zope.principalregistry', 'zope.site', 'zope.traversing', 'zope.app.appsetup', 'zope.app.publication', 'zope.app.testing', ]}, install_requires=[ "setuptools", "transaction", "zope.formlib >= 4.0", "zope.browser>=1.1", "zope.browserpage>=3.10.1", "zope.browsermenu", "zope.component", "zope.configuration", "zope.datetime", "zope.exceptions", "zope.i18n", "zope.interface", "zope.proxy", "zope.publisher", "zope.schema>=3.5.1dev", "zope.security", ], include_package_data = True, zip_safe = False, ) �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zope.app.form-4.0.2/COPYRIGHT.txt�������������������������������������������������������������������0000644�0001750�0001750�00000000712�11340453312�015630� 0����������������������������������������������������������������������������������������������������ustar �sidnei��������������������������sidnei�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Copyright (c) 2007 Zope Corporation 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. ������������������������������������������������������zope.app.form-4.0.2/setup.cfg�����������������������������������������������������������������������0000644�0001750�0001750�00000000073�11340453341�015342� 0����������������������������������������������������������������������������������������������������ustar �sidnei��������������������������sidnei�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������[egg_info] tag_build = tag_date = 0 tag_svn_revision = 0 ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zope.app.form-4.0.2/README.txt����������������������������������������������������������������������0000644�0001750�0001750�00000000551�11340453312�015216� 0����������������������������������������������������������������������������������������������������ustar �sidnei��������������������������sidnei�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������This package provides the old form framework for Zope 3. It also implements a few high-level ZCML directives for declaring forms. More advanced alternatives are implemented in ``zope.formlib`` and ``z3c.form``. The widgets that were defined in here were moved to ``zope.formlib``. Version 4.0 and newer are maintained for backwards compatibility reasons only. �������������������������������������������������������������������������������������������������������������������������������������������������������zope.app.form-4.0.2/LICENSE.txt���������������������������������������������������������������������0000644�0001750�0001750�00000004027�11340453312�015345� 0����������������������������������������������������������������������������������������������������ustar �sidnei��������������������������sidnei�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������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. ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zope.app.form-4.0.2/buildout.cfg��������������������������������������������������������������������0000644�0001750�0001750�00000000146�11340453312�016030� 0����������������������������������������������������������������������������������������������������ustar �sidnei��������������������������sidnei�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������[buildout] develop = . parts = test [test] recipe = zc.recipe.testrunner eggs = zope.app.form [test] ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zope.app.form-4.0.2/src/����������������������������������������������������������������������������0000755�0001750�0001750�00000000000�11340453341�014310� 5����������������������������������������������������������������������������������������������������ustar �sidnei��������������������������sidnei�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zope.app.form-4.0.2/src/zope/�����������������������������������������������������������������������0000755�0001750�0001750�00000000000�11340453312�015263� 5����������������������������������������������������������������������������������������������������ustar �sidnei��������������������������sidnei�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zope.app.form-4.0.2/src/zope/__init__.py������������������������������������������������������������0000644�0001750�0001750�00000000310�11340453312�017366� 0����������������������������������������������������������������������������������������������������ustar �sidnei��������������������������sidnei�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# this is a namespace package try: import pkg_resources pkg_resources.declare_namespace(__name__) except ImportError: import pkgutil __path__ = pkgutil.extend_path(__path__, __name__) ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zope.app.form-4.0.2/src/zope/app/�������������������������������������������������������������������0000755�0001750�0001750�00000000000�11340453312�016043� 5����������������������������������������������������������������������������������������������������ustar �sidnei��������������������������sidnei�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zope.app.form-4.0.2/src/zope/app/__init__.py��������������������������������������������������������0000644�0001750�0001750�00000000310�11340453312�020146� 0����������������������������������������������������������������������������������������������������ustar �sidnei��������������������������sidnei�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# this is a namespace package try: import pkg_resources pkg_resources.declare_namespace(__name__) except ImportError: import pkgutil __path__ = pkgutil.extend_path(__path__, __name__) ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zope.app.form-4.0.2/src/zope/app/form/��������������������������������������������������������������0000755�0001750�0001750�00000000000�11340453312�017006� 5����������������������������������������������������������������������������������������������������ustar �sidnei��������������������������sidnei�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zope.app.form-4.0.2/src/zope/app/form/testing.py����������������������������������������������������0000644�0001750�0001750�00000001745�11340453312�021044� 0����������������������������������������������������������������������������������������������������ustar �sidnei��������������������������sidnei�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������############################################################################## # # Copyright (c) 2007 Zope Corporation 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. # ############################################################################## """zope.app.form common test related classes/functions/objects. $Id: testing.py 72343 2007-02-03 06:04:09Z baijum $ """ __docformat__ = "reStructuredText" import os from zope.app.testing.functional import ZCMLLayer AppFormLayer = ZCMLLayer( os.path.join(os.path.split(__file__)[0], 'ftesting.zcml'), __name__, 'AppFormLayer', allow_teardown=True) ���������������������������zope.app.form-4.0.2/src/zope/app/form/utility.py����������������������������������������������������0000644�0001750�0001750�00000021247�11340453312�021071� 0����������������������������������������������������������������������������������������������������ustar �sidnei��������������������������sidnei�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������############################################################################## # # Copyright (c) 2002 Zope Corporation 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 utility functions In Zope 2's formulator, forms provide a basic mechanism for organizing collections of fields and providing user interfaces for them, especially editing interfaces. In Zope 3, formulator's forms are replaced by Schema (See zope.schema). In addition, the Formulator fields have been replaced by schema fields and form widgets. Schema fields just express the semantics of data values. They contain no presentation logic or parameters. Widgets are views on fields that take care of presentation. The widget view names represent styles that can be selected by applications to customise the presentation. There can also be custom widgets with specific parameters. This module provides some utility functions that provide some of the functionality of formulator forms that isn't handled by schema, fields, or widgets. $Id: utility.py 107385 2009-12-30 20:25:24Z faassen $ """ __docformat__ = 'restructuredtext' from zope import security from zope.security.proxy import Proxy from zope.proxy import isProxy from zope.interface.interfaces import IMethod from zope.security.interfaces import ForbiddenAttribute, Unauthorized from zope.formlib.interfaces import WidgetsError, MissingInputError from zope.formlib.interfaces import InputErrors from zope.formlib.interfaces import IInputWidget, IDisplayWidget # BBB from zope.formlib.utility import ( setUpWidget, setUpWidgets, applyWidgetsChanges, _fieldlist, no_value, _widgetHasStickyValue) def setUpEditWidgets(view, schema, source=None, prefix=None, ignoreStickyValues=False, names=None, context=None, degradeInput=False, degradeDisplay=False): """Sets up widgets to collect input on a view. See `setUpWidgets` for details on `view`, `schema`, `prefix`, `ignoreStickyValues`, `names`, and `context`. `source`, if specified, is an object from which initial widget values are read. If source is not specified, the view context is used as the source. `degradeInput` is a flag that changes the behavior when a user does not have permission to edit a field in the names. By default, the function raises Unauthorized. If degradeInput is True, the field is changed to an IDisplayWidget. `degradeDisplay` is a flag that changes the behavior when a user does not have permission to access a field in the names. By default, the function raises Unauthorized. If degradeDisplay is True, the field is removed from the form. Returns a list of names, equal to or a subset of the names that were supposed to be drawn, with uninitialized undrawn fields missing. """ if context is None: context = view.context if source is None: source = view.context security_proxied = isProxy(source, Proxy) res_names = [] for name, field in _fieldlist(names, schema): try: value = field.get(source) except ForbiddenAttribute: raise except AttributeError: value = no_value except Unauthorized: if degradeDisplay: continue else: raise if field.readonly: viewType = IDisplayWidget else: if security_proxied: is_accessor = IMethod.providedBy(field) if is_accessor: set_name = field.writer.__name__ authorized = security.canAccess(source, set_name) else: set_name = name authorized = security.canWrite(source, name) if not authorized: if degradeInput: viewType = IDisplayWidget else: raise Unauthorized(set_name) else: viewType = IInputWidget else: # if object is not security proxied, might be a standard # adapter without a registered checker. If the feature of # paying attention to the users ability to actually set a # field is decided to be a must-have for the form machinery, # then we ought to change this case to have a deprecation # warning. viewType = IInputWidget setUpWidget(view, name, field, viewType, value, prefix, ignoreStickyValues, context) res_names.append(name) return res_names def setUpDisplayWidgets(view, schema, source=None, prefix=None, ignoreStickyValues=False, names=None, context=None, degradeDisplay=False): """Sets up widgets to display field values on a view. See `setUpWidgets` for details on `view`, `schema`, `prefix`, `ignoreStickyValues`, `names`, and `context`. `source`, if specified, is an object from which initial widget values are read. If source is not specified, the view context is used as the source. `degradeDisplay` is a flag that changes the behavior when a user does not have permission to access a field in the names. By default, the function raises Unauthorized. If degradeDisplay is True, the field is removed from the form. Returns a list of names, equal to or a subset of the names that were supposed to be drawn, with uninitialized undrawn fields missing. """ if context is None: context = view.context if source is None: source = view.context res_names = [] for name, field in _fieldlist(names, schema): try: value = field.get(source) except ForbiddenAttribute: raise except AttributeError: value = no_value except Unauthorized: if degradeDisplay: continue else: raise setUpWidget(view, name, field, IDisplayWidget, value, prefix, ignoreStickyValues, context) res_names.append(name) return res_names def viewHasInput(view, schema, names=None): """Returns ``True`` if the any of the view's widgets contain user input. `schema` specifies the set of fields that correspond to the view widgets. `names` can be specified to provide a subset of these fields. """ for name, field in _fieldlist(names, schema): if getattr(view, name + '_widget').hasInput(): return True return False def getWidgetsData(view, schema, names=None): """Returns user entered data for a set of `schema` fields. The return value is a map of field names to data values. `view` is the view containing the widgets. `schema` is the schema that defines the widget fields. An optional `names` argument can be provided to specify an alternate list of field values to return. If `names` is not specified, or is ``None``, `getWidgetsData` will attempt to return values for all of the fields in the schema. A requested field value may be omitted from the result for one of two reasons: - The field is read only, in which case its widget will not have user input. - The field is editable and not required but its widget does not contain user input. If a field is required and its widget does not have input, `getWidgetsData` raises an error. A widget may raise a validation error if it cannot return a value that satisfies its field's contraints. Errors, if any, are collected for all fields and reraised as a single `WidgetsError`. """ result = {} errors = [] for name, field in _fieldlist(names, schema): widget = getattr(view, name + '_widget') if IInputWidget.providedBy(widget): if widget.hasInput(): try: result[name] = widget.getInputValue() except InputErrors, error: errors.append(error) elif field.required: errors.append(MissingInputError( name, widget.label, 'the field is required')) if errors: raise WidgetsError(errors, widgetsData=result) return result ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zope.app.form-4.0.2/src/zope/app/form/interfaces.py�������������������������������������������������0000644�0001750�0001750�00000002576�11340453312�021515� 0����������������������������������������������������������������������������������������������������ustar �sidnei��������������������������sidnei�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������############################################################################## # # Copyright (c) 2002 Zope Corporation 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. # ############################################################################## """Validation Exceptions $Id: interfaces.py 107371 2009-12-30 18:36:02Z faassen $ """ __docformat__ = 'restructuredtext' # this moved to zope.formlib.interfaces from zope.formlib.interfaces import (IWidgetInputError, WidgetInputError, MissingInputError, ConversionError, InputErrors, ErrorContainer, WidgetsError, IWidget, IInputWidget, IDisplayWidget, IWidgetFactory) ����������������������������������������������������������������������������������������������������������������������������������zope.app.form-4.0.2/src/zope/app/form/browser/������������������������������������������������������0000755�0001750�0001750�00000000000�11340453312�020471� 5����������������������������������������������������������������������������������������������������ustar �sidnei��������������������������sidnei�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zope.app.form-4.0.2/src/zope/app/form/browser/metadirectives.py�������������������������������������0000644�0001750�0001750�00000021577�11340453312�024067� 0����������������������������������������������������������������������������������������������������ustar �sidnei��������������������������sidnei�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������############################################################################## # # Copyright (c) 2001, 2002 Zope Corporation 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 and Widget specific 'browser' ZCML namespace interfaces $Id: metadirectives.py 104906 2009-10-08 06:06:50Z tlotze $ """ __docformat__ = 'restructuredtext' from zope.interface import Interface from zope.configuration.fields import GlobalObject, GlobalInterface from zope.configuration.fields import Tokens, Path, Bool, PythonIdentifier from zope.configuration.fields import MessageID from zope.schema import Text, TextLine, Id from zope.security.zcml import Permission from zope.browsermenu.field import MenuField class ICommonInformation(Interface): """ Common information for all successive directives """ name = TextLine( title=u"Name", description=u"The name of the generated view.", required=True ) schema = GlobalInterface( title=u"Schema", description=u"The schema from which the form is generated.", required=True ) for_ = GlobalInterface( title=u"Interface", description=u""" The interface this page (view) applies to. The view will be for all objects that implement this interface. The schema is used if the for attribute is not specified. If the for attribute is specified, then the objects views must implement or be adaptable to the schema.""", required=False ) permission = Permission( title=u"Permission", description=u"The permission needed to use the view.", required=True ) layer = GlobalInterface( title=u"Layer", description=u"The later the view is in. Default: 'default'", required=False ) template = Path( title=u"Template", description=u"An alternate template to use for the form.", required=False ) class_ = GlobalObject( title=u"Class", description=u""" A class to provide custom widget definitions or methods to be used by a custom template. This class is used as a mix-in class. As a result, it needn't subclass any special classes, such as BrowserView.""", required=False ) class ICommonFormInformation(ICommonInformation): """ Common information for browser forms """ label = MessageID( title=u"Label", description=u"A label to be used as the heading for the form.", required=False ) menu = MenuField( title=u"The browser menu to include the form in.", description=u""" Many views are included in menus. It's convenient to name the menu in the page directive, rather than having to give a separate menuItem directive.""", required=False ) title = MessageID( title=u"Menu title", description=u"The browser menu label for the form.", required=False ) fields = Tokens( title=u"Fields", description=u""" Here you can specify the names of the fields you wish to display. The order in this list is also the order the fields will be displayed in. If this attribute is not specified, all schema fields will be displayed in the order specified in the schema itself.""", required=False, value_type=PythonIdentifier() ) class ICommonAddInformation(Interface): """ Common information for add forms """ content_factory = GlobalObject( title=u"Content factory", description=u""" An object to call to create new content objects. This attribute isn't used if a class is specified that implements createAndAdd.""", required=False ) content_factory_id = Id( title=u"Content factory id", description=u"A factory id to create new content objects", required = False, ) arguments = Tokens( title=u"Arguments", description=u""" A list of field names to supply as positional arguments to the factory.""", required=False, value_type=PythonIdentifier() ) keyword_arguments = Tokens( title=u"Keyword arguments", description=u""" A list of field names to supply as keyword arguments to the factory.""", required=False, value_type=PythonIdentifier() ) set_before_add = Tokens( title=u"Set before add", description=u""" A list of fields to be assigned to the newly created object before it is added.""", required=False, value_type=PythonIdentifier(), ) set_after_add = Tokens( title=u"Set after add", description=u""" A list of fields to be assigned to the newly created object after it is added.""", required=False, value_type=PythonIdentifier() ) class IFormDirective(ICommonFormInformation): """ Define an automatically generated form. The form directive does nto require the data to be stored in its context, but leaves the storing procedure to the to a method. """ class_ = GlobalObject( title=u"Class", description=u""" A class to provide the `getData()` and `setData()` methods or completely custom methods to be used by a custom template. This class is used as a mix-in class. As a result, it needn't subclass any special classes, such as BrowserView.""", required=True ) class IEditFormDirective(ICommonFormInformation): """ Define an automatically generated edit form The editform directive creates and registers a view for editing an object based on a schema. """ class ISubeditFormDirective(ICommonInformation): """ Define a subedit form """ label = TextLine( title=u"Label", description=u"A label to be used as the heading for the form.", required=False ) fulledit_path = TextLine( title=u"Path (relative URL) to the full edit form", required=False ) fulledit_label = MessageID( title=u"Label of the full edit form", required=False ) class IAddFormDirective(ICommonFormInformation, ICommonAddInformation): """ Define an automatically generated add form The addform directive creates and registers a view for adding an object based on a schema. Adding an object is a bit trickier than editing an object, because the object the schema applies to isn't available when forms are being rendered. The addform directive provides a customization interface to overcome this difficulty. See zope.app.form.browser.interfaces.IAddFormCustomization. """ description = MessageID( title=u"A longer description of the add form.", description=u""" A UI may display this with the item or display it when the user requests more assistance.""", required=False ) class ISchemaDisplayDirective(ICommonFormInformation): """ Define an automatically generated display form. The schemadisplay directive creates and registers a view for displaying an object based on a schema. """ title = MessageID( title=u"The browser menu label for the edit form", description=u"This attribute defaults to 'Edit'.", required=False ) class IWidgetSubdirective(Interface): """Register custom widgets for a form. This directive allows you to quickly generate custom widget directives for a form. Besides the two required arguments, field and class, you can specify any amount of keyword arguments, e.g. style='background-color:#fefefe;'. The keywords will be stored as attributes on the widget instance. To see which keywords are sensible, you should look at the code of the specified widget class. """ field = TextLine( title=u"Field Name", description=u""" The name of the field/attribute/property for which this widget will be used.""", required=True, ) class_ = GlobalObject( title=u"Widget Class", description=u"""The class that will create the widget.""", required=False, ) # Arbitrary keys and values are allowed to be passed to the CustomWidget. IWidgetSubdirective.setTaggedValue('keyword_arguments', True) ���������������������������������������������������������������������������������������������������������������������������������zope.app.form-4.0.2/src/zope/app/form/browser/form.txt����������������������������������������������0000644�0001750�0001750�00000015117�11340453312�022202� 0����������������������������������������������������������������������������������������������������ustar �sidnei��������������������������sidnei�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������============= Generic Forms ============= The `browser:form` allows the developer to use the form and widget framework without relying on a particular context object. Instead, it is up to the developer to implement two simple methods that handle the retrieval and mutation of the data in form of a dictionary. But I am getting ahead of myself. We first need to define a schema that we would like to use for our form: >>> import zope.interface >>> import zope.schema >>> class IName(zope.interface.Interface): ... """The name of a person.""" ... ... first = zope.schema.TextLine( ... title=u"First Name", ... required=False) ... ... last = zope.schema.TextLine( ... title=u"Last Name", ... required=True) Now we are almost ready to create the form view. But first we have to create a class that knows how to get and set values for the fields described by the schema. The system calls for a class (that will be used as a mixin) that implements a method called `getData()` that returns a dictionary mapping field names to values and a second method called `setData(data)` that takes a data dictionary as argument and handles the data in any way fit. In our case, let's store the data in a global attribute called name: >>> name = ['John', 'Doe'] >>> class DataHandler(object): ... ... def getData(self): ... global name ... return {'first': name[0], 'last': name[1]} ... ... def setData(self, data): ... global name ... name[0] = data['first'] ... name[1] = data['last'] ... return u"Saved changes." We now imitate the form-directive's behavior and create the view class: >>> from zope.app.form.browser.formview import FormView >>> View = type('View', (DataHandler, FormView), {'schema': IName}) To initialize the view, you still need a context and a request. The context is useful because it gives you a location, so that you can look up local components to store the data, such as the principal annotations. In our case we do not care about the context, so it will be just `None`: >>> from zope.publisher.browser import TestRequest >>> request = TestRequest() >>> view = View(None, request) We can now look at the widgets and see that the data was correctly loaded: >>> view.first_widget() u'<input class="textType" id="field.first" name="field.first" size="20" type="text" value="John" />' >>> view.last_widget() u'<input class="textType" id="field.last" name="field.last" size="20" type="text" value="Doe" />' Now when a request is sent in, the data is transmitted in the form >>> request.form['field.first'] = u'Stephan' >>> request.form['field.last'] = u'Richter' >>> request.form['UPDATE_SUBMIT'] = u'' and as soon as the `update()` method is called >>> view.update() u'Saved changes.' the global name variable is changed: >>> name [u'Stephan', u'Richter'] And that's pretty much all that there is to it. The rest behaves exactly like an edit form, from which the form view was derived. Of course you can also completely overwrite the `update()` method like for the edit view removing the requirement to implement the `getData()` and `setData()` methods. Using the `browser:form` directive ================================== Let's now see how the form directive works. The first task is to load the necessary meta-configuration: >>> from zope.configuration import xmlconfig >>> import zope.component >>> context = xmlconfig.file('meta.zcml', zope.component) >>> import zope.app.form.browser >>> context = xmlconfig.file('meta.zcml', zope.app.form.browser, context) Before we run the directive, make sure that no view exists: >>> class IAnything(zope.interface.Interface): ... pass >>> class Anything(object): ... zope.interface.implements(IAnything) >>> from zope.publisher.browser import TestRequest >>> from zope.component import queryMultiAdapter >>> queryMultiAdapter((Anything(), TestRequest()), name='name.html') Now that we know that the view did not exist before the registration, let's execute the form directive: >>> import sys >>> sys.modules['form'] = type( ... 'Module', (), ... {'DataHandler': DataHandler, ... 'IAnything': IAnything, ... 'IName': IName})() >>> context = xmlconfig.string(''' ... <configure ... xmlns="http://namespaces.zope.org/zope" ... xmlns:browser="http://namespaces.zope.org/browser" ... i18n_domain="zope"> ... ... <view ... type="zope.publisher.interfaces.browser.IBrowserRequest" ... for="zope.schema.interfaces.ITextLine" ... provides="zope.formlib.interfaces.IInputWidget" ... factory="zope.app.form.browser.TextWidget" ... permission="zope.Public" ... /> ... ... <browser:form ... for="form.IAnything" ... schema="form.IName" ... class="form.DataHandler" ... name="name.html" ... label="Edit the name" ... fields="first last" ... permission="zope.Public" /> ... ... </configure> ... ''', context) and try to look up the view again: >>> queryMultiAdapter( ... (Anything(), TestRequest()), name='name.html') #doctest:+ELLIPSIS <zope.browserpage.simpleviewclass.SimpleViewClass from edit.pt ...> Now, if I do not specify my own template, and my class does not overwrite the `update()` method, then the class *must* implement `getData()` and `setData(data)`, otherwise a configuration error is raised: >>> class NewDataHandler(object): ... ... def getData(self): ... return {} >>> sys.modules['form'].NewDataHandler = NewDataHandler >>> context = xmlconfig.string(''' ... <configure ... xmlns:browser="http://namespaces.zope.org/browser" ... i18n_domain="zope"> ... ... <browser:form ... for="form.IAnything" ... schema="form.IName" ... class="form.NewDataHandler" ... name="name.html" ... label="Edit the name" ... fields="first last" ... permission="zope.Public" /> ... ... </configure> ... ''', context) Traceback (most recent call last): ... ZopeXMLConfigurationError: File "<string>", line 6.6 ConfigurationError: You must specify a class that implements `getData()` and `setData()`, if you do not overwrite `update()`. Now we need to clean up afterwards. >>> del sys.modules['form'] �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zope.app.form-4.0.2/src/zope/app/form/browser/widget.py���������������������������������������������0000644�0001750�0001750�00000001723�11340453312�022331� 0����������������������������������������������������������������������������������������������������ustar �sidnei��������������������������sidnei�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������############################################################################## # # Copyright (c) 2001-2004 Zope Corporation 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. # ############################################################################## """Browser Widget Definitions $Id: widget.py 107818 2010-01-08 19:14:50Z faassen $ """ __docformat__ = 'restructuredtext' # BBB from zope.formlib.widget import ( quoteattr, BrowserWidget, SimpleInputWidget, DisplayWidget, UnicodeDisplayWidget, renderTag, renderElement, escape, setUp, tearDown) ���������������������������������������������zope.app.form-4.0.2/src/zope/app/form/browser/formview.py�������������������������������������������0000644�0001750�0001750�00000005470�11340453312�022707� 0����������������������������������������������������������������������������������������������������ustar �sidnei��������������������������sidnei�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������############################################################################## # # Copyright (c) 2001, 2002 Zope Corporation 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 View Classes $Id: formview.py 107371 2009-12-30 18:36:02Z faassen $ """ __docformat__ = 'restructuredtext' import transaction from zope.formlib.interfaces import WidgetsError, IInputWidget from zope.app.form.utility import setUpWidgets, applyWidgetsChanges from zope.app.form.browser.editview import EditView from zope.app.form.browser.i18n import _ from zope.app.form.browser.submit import Update class Data(dict): """Dictionary wrapper to make keys available as attributes.""" def __getattr__(self, name): return self[name] def __setattr__(self, name, value): self[name] = value class FormView(EditView): def getData(self): """Get the data for the form. This method should return a dictionary mapping field names to values. """ NotImplemented, 'Must be implemented by a specific form class' def setData(self, data): """Set the data gotten from a form. The data will be a dictionary of fieldnames to values. May return a status message. """ NotImplemented, 'Must be implemented by a specific form class' def _setUpWidgets(self): self.data = Data(self.getData()) setUpWidgets( self, self.schema, IInputWidget, initial=self.data, names=self.fieldNames) def update(self): if self.update_status is not None: # We've been called before. Just return the status we previously # computed. return self.update_status status = '' if Update in self.request: try: changed = applyWidgetsChanges( self, self.schema, target=self.data, names=self.fieldNames) except WidgetsError, errors: self.errors = errors status = _("An error occurred.") transaction.doom() else: if changed: status = self.setData(self.data) setUpWidgets( self, self.schema, IInputWidget, initial=self.data, ignoreStickyValues=True, names=self.fieldNames) self.update_status = status return status ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zope.app.form-4.0.2/src/zope/app/form/browser/add.py������������������������������������������������0000644�0001750�0001750�00000014020�11340453312�021570� 0����������������������������������������������������������������������������������������������������ustar �sidnei��������������������������sidnei�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������############################################################################## # # Copyright (c) 2001, 2002 Zope Corporation 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. # ############################################################################## """Add Form View class $Id: add.py 107371 2009-12-30 18:36:02Z faassen $ """ __docformat__ = 'restructuredtext' import sys import zope.component from zope.component.interfaces import IFactory from zope.event import notify from zope.interface import Interface from zope.schema.interfaces import ValidationError from zope.security.checker import defineChecker, NamesChecker from zope.publisher.interfaces.browser import IDefaultBrowserLayer from zope.lifecycleevent import ObjectCreatedEvent, ObjectModifiedEvent from zope.lifecycleevent import Attributes from zope.app.form.utility import setUpWidgets, getWidgetsData from zope.formlib.interfaces import IInputWidget, WidgetsError from zope.app.form.browser.i18n import _ from zope.browserpage.simpleviewclass import SimpleViewClass from zope.browserpage import ViewPageTemplateFile from editview import EditView from submit import Update class AddView(EditView): """Simple edit-view base class. Subclasses should provide a schema attribute defining the schema to be edited. """ def _setUpWidgets(self): setUpWidgets(self, self.schema, IInputWidget, names=self.fieldNames) def update(self): if self.update_status is not None: # We've been called before. Just return the previous result. return self.update_status if Update in self.request: self.update_status = '' try: data = getWidgetsData(self, self.schema, names=self.fieldNames) self.createAndAdd(data) except WidgetsError, errors: self.errors = errors self.update_status = _("An error occurred.") return self.update_status self.request.response.redirect(self.nextURL()) return self.update_status def create(self, *args, **kw): """Do the actual instantiation.""" return self._factory(*args, **kw) def createAndAdd(self, data): """Add the desired object using the data in the data argument. The data argument is a dictionary with the data entered in the form. """ args = [] if self._arguments: for name in self._arguments: args.append(data[name]) kw = {} if self._keyword_arguments: for name in self._keyword_arguments: if name in data: kw[str(name)] = data[name] content = self.create(*args, **kw) errors = [] if self._set_before_add: adapted = self.schema(content) for name in self._set_before_add: if name in data: field = self.schema[name] try: field.set(adapted, data[name]) except ValidationError: errors.append(sys.exc_info()[1]) if errors: raise WidgetsError(*errors) notify(ObjectCreatedEvent(content)) content = self.add(content) if self._set_after_add: adapted = self.schema(content) for name in self._set_after_add: if name in data: if data[name] is not None: field = self.schema[name] try: field.set(adapted, data[name]) except ValidationError: errors.append(sys.exc_info()[1]) # We have modified the object, so we need to publish an # object-modified event: description = Attributes(self.schema, *self._set_after_add) notify(ObjectModifiedEvent(content, description)) if errors: raise WidgetsError(*errors) return content def add(self, content): return self.context.add(content) def nextURL(self): return self.context.nextURL() # helper for factory resp. content_factory handling def _getFactory(self): # get factory or factory id factory = self.__dict__.get('_factory_or_id', self._factory_or_id) if type(factory) is str: # factory id return zope.component.getUtility(IFactory, factory, self.context) else: return factory def _setFactory(self, value): self.__dict__['_factory_or_id'] = value def AddViewFactory(name, schema, label, permission, layer, template, default_template, bases, for_, fields, content_factory, arguments, keyword_arguments, set_before_add, set_after_add): class_ = SimpleViewClass( template, used_for=schema, bases=bases, name=name) class_.schema = schema class_.label = label class_.fieldNames = fields class_._factory_or_id = content_factory class_._factory = property(_getFactory, _setFactory) class_._arguments = arguments class_._keyword_arguments = keyword_arguments class_._set_before_add = set_before_add class_._set_after_add = set_after_add class_.generated_form = ViewPageTemplateFile(default_template) defineChecker(class_, NamesChecker( ("__call__", "__getitem__", "browserDefault", "publishTraverse"), permission, ) ) if layer is None: layer = IDefaultBrowserLayer s = zope.component.getGlobalSiteManager() s.registerAdapter(class_, (for_, layer), Interface, name) ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zope.app.form-4.0.2/src/zope/app/form/browser/exception.py������������������������������������������0000644�0001750�0001750�00000001507�11340453312�023044� 0����������������������������������������������������������������������������������������������������ustar �sidnei��������������������������sidnei�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������############################################################################## # # Copyright (c) 2003 Zope Corporation 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-related exception views $Id: exception.py 107385 2009-12-30 20:25:24Z faassen $ """ # BBB implementation moved to zope.formlib.exception from zope.formlib.exception import WidgetInputErrorView �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zope.app.form-4.0.2/src/zope/app/form/browser/edit.pt�����������������������������������������������0000644�0001750�0001750�00000004035�11340453312�021765� 0����������������������������������������������������������������������������������������������������ustar �sidnei��������������������������sidnei�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<tal:tag condition="view/update"/> <html metal:use-macro="context/@@standard_macros/view" i18n:domain="zope"> <body> <div metal:fill-slot="body"> <div metal:define-macro="body"> <form action="." tal:attributes="action request/URL" method="post" enctype="multipart/form-data"> <div metal:define-macro="formbody"> <h3 tal:condition="view/label" tal:content="view/label" metal:define-slot="heading" i18n:translate="" >Edit something</h3> <p tal:define="status view/update" tal:condition="status" tal:content="status" i18n:translate=""/> <p tal:condition="view/errors" i18n:translate=""> There are <strong tal:content="python:len(view.errors)" i18n:name="num_errors">6</strong> input errors. </p> <div metal:define-slot="extra_info" tal:replace="nothing"> </div> <div class="row" metal:define-slot="extra_top" tal:replace="nothing"> <div class="label">Extra top</div> <div class="field"><input type="text" style="width:100%" /></div> </div> <div metal:use-macro="context/@@form_macros/widget_rows" /> <div class="separator"></div> <div class="row" metal:define-slot="extra_bottom" tal:replace="nothing"> <div class="label">Extra bottom</div> <div class="field"><input type="text" style="width:100%" /></div> </div> <div class="separator"></div> </div> <div class="row"> <div class="controls"> <input type="submit" value="Refresh" i18n:attributes="value refresh-button" /> <input type="submit" name="UPDATE_SUBMIT" value="Change" i18n:attributes="value submit-button"/> </div> </div> <div class="row" metal:define-slot="extra_buttons" tal:replace="nothing"> </div> <div class="separator"></div> </form> </div> </div> </body> </html> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zope.app.form-4.0.2/src/zope/app/form/browser/interfaces.py�����������������������������������������0000644�0001750�0001750�00000007433�11340453312�023175� 0����������������������������������������������������������������������������������������������������ustar �sidnei��������������������������sidnei�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������############################################################################## # # Copyright (c) 2002 Zope Corporation 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 and Widget Interfaces $Id: interfaces.py 107398 2009-12-30 22:26:34Z faassen $ """ __docformat__ = 'restructuredtext' from zope.interface import Interface from zope.schema import TextLine, Bool from zope.formlib.interfaces import IWidget, IInputWidget # BBB: ITerms are also used by z3c.form and possibly other form # frameworks, so it was moved to zope.browser.interfaces and it's # preferred to import from there now. from zope.browser.interfaces import ITerms from zope.formlib.interfaces import ( IBrowserWidget, ISimpleInputWidget, ITextBrowserWidget, IWidgetInputErrorView, ISourceQueryView) class IFormCollaborationView(Interface): """Views that collaborate to create a single form. When a form is applied, the changes in the form need to be applied to individual views, which update objects as necessary. """ def __call__(): """Render the view as a part of a larger form. Form input elements should be included, prefixed with the prefix given to setPrefix. `form` and `submit` elements should not be included. They will be provided for the larger form. """ def setPrefix(prefix): """Set the `prefix` used for names of input elements Element names should begin with the given `prefix`, followed by a dot. """ def update(): """Update the form with data from the request.""" class IAddFormCustomization(Interface): """API for add form customization. Classes supplied when defining add forms may need to override some of these methods. In particular, when the context of an add form is not an `IAdding`, a subclass needs to override `nextURL` and one of `add` or `createAndAdd`. To see how all this fits together, here's pseudo code for the update() method of the form: def update(self): data = <get data from widgets> # a dict self.createAndAdd(data) self.request.response.redirect(self.nextURL()) def createAndAdd(self, data): content = <create the content from the data> content = self.add(content) <set after-add attributes on content> """ def createAndAdd(data): """Create a new object from the given data and the resulting object. The data argument is a dictionary with values supplied by the form. If any user errors occur, they should be collected into a list and raised as a ``WidgetsError``. (For the default implementation, see pseudo-code in class docs.) """ def add(content): """Add the given content. This method is overridden when the context of the add form is not an `IAdding`. In this case, the class that customizes the form must take over adding the object. The default implementation returns `self.context.add(content)`, i.e. it delegates to the `IAdding` view. """ def nextURL(): """Return the URL to be displayed after the add operation. This can be relative to the view's context. The default implementation returns `self.context.nextURL()`, i.e. it delegates to the `IAdding` view. """ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zope.app.form-4.0.2/src/zope/app/form/browser/source.py���������������������������������������������0000644�0001750�0001750�00000002162�11340453312�022344� 0����������������������������������������������������������������������������������������������������ustar �sidnei��������������������������sidnei�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������############################################################################## # # Copyright (c) 2004 Zope Corporation and Contributors. # All Rights Reserved. # # This software is subject to the provisions of the Zope Public License, # Version 2.0 (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. # ############################################################################## """Source widgets support $Id: source.py 107398 2009-12-30 22:26:34Z faassen $ """ # BBB from zope.formlib.source import ( SourceDisplayWidget, SourceSequenceDisplayWidget, SourceInputWidget, SourceListInputWidget, IterableSourceVocabulary, SourceSelectWidget, SourceDropdownWidget, SourceRadioWidget, SourceMultiSelectWidget, SourceOrderedMultiSelectWidget, SourceMultiSelectSetWidget, SourceMultiSelectFrozenSetWidget, SourceMultiCheckBoxWidget) ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zope.app.form-4.0.2/src/zope/app/form/browser/macros.py���������������������������������������������0000644�0001750�0001750�00000003131�11340453312�022325� 0����������������������������������������������������������������������������������������������������ustar �sidnei��������������������������sidnei�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������############################################################################## # # Copyright (c) 2003 Zope Corporation 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. # ############################################################################## """API Documentation macros $Id: macros.py 106723 2009-12-17 23:16:34Z hannosch $ """ __docformat__ = 'restructuredtext' from zope.component import getMultiAdapter from zope.interface import implements from zope.interface.common.mapping import IItemMapping from zope.publisher.browser import BrowserView class FormMacros(BrowserView): implements(IItemMapping) macro_pages = ( 'view_macros', 'widget_macros', 'addform_macros', ) aliases = { 'view': 'page', 'dialog': 'page', 'addingdialog': 'page', } def __getitem__(self, key): key = self.aliases.get(key, key) context = self.context request = self.request for name in self.macro_pages: page = getMultiAdapter((context, request), name=name) try: v = page[key] except KeyError: pass else: return v raise KeyError(key) ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zope.app.form-4.0.2/src/zope/app/form/browser/display.pt��������������������������������������������0000644�0001750�0001750�00000001700�11340453312�022501� 0����������������������������������������������������������������������������������������������������ustar �sidnei��������������������������sidnei�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<html metal:use-macro="context/@@standard_macros/view" i18n:domain="zope"> <body> <div metal:fill-slot="body"> <div metal:define-macro="body"> <div metal:define-macro="formbody"> <h3 tal:condition="view/label" tal:content="view/label" metal:define-slot="heading" i18n:translate="" >Display something</h3> <div metal:define-slot="extra_info" tal:replace="nothing"> </div> <div class="row" metal:define-slot="extra_top" tal:replace="nothing"> <div class="label">Extra top</div> <div class="field"><input type="text" style="width:100%" /></div> </div> <div metal:use-macro="context/@@form_macros/widget_rows" /> <div class="row" metal:define-slot="extra_bottom" tal:replace="nothing"> <div class="label">Extra bottom</div> <div class="field"><input type="text" style="width:100%" /></div> </div> </div> </div> </div> </body> </html> ����������������������������������������������������������������zope.app.form-4.0.2/src/zope/app/form/browser/__init__.py�������������������������������������������0000644�0001750�0001750�00000007143�11340453312�022607� 0����������������������������������������������������������������������������������������������������ustar �sidnei��������������������������sidnei�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������############################################################################## # # Copyright (c) 2004 Zope Corporation 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. # ############################################################################## """Browser widgets $Id: __init__.py 107377 2009-12-30 19:46:00Z faassen $ """ __docformat__ = 'restructuredtext' # the implementation of widgets has moved to zope.formlib.widgets # import directly from there instead. from zope.formlib.widget import BrowserWidget, DisplayWidget from zope.formlib.widget import UnicodeDisplayWidget from zope.formlib.widgets import TextWidget, BytesWidget from zope.formlib.widgets import TextAreaWidget, BytesAreaWidget from zope.formlib.widgets import PasswordWidget, FileWidget from zope.formlib.widgets import ASCIIWidget, ASCIIAreaWidget from zope.formlib.widgets import IntWidget, FloatWidget from zope.formlib.widgets import DecimalWidget from zope.formlib.widgets import DatetimeWidget, DateWidget from zope.formlib.widgets import DatetimeI18nWidget from zope.formlib.widgets import DateI18nWidget from zope.formlib.widgets import DatetimeDisplayWidget from zope.formlib.widgets import DateDisplayWidget from zope.formlib.widgets import BytesDisplayWidget from zope.formlib.widgets import ASCIIDisplayWidget from zope.formlib.widgets import URIDisplayWidget # Widgets for boolean fields from zope.formlib.widgets import CheckBoxWidget from zope.formlib.widgets import BooleanRadioWidget from zope.formlib.widgets import BooleanSelectWidget from zope.formlib.widgets import BooleanDropdownWidget # Choice and Sequence Display Widgets from zope.formlib.widgets import ItemDisplayWidget from zope.formlib.widgets import ItemsMultiDisplayWidget from zope.formlib.widgets import SetDisplayWidget from zope.formlib.widgets import ListDisplayWidget # Widgets for fields with vocabularies. # Note that these are only dispatchers for the widgets below. from zope.formlib.widgets import ChoiceDisplayWidget from zope.formlib.widgets import ChoiceInputWidget from zope.formlib.widgets import CollectionDisplayWidget from zope.formlib.widgets import CollectionInputWidget from zope.formlib.widgets import ChoiceCollectionDisplayWidget from zope.formlib.widgets import ChoiceCollectionInputWidget # Widgets that let you choose a single item from a list # These widgets are multi-views on (field, vocabulary) from zope.formlib.widgets import SelectWidget from zope.formlib.widgets import DropdownWidget from zope.formlib.widgets import RadioWidget # Widgets that let you choose several items from a list # These widgets are multi-views on (field, vocabulary) from zope.formlib.widgets import MultiSelectWidget from zope.formlib.widgets import MultiSelectSetWidget from zope.formlib.widgets import MultiSelectFrozenSetWidget from zope.formlib.widgets import MultiCheckBoxWidget from zope.formlib.widgets import OrderedMultiSelectWidget # Widgets that let you enter several items in a sequence # These widgets are multi-views on (sequence type, value type) from zope.formlib.widgets import SequenceWidget from zope.formlib.widgets import TupleSequenceWidget from zope.formlib.widgets import ListSequenceWidget from zope.formlib.widgets import SequenceDisplayWidget from zope.formlib.widgets import ObjectWidget �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zope.app.form-4.0.2/src/zope/app/form/browser/add.pt������������������������������������������������0000644�0001750�0001750�00000004456�11340453312�021577� 0����������������������������������������������������������������������������������������������������ustar �sidnei��������������������������sidnei�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<html metal:use-macro="context/@@standard_macros/page" i18n:domain="zope"> <body> <div metal:fill-slot="body"> <div metal:define-macro="addform"> <form action="." tal:attributes="action request/URL" method="post" enctype="multipart/form-data"> <div metal:define-macro="formbody"> <h3 tal:condition="view/label" tal:content="view/label" metal:define-slot="heading" i18n:translate="" >Edit something</h3> <p tal:define="status view/update" tal:condition="status" tal:content="status" i18n:translate=""/> <p tal:condition="view/errors" i18n:translate=""> There are <strong tal:content="python:len(view.errors)" i18n:name="num_errors">6</strong> input errors. </p> <div metal:define-slot="extra_info" tal:replace="nothing"> </div> <div class="row" metal:define-slot="extra_top" tal:replace="nothing"> <div class="label">Extra top</div> <div class="label"><input type="text" style="width:100%" /></div> </div> <div metal:use-macro="context/@@form_macros/widget_rows" /> <div class="separator"></div> <div class="row" metal:define-slot="extra_bottom" tal:replace="nothing"> <div class="label">Extra bottom</div> <div class="field"><input type="text" style="width:100%" /></div> </div> <div class="separator"></div> </div> <br/><br/> <div class="row"> <div class="controls"><hr /> <input type='submit' value='Refresh' i18n:attributes='value refresh-button' /> <input type='submit' value='Add' name='UPDATE_SUBMIT' i18n:attributes='value add-button' /> <span tal:condition="context/nameAllowed|nothing" tal:omit-tag="">   <b i18n:translate="">Object Name</b>   <input type='text' name='add_input_name' tal:attributes="value context/contentName" /> </span> </div> </div> <div class="row" metal:define-slot="extra_buttons" tal:replace="nothing"> </div> <div class="separator"></div> </form> </div> </div> </body> </html> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zope.app.form-4.0.2/src/zope/app/form/browser/boolwidgets.py����������������������������������������0000644�0001750�0001750�00000001666�11340453312�023376� 0����������������������������������������������������������������������������������������������������ustar �sidnei��������������������������sidnei�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������############################################################################## # # Copyright (c) 2004 Zope Corporation 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. # ############################################################################## """Browser widgets for items $Id: boolwidgets.py 107385 2009-12-30 20:25:24Z faassen $ """ # BBB implementation moved to zope.formlib.boolwidgets from zope.formlib.boolwidgets import ( CheckBoxWidget, BooleanRadioWidget, BooleanSelectWidget, BooleanDropdownWidget, BooleanDisplayWidget) ��������������������������������������������������������������������������zope.app.form-4.0.2/src/zope/app/form/browser/itemswidgets.py���������������������������������������0000644�0001750�0001750�00000002761�11340453312�023561� 0����������������������������������������������������������������������������������������������������ustar �sidnei��������������������������sidnei�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������############################################################################## # # Copyright (c) 2004 Zope Corporation 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. # ############################################################################## """Browser widgets for items $Id: itemswidgets.py 107385 2009-12-30 20:25:24Z faassen $ """ __docformat__ = 'restructuredtext' # BBB the implementation has moved to zope.formlib.itemswidgets from zope.formlib.itemswidgets import ( ChoiceDisplayWidget, ChoiceInputWidget, CollectionDisplayWidget, CollectionInputWidget, ChoiceCollectionDisplayWidget, ChoiceCollectionInputWidget, TranslationHook, ItemsWidgetBase, SingleDataHelper, MultiDataHelper, ItemsWidgetBase, ItemDisplayWidget, ItemsMultiDisplayWidget, ListDisplayWidget, SetDisplayWidget, ItemsEditWidgetBase, EXPLICIT_EMPTY_SELECTION, SelectWidget, DropdownWidget, RadioWidget, ItemsMultiEditWidgetBase, MultiSelectWidget, MultiSelectSetWidget, MultiSelectFrozenSetWidget, OrderedMultiSelectWidget, MultiCheckBoxWidget) ���������������zope.app.form-4.0.2/src/zope/app/form/browser/metaconfigure.py��������������������������������������0000644�0001750�0001750�00000025553�11340453312�023705� 0����������������������������������������������������������������������������������������������������ustar �sidnei��������������������������sidnei�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������############################################################################## # # Copyright (c) 2001, 2002 Zope Corporation 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. # ############################################################################## """Configuration handlers for forms and widgets $Id: metaconfigure.py 107376 2009-12-30 19:21:24Z faassen $ """ __docformat__ = 'restructuredtext' import os import zope.component from zope.security.checker import CheckerPublic from zope.interface import implementedBy from zope.configuration.exceptions import ConfigurationError from zope.browser.interfaces import IAdding from zope.schema import getFieldNamesInOrder from zope.publisher.interfaces.browser import IBrowserRequest from zope.publisher.interfaces.browser import IDefaultBrowserLayer from zope.browsermenu.metaconfigure import menuItemDirective from zope.formlib.widget import CustomWidgetFactory from zope.app.form.browser.i18n import _ from zope.formlib.interfaces import IInputWidget, IDisplayWidget from zope.formlib.interfaces import IWidgetFactory from add import AddView, AddViewFactory from editview import EditView, EditViewFactory from formview import FormView from schemadisplay import DisplayView, DisplayViewFactory class BaseFormDirective(object): # to be overriden by the subclasses view = None default_template = None # default basic information for_ = None layer = IDefaultBrowserLayer permission = CheckerPublic template = None class_ = None # default form information title = None label = None menu = None fields = None def __init__(self, _context, **kwargs): self._context = _context for key, value in kwargs.items(): if not (value is None and hasattr(self, key)): setattr(self, key, value) self._normalize() self._widgets = {} def widget(self, _context, field, **kw): attrs = kw class_ = attrs.pop("class_", None) # Try to do better than accepting the string value by looking through # the interfaces and trying to find the field, so that we can use # 'fromUnicode()' if isinstance(class_, type): ifaces = implementedBy(class_) for name, value in kw.items(): for iface in ifaces: if name in iface: attrs[name] = iface[name].fromUnicode(value) break if class_ is None: # The _default_widget_factory is required to allow the # <widget> directive to be given without a "class" # attribute. This can be used to override some of the # presentational attributes of the widget implementation. class_ = self._default_widget_factory # don't wrap a factory into a factory if IWidgetFactory.providedBy(class_): factory = class_ else: factory = CustomWidgetFactory(class_, **attrs) self._widgets[field+'_widget'] = factory def _processWidgets(self): if self._widgets: customWidgetsObject = type('CustomWidgetsMixin', (object,), self._widgets) self.bases = self.bases + (customWidgetsObject,) def _normalize(self): if self.for_ is None: self.for_ = self.schema if self.class_ is None: self.bases = (self.view,) else: self.bases = (self.class_, self.view) if self.template is not None: self.template = os.path.abspath(str(self.template)) if not os.path.isfile(self.template): raise ConfigurationError("No such file", self.template) else: self.template = self.default_template self.names = getFieldNamesInOrder(self.schema) if self.fields: for name in self.fields: if name not in self.names: raise ValueError("Field name is not in schema", name, self.schema) else: self.fields = self.names def _args(self): permission = self.permission if permission == 'zope.Public': # Translate public permission to CheckerPublic permission = CheckerPublic return (self.name, self.schema, self.label, permission, self.layer, self.template, self.default_template, self.bases, self.for_, self.fields) def _discriminator(self): return ('view', self.for_, self.name, IBrowserRequest, self.layer) class AddFormDirective(BaseFormDirective): view = AddView default_template = 'add.pt' for_ = IAdding # default add form information description = None content_factory_id = None content_factory = None arguments = None keyword_arguments = None set_before_add = None set_after_add = None def _default_widget_factory(self, field, request): # `field` is a bound field return zope.component.getMultiAdapter( (field, request), IInputWidget) def _handle_menu(self): if self.menu or self.title: if (not self.menu) or (not self.title): raise ValueError("If either menu or title are specified, " "they must both be specified") # Add forms are really for IAdding components, so do not use # for=self.schema. menuItemDirective( self._context, self.menu, self.for_, '@@' + self.name, self.title, permission=self.permission, layer=self.layer, description=self.description) def _handle_arguments(self, leftover=None): schema = self.schema fields = self.fields arguments = self.arguments keyword_arguments = self.keyword_arguments set_before_add = self.set_before_add set_after_add = self.set_after_add if leftover is None: leftover = fields if arguments: missing = [n for n in arguments if n not in fields] if missing: raise ValueError("Some arguments are not included in the form", missing) optional = [n for n in arguments if not schema[n].required] if optional: raise ValueError("Some arguments are optional, use" " keyword_arguments for them", optional) leftover = [n for n in leftover if n not in arguments] if keyword_arguments: missing = [n for n in keyword_arguments if n not in fields] if missing: raise ValueError( "Some keyword_arguments are not included in the form", missing) leftover = [n for n in leftover if n not in keyword_arguments] if set_before_add: missing = [n for n in set_before_add if n not in fields] if missing: raise ValueError( "Some set_before_add are not included in the form", missing) leftover = [n for n in leftover if n not in set_before_add] if set_after_add: missing = [n for n in set_after_add if n not in fields] if missing: raise ValueError( "Some set_after_add are not included in the form", missing) leftover = [n for n in leftover if n not in set_after_add] self.set_after_add += leftover else: self.set_after_add = leftover def _handle_content_factory(self): if self.content_factory is None: self.content_factory = self.content_factory_id def __call__(self): self._processWidgets() self._handle_menu() self._handle_content_factory() self._handle_arguments() self._context.action( discriminator=self._discriminator(), callable=AddViewFactory, args=self._args()+(self.content_factory, self.arguments, self.keyword_arguments, self.set_before_add, self.set_after_add), ) class EditFormDirectiveBase(BaseFormDirective): view = EditView def _default_widget_factory(self, field, request): # `field` is a bound field if field.readonly: iface = IDisplayWidget else: iface = IInputWidget return zope.component.getMultiAdapter( (field, request), iface) class EditFormDirective(EditFormDirectiveBase): default_template = 'edit.pt' title = _('Edit') def _handle_menu(self): if self.menu: menuItemDirective( self._context, self.menu, self.for_ or self.schema, '@@' + self.name, self.title, permission=self.permission, layer=self.layer) def __call__(self): self._processWidgets() self._handle_menu() self._context.action( discriminator=self._discriminator(), callable=EditViewFactory, args=self._args(), ) class FormDirective(EditFormDirective): view = FormView def __init__(self, _context, **kwargs): super(FormDirective, self).__init__(_context, **kwargs) attrs = self.class_.__dict__.keys() if 'template' not in kwargs.keys() and 'update' not in attrs and \ ('getData' not in attrs or 'setData' not in attrs): raise ConfigurationError( "You must specify a class that implements `getData()` " "and `setData()`, if you do not overwrite `update()`.") class SubeditFormDirective(EditFormDirectiveBase): default_template = 'subedit.pt' # default subedit form directive fulledit_path = None fulledit_label = None def __call__(self): self._processWidgets() self._context.action( discriminator = self._discriminator(), callable = EditViewFactory, args = self._args()+(self.fulledit_path, self.fulledit_label), ) class SchemaDisplayDirective(EditFormDirective): view = DisplayView default_template = 'display.pt' def __call__(self): self._processWidgets() self._handle_menu() self._context.action( discriminator = self._discriminator(), callable = DisplayViewFactory, args = self._args()+(self.menu,) ) �����������������������������������������������������������������������������������������������������������������������������������������������������zope.app.form-4.0.2/src/zope/app/form/browser/tests/������������������������������������������������0000755�0001750�0001750�00000000000�11340453312�021633� 5����������������������������������������������������������������������������������������������������ustar �sidnei��������������������������sidnei�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zope.app.form-4.0.2/src/zope/app/form/browser/tests/test_browserwidget.py���������������������������0000644�0001750�0001750�00000001546�11340453312�026141� 0����������������������������������������������������������������������������������������������������ustar �sidnei��������������������������sidnei�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������############################################################################## # # Copyright (c) 2001, 2002 Zope Corporation 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. # ############################################################################## """Test Browser Widget $Id: test_browserwidget.py 107392 2009-12-30 21:07:14Z faassen $ """ # BBB from zope.formlib.tests.test_browserwidget import ( BrowserWidgetTest, SimpleInputWidgetTest, TestWidget, Test) ����������������������������������������������������������������������������������������������������������������������������������������������������������zope.app.form-4.0.2/src/zope/app/form/browser/tests/test_directives.py������������������������������0000644�0001750�0001750�00000025335�11340453312�025415� 0����������������������������������������������������������������������������������������������������ustar �sidnei��������������������������sidnei�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������############################################################################# # # Copyright (c) 2001, 2002 Zope Corporation 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 Directives Tests $Id: test_directives.py 107371 2009-12-30 18:36:02Z faassen $ """ import unittest from cStringIO import StringIO from zope import component from zope.component.testing import PlacelessSetup from zope.configuration.xmlconfig import xmlconfig, XMLConfig from zope.traversing.interfaces import TraversalError from zope.interface import Interface, implements from zope.publisher.browser import TestRequest from zope.schema import TextLine, Int from zope.app.form.browser import TextWidget from zope.app.form.tests import utils template = """<configure xmlns='http://namespaces.zope.org/zope' xmlns:browser='http://namespaces.zope.org/browser' i18n_domain='zope'> %s </configure>""" request = TestRequest() class Schema(Interface): text = TextLine( title=u'Text', description=u'Nice text', required=False) class IC(Schema): pass class Ob(object): implements(IC) unwrapped_ob = Ob() ob = utils.securityWrap(unwrapped_ob, IC) class ISomeWidget(Interface): displayWidth = Int( title=u"Display Width", default=20, required=True) class SomeWidget(TextWidget): implements(ISomeWidget) class Test(PlacelessSetup, unittest.TestCase): def setUp(self): super(Test, self).setUp() import zope.component XMLConfig('meta.zcml', zope.component)() import zope.app.form.browser XMLConfig('meta.zcml', zope.app.form.browser)() import zope.browsermenu XMLConfig('meta.zcml', zope.browsermenu)() from zope.traversing.adapters import DefaultTraversable from zope.traversing.interfaces import ITraversable component.provideAdapter(DefaultTraversable, (None,), ITraversable) def testAddForm(self): self.assertEqual( component.queryMultiAdapter((ob, request), name='add.html'), None) xmlconfig(StringIO(template % (""" <view type="zope.publisher.interfaces.browser.IBrowserRequest" for="zope.schema.interfaces.ITextLine" provides="zope.formlib.interfaces.IInputWidget" factory="zope.app.form.browser.TextWidget" permission="zope.Public" /> <browser:addform for="zope.app.form.browser.tests.test_directives.IC" schema="zope.app.form.browser.tests.test_directives.Schema" name="add.html" label="Add a ZPT page" fields="text" permission="zope.Public" /> """))) v = component.getMultiAdapter((ob, request), name='add.html') # expect to fail as standard macros are not configured self.assertRaises(TraversalError, v) def testEditForm(self): self.assertEqual( component.queryMultiAdapter((ob, request), name='edit.html'), None) xmlconfig(StringIO(template % (""" <view type="zope.publisher.interfaces.browser.IBrowserRequest" for="zope.schema.interfaces.ITextLine" provides="zope.formlib.interfaces.IInputWidget" factory="zope.app.form.browser.TextWidget" permission="zope.Public" /> <browser:editform for="zope.app.form.browser.tests.test_directives.IC" schema="zope.app.form.browser.tests.test_directives.Schema" name="edit.html" label="Edit a ZPT page" fields="text" permission="zope.Public" /> """))) v = component.getMultiAdapter((ob, request), name='edit.html') # expect to fail as standard macros are not configured self.assertRaises(TraversalError, v) def testEditFormWithMenu(self): self.assertEqual( component.queryMultiAdapter((ob, request), name='edit.html'), None) xmlconfig(StringIO(template % (''' <browser:menu id="test_menu" title="Test menu"/> <view type="zope.publisher.interfaces.browser.IBrowserRequest" for="zope.schema.interfaces.ITextLine" provides="zope.formlib.interfaces.IInputWidget" factory="zope.app.form.browser.TextWidget" permission="zope.Public" /> <browser:editform for="zope.app.form.browser.tests.test_directives.IC" schema="zope.app.form.browser.tests.test_directives.Schema" name="edit.html" label="Edit a ZPT page" fields="text" permission="zope.Public" menu="test_menu" title="Test View" /> '''))) v = component.queryMultiAdapter((ob, request), name='edit.html') # expect to fail as standard macros are not configured self.assertRaises(TraversalError, v) def testSchemaDisplay(self): self.assertEqual( component.queryMultiAdapter((ob, request), name='view.html'), None) xmlconfig(StringIO(template % (''' <view type="zope.publisher.interfaces.browser.IBrowserRequest" for="zope.schema.interfaces.IField" provides="zope.formlib.interfaces.IDisplayWidget" factory="zope.app.form.browser.DisplayWidget" permission="zope.Public" /> <browser:schemadisplay for="zope.app.form.browser.tests.test_directives.IC" schema="zope.app.form.browser.tests.test_directives.Schema" name="view.html" label="View a ZPT page" fields="text" permission="zope.Public" /> '''))) v = component.queryMultiAdapter((ob, request), name='view.html') # expect to fail as standard macros are not configured self.assertRaises(TraversalError, v) def testAddFormWithWidget(self): self.assertEqual( component.queryMultiAdapter((ob, request), name='add.html'), None) xmlconfig(StringIO(template % (''' <view type="zope.publisher.interfaces.browser.IBrowserRequest" for="zope.schema.interfaces.ITextLine" provides="zope.formlib.interfaces.IInputWidget" factory="zope.app.form.browser.TextWidget" permission="zope.Public" /> <browser:addform for="zope.app.form.browser.tests.test_directives.IC" schema="zope.app.form.browser.tests.test_directives.Schema" name="add.html" label="Add a ZPT page" fields="text" permission="zope.Public"> <widget field="text" class="zope.app.form.browser.tests.test_directives.SomeWidget" displayWidth="30" extra="foo" /> </browser:addform> ''')), ) view = component.queryMultiAdapter((ob, request), name='add.html') self.assert_(hasattr(view, 'text_widget')) self.assert_(isinstance(view.text_widget, SomeWidget)) self.assertEqual(view.text_widget.extra, u'foo') self.assertEqual(view.text_widget.displayWidth, 30) def testEditFormWithWidget(self): self.assertEqual( component.queryMultiAdapter((ob, request), name='edit.html'), None) xmlconfig(StringIO(template % (''' <view type="zope.publisher.interfaces.browser.IBrowserRequest" for="zope.schema.interfaces.ITextLine" provides="zope.formlib.interfaces.IInputWidget" factory="zope.app.form.browser.TextWidget" permission="zope.Public" /> <browser:editform for="zope.app.form.browser.tests.test_directives.IC" schema="zope.app.form.browser.tests.test_directives.Schema" name="edit.html" label="Edit a ZPT page" fields="text" permission="zope.Public"> <widget field="text" class="zope.app.form.browser.tests.test_directives.SomeWidget" displayWidth="30" extra="foo" /> </browser:editform> ''')), ) view = component.queryMultiAdapter((ob, request), name='edit.html') self.assert_(hasattr(view, 'text_widget')) self.assert_(isinstance(view.text_widget, SomeWidget)) self.assertEqual(view.text_widget.extra, u'foo') self.assertEqual(view.text_widget.displayWidth, 30) def testSchemaDisplayWithWidget(self): self.assertEqual( component.queryMultiAdapter((ob, request), name='view.html'), None) xmlconfig(StringIO(template % (''' <view type="zope.publisher.interfaces.browser.IBrowserRequest" for="zope.schema.interfaces.IField" provides="zope.formlib.interfaces.IDisplayWidget" factory="zope.app.form.browser.DisplayWidget" permission="zope.Public" /> <browser:schemadisplay for="zope.app.form.browser.tests.test_directives.IC" schema="zope.app.form.browser.tests.test_directives.Schema" name="view.html" label="View a ZPT page" fields="text" permission="zope.Public"> <browser:widget field="text" class="zope.app.form.browser.tests.test_directives.SomeWidget" displayWidth="30" extra="foo" /> </browser:schemadisplay> '''))) view = component.queryMultiAdapter((ob, request), name='view.html') self.assert_(hasattr(view, 'text_widget')) self.assert_(isinstance(view.text_widget, SomeWidget)) self.assertEqual(view.text_widget.extra, u'foo') self.assertEqual(view.text_widget.displayWidth, 30) def test_suite(): loader=unittest.TestLoader() return loader.loadTestsFromTestCase(Test) if __name__=='__main__': unittest.TextTestRunner().run(test_suite()) ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zope.app.form-4.0.2/src/zope/app/form/browser/tests/test_functional_editview.py���������������������0000644�0001750�0001750�00000006551�11340453312�027315� 0����������������������������������������������������������������������������������������������������ustar �sidnei��������������������������sidnei�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������############################################################################## # # Copyright (c) 2001, 2002 Zope Corporation 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. # ############################################################################## """Editview tests $Id: test_functional_editview.py 81040 2007-10-24 15:27:12Z srichter $ """ import unittest import transaction from persistent import Persistent import zope.security.checker from zope.interface import Interface, implements from zope.schema import TextLine from zope.traversing.api import traverse from zope.app.form.browser.editview import EditView from zope.app.form.testing import AppFormLayer from zope.app.form.browser.tests.support import * from zope.app.testing.functional import BrowserTestCase class IFoo(Interface): optional_text = TextLine(required=False) required_text = TextLine(required=True) class Foo(Persistent): implements(IFoo) class Test(BrowserTestCase): def setUp(self): BrowserTestCase.setUp(self) registerEditForm(IFoo) defineSecurity(Foo, IFoo) def test_rollback_on_error(self): """Tests rollback when a widget error occurs. When one or more errors are generated by input widgets, the current transaction should be rolledback to ensure object integrity. """ self.getRootFolder()['foo'] = Foo() self.getRootFolder()['foo'].required_text = u'initial required' self.getRootFolder()['foo'].optional_text = u'initial optional' transaction.commit() # submit form with legal value for optional_text and invalid for # required_text old_update = EditView.update try: def new_update(self): # This update changes something after form validation has failed. # Side effects like this should not be committed. # http://www.zope.org/Collectors/Zope3-dev/655 result = old_update(self) self.context.required_text = u'changed after form validation' return result EditView.update = new_update response = self.publish('/foo/edit.html', form={ 'field.optional_text': u'', 'field.required_text': u'', 'UPDATE_SUBMIT': ''}) self.assertEqual(response.getStatus(), 200) finally: EditView.update = old_update # confirm that one errors exists self.assert_(patternExists( 'There are <strong>1</strong> input errors.', response.getBody())) # confirm that foo was not modified foo = traverse(self.getRootFolder(), 'foo') self.assertEquals(foo.required_text, u'initial required') self.assertEquals(foo.optional_text, u'initial optional') def test_suite(): suite = unittest.TestSuite() Test.layer = AppFormLayer suite.addTest(unittest.makeSuite(Test)) return suite if __name__=='__main__': unittest.main(defaultTest='test_suite') �������������������������������������������������������������������������������������������������������������������������������������������������������zope.app.form-4.0.2/src/zope/app/form/browser/tests/testconfigure.zcml������������������������������0000644�0001750�0001750�00000000741�11340453312�025405� 0����������������������������������������������������������������������������������������������������ustar �sidnei��������������������������sidnei�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<configure xmlns='http://namespaces.zope.org/zope' xmlns:browser='http://namespaces.zope.org/browser' i18n_domain='zope' > <!-- Test view for folders --> <browser:pages permission="zope.View" for="zope.site.interfaces.IFolder" class=".SchemaTestObject.EditFactory"> <browser:page name="testSchemaFormView.html" attribute="form" /> <browser:page name="testSchemaFormAction.html" attribute="action" /> </browser:pages> </configure> �������������������������������zope.app.form-4.0.2/src/zope/app/form/browser/tests/test_functional_i18n.py�������������������������0000644�0001750�0001750�00000004321�11340453312�026245� 0����������������������������������������������������������������������������������������������������ustar �sidnei��������������������������sidnei�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������############################################################################## # # Copyright (c) 2005 Zope Corporation 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. # ############################################################################## """Test form i18n $Id: test_functional_i18n.py 107401 2009-12-30 22:56:20Z faassen $ """ import re import unittest import doctest from persistent import Persistent from zope.testing import renormalizing from zope.interface import Interface, implements from zope.schema import TextLine, Text, Int, List from zope.i18nmessageid import MessageFactory from zope.app.testing.functional import FunctionalDocFileSuite from zope.app.form.testing import AppFormLayer _ = MessageFactory('formtest') __docformat__ = "reStructuredText" class IFieldContent(Interface): title = TextLine( title=_(u"Title"), description=_(u"A short description of the event."), default=u"", required=True ) description = Text( title=_(u"Description"), description=_(u"A long description of the event."), default=u"", required=False ) somenumber = Int( title=_(u"Some number"), default=0, required=False ) somelist = List( title=_(u"Some List"), value_type=TextLine(title=_(u"Some item")), default=[], required=False ) class FieldContent(Persistent): implements(IFieldContent) checker = renormalizing.RENormalizing([ (re.compile(r"HTTP/1\.1 200 .*"), "HTTP/1.1 200 OK"), ]) def test_suite(): i18n = FunctionalDocFileSuite('i18n.txt', package='zope.app.form.browser', checker=checker) i18n.layer = AppFormLayer return unittest.TestSuite([ i18n, ]) if __name__ == '__main__': unittest.main(defaultTest='test_suite') ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zope.app.form-4.0.2/src/zope/app/form/browser/tests/__init__.py�������������������������������������0000644�0001750�0001750�00000000075�11340453312�023746� 0����������������������������������������������������������������������������������������������������ustar �sidnei��������������������������sidnei�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # This file is necessary to make this directory a package. �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zope.app.form-4.0.2/src/zope/app/form/browser/tests/test_editview.py��������������������������������0000644�0001750�0001750�00000014354�11340453312�025073� 0����������������������������������������������������������������������������������������������������ustar �sidnei��������������������������sidnei�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������############################################################################## # # Copyright (c) 2001, 2002 Zope Corporation 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. # ############################################################################## """Edit View Tests $Id: test_editview.py 107371 2009-12-30 18:36:02Z faassen $ """ import unittest from zope.component.eventtesting import getEvents, clearEvents from zope.component.testing import PlacelessSetup from zope.interface import Interface, implements from zope.location.interfaces import ILocation from zope.publisher.browser import TestRequest from zope.schema import TextLine, accessors from zope.schema.interfaces import ITextLine from zope.app.testing import ztapi from zope.app.form.browser import TextWidget from zope.app.form.browser.editview import EditView from zope.app.form.browser.submit import Update from zope.formlib.interfaces import IInputWidget from zope.app.form.tests import utils class I(Interface): foo = TextLine(title=u"Foo") bar = TextLine(title=u"Bar") a = TextLine(title=u"A") b = TextLine(title=u"B", min_length=0, required=False) getbaz, setbaz = accessors(TextLine(title=u"Baz")) class EV(EditView): schema = I object_factories = [] class C(object): implements(I) foo = u"c foo" bar = u"c bar" a = u"c a" b = u"c b" __Security_checker__ = utils.SchemaChecker(I) _baz = u"c baz" def getbaz(self): return self._baz def setbaz(self, v): self._baz = v class IFoo(Interface): foo = TextLine(title=u"Foo") class IBar(Interface): bar = TextLine(title=u"Bar") class Foo(object): implements(IFoo) __Security_checker__ = utils.SchemaChecker(IFoo) foo = u'Foo foo' class ConformFoo(object): implements(IFoo) foo = u'Foo foo' def __conform__(self, interface): if interface is IBar: return OtherFooBarAdapter(self) class FooBarAdapter(object): implements(IBar, ILocation) __used_for__ = IFoo def __init__(self, context): self.context = context def getbar(self): return self.context.foo def setbar(self, v): self.context.foo = v bar = property(getbar, setbar) __Security_checker__ = utils.SchemaChecker(IBar) class OtherFooBarAdapter(FooBarAdapter): pass class BarV(EditView): schema = IBar object_factories = [] class Test(PlacelessSetup, unittest.TestCase): def setUp(self): super(Test, self).setUp() ztapi.browserViewProviding(ITextLine, TextWidget, IInputWidget) ztapi.provideAdapter(IFoo, IBar, FooBarAdapter) clearEvents() def test_setPrefix_and_widgets(self): v = EV(C(), TestRequest()) v.setPrefix("test") self.assertEqual( [w.name for w in v.widgets()], ['test.foo', 'test.bar', 'test.a', 'test.b', 'test.getbaz'] ) def test_empty_prefix(self): v = EV(C(), TestRequest()) v.setPrefix("") self.assertEqual( [w.name for w in v.widgets()], ['foo', 'bar', 'a', 'b', 'getbaz'] ) def test_fail_wo_adapter(self): c = Foo() request = TestRequest() self.assertRaises(TypeError, EV, c, request) def test_update_no_update(self): c = C() request = TestRequest() v = EV(c, request) self.assertEqual(v.update(), '') self.assertEqual(c.foo, u'c foo') self.assertEqual(c.bar, u'c bar') self.assertEqual(c.a , u'c a') self.assertEqual(c.b , u'c b') self.assertEqual(c.getbaz(), u'c baz') request.form['field.foo'] = u'r foo' request.form['field.bar'] = u'r bar' request.form['field.a'] = u'r a' request.form['field.b'] = u'r b' request.form['field.getbaz'] = u'r baz' self.assertEqual(v.update(), '') self.assertEqual(c.foo, u'c foo') self.assertEqual(c.bar, u'c bar') self.assertEqual(c.a , u'c a') self.assertEqual(c.b , u'c b') self.assertEqual(c.getbaz(), u'c baz') self.failIf(getEvents()) def test_update(self): c = C() request = TestRequest() v = EV(c, request) request.form[Update] = '' request.form['field.foo'] = u'r foo' request.form['field.bar'] = u'r bar' request.form['field.getbaz'] = u'r baz' request.form['field.a'] = u'c a' message = v.update() self.failUnless(message.startswith('Updated '), message) self.assertEqual(c.foo, u'r foo') self.assertEqual(c.bar, u'r bar') self.assertEqual(c.a , u'c a') self.assertEqual(c.b , u'c b') # missing from form - unchanged self.assertEqual(c.getbaz(), u'r baz') # Verify that calling update multiple times has no effect c.__dict__.clear() self.assertEqual(v.update(), message) self.assertEqual(c.foo, u'c foo') self.assertEqual(c.bar, u'c bar') self.assertEqual(c.a , u'c a') self.assertEqual(c.b , u'c b') self.assertEqual(c.getbaz(), u'c baz') def test_update_via_adapter(self): f = Foo() request = TestRequest() v = BarV(f, request) # check adapter self.assertEqual(f.foo, u'Foo foo') a = IBar(f) self.assertEqual(a.bar, u'Foo foo') # update request.form[Update] = '' request.form['field.bar'] = u'r bar' message = v.update() self.failUnless(message.startswith('Updated '), message) self.assertEqual(a.bar, u'r bar') # wrong update self.failIf(getEvents()) def test_setUpWidget_via_conform_adapter(self): f = ConformFoo() request = TestRequest() v = BarV(f, request) def test_suite(): return unittest.makeSuite(Test) if __name__=='__main__': unittest.main(defaultTest='test_suite') ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zope.app.form-4.0.2/src/zope/app/form/browser/tests/testeditform.pt���������������������������������0000644�0001750�0001750�00000002053�11340453312�024711� 0����������������������������������������������������������������������������������������������������ustar �sidnei��������������������������sidnei�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<html> <head> <title>Simple Edit Form

This is a Schema produced form

Errors:
:

Title:
zope.app.form-4.0.2/src/zope/app/form/browser/tests/testlabeltranslation.po0000644000175000017500000000114311340453312026430 0ustar sidneisidnei# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2003-03-25 15:01-0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=us-ascii\n" "Content-Transfer-Encoding: 8bit\n" #: test_browserwidget.py:34 msgid "Foo Title" msgstr "oofay itletay" zope.app.form-4.0.2/src/zope/app/form/browser/tests/test_widgetdirective.py0000644000175000017500000000555411340453312026437 0ustar sidneisidnei############################################################################## # # Copyright (c) 2004 Zope Corporation 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. # ############################################################################## """Tests for the subdirective for the generated form pages. $Id: test_widgetdirective.py 107371 2009-12-30 18:36:02Z faassen $ """ import unittest import zope.component import zope.interface import zope.configuration.xmlconfig import zope.publisher.browser import zope.schema from zope.browser.interfaces import IAdding import zope.app.form.browser.interfaces import zope.formlib.interfaces from zope.app.form.tests import utils import zope.component.testing __docformat__ = "reStructuredText" class IContent(zope.interface.Interface): field = zope.schema.TextLine( title=u"Field", description=u"Sample input field", required=False, ) class Content(object): zope.interface.implements(IContent) __Security_checker__ = utils.SchemaChecker(IContent) __parent__ = None __name__ = "sample-content" field = None class Adding(object): zope.interface.implements(IAdding) def add(self, content): self.content = content class WidgetDirectiveTestCase(zope.component.testing.PlacelessSetup, unittest.TestCase): def setUp(self): super(WidgetDirectiveTestCase, self).setUp() zope.configuration.xmlconfig.file("widgetDirectives.zcml", zope.app.form.browser.tests) def get_widget(self, name, context): request = zope.publisher.browser.TestRequest() view = zope.component.getMultiAdapter((context, request), name=name) return view.field_widget def test_addform_widget_without_class(self): w = self.get_widget("add.html", Adding()) self.assert_(zope.formlib.interfaces.IInputWidget.providedBy(w)) self.assertEqual(w.extraAttr, "42") def test_editform_widget_without_class(self): w = self.get_widget("edit.html", Content()) self.assert_(zope.formlib.interfaces.IInputWidget.providedBy(w)) self.assertEqual(w.extraAttr, "84") def test_subeditform_widget_without_class(self): w = self.get_widget("subedit.html", Content()) self.assert_(zope.formlib.interfaces.IInputWidget.providedBy(w)) self.assertEqual(w.extraAttr, "168") def test_suite(): return unittest.makeSuite(WidgetDirectiveTestCase) zope.app.form-4.0.2/src/zope/app/form/browser/tests/locales/0000755000175000017500000000000011340453312023255 5ustar sidneisidneizope.app.form-4.0.2/src/zope/app/form/browser/tests/locales/de/0000755000175000017500000000000011340453341023647 5ustar sidneisidneizope.app.form-4.0.2/src/zope/app/form/browser/tests/locales/de/LC_MESSAGES/0000755000175000017500000000000011340453312025432 5ustar sidneisidneizope.app.form-4.0.2/src/zope/app/form/browser/tests/locales/de/LC_MESSAGES/formtest.po0000644000175000017500000000267511340453312027647 0ustar sidneisidnei############################################################################## # # Copyright (c) 2005 Zope Corporation 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. # ############################################################################## msgid "" msgstr "" "Project-Id-Version: Five form tests\n" "POT-Creation-Date: \n" "PO-Revision-Date: 2005-07-29 11:38+0100\n" "Last-Translator: \n" "Language-Team: Five Developers \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" msgid "Title" msgstr "Titel" msgid "A short description of the event." msgstr "Eine kurze Beschreibung des Ereignisses." msgid "Description" msgstr "Beschreibung" msgid "A long description of the event." msgstr "Eine ausführliche Beschreibung des Ereignisses." msgid "Some number" msgstr "Irgendeine Zahl" msgid "Some List" msgstr "Irgendeine Liste" msgid "Some item" msgstr "Irgendeine Element" msgid "Edit Field Content" msgstr "Felderinhalt bearbeiten" msgid "Add Field Content" msgstr "Felderinhalt hinzufügen" zope.app.form-4.0.2/src/zope/app/form/browser/tests/locales/de/LC_MESSAGES/formtest.mo0000644000175000017500000000153411340453312027635 0ustar sidneisidneiÞ• l ¼ð ñ!4 FR e o y…þ‹0Š(»ä ý "3FV  A long description of the event.A short description of the event.Add Field ContentDescriptionEdit Field ContentSome ListSome itemSome numberTitleProject-Id-Version: Five form tests POT-Creation-Date: PO-Revision-Date: 2005-07-29 11:38+0100 Last-Translator: Language-Team: Five Developers MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Eine ausführliche Beschreibung des Ereignisses.Eine kurze Beschreibung des Ereignisses.Felderinhalt hinzufügenBeschreibungFelderinhalt bearbeitenIrgendeine ListeIrgendeine ElementIrgendeine ZahlTitelzope.app.form-4.0.2/src/zope/app/form/browser/tests/locales/formtest.pot0000644000175000017500000000233611340453312025650 0ustar sidneisidnei############################################################################## # # Copyright (c) 2005 Zope Corporation 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. # ############################################################################## msgid "" msgstr "" "Project-Id-Version: Five form tests\n" "POT-Creation-Date: \n" "PO-Revision-Date: \n" "Last-Translator: \n" "Language-Team: Five Developers \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" msgid "Title" msgstr "" msgid "A short description of the event." msgstr "" msgid "Description" msgstr "" msgid "A long description of the event." msgstr "" msgid "Some number" msgstr "" msgid "Some List" msgstr "" msgid "Some item" msgstr "" msgid "Edit Field Content" msgstr "" msgid "Add Field Content" msgstr "" zope.app.form-4.0.2/src/zope/app/form/browser/tests/i18n.zcml0000644000175000017500000000101311340453312023274 0ustar sidneisidnei zope.app.form-4.0.2/src/zope/app/form/browser/tests/widgetDirectives.zcml0000644000175000017500000000231611340453312026031 0ustar sidneisidnei zope.app.form-4.0.2/src/zope/app/form/browser/tests/testlabeltranslation.mo0000644000175000017500000000061311340453312026426 0ustar sidneisidneiÞ•,<P Q![ }Foo TitleProject-Id-Version: PACKAGE VERSION POT-Creation-Date: 2003-03-25 15:01-0500 PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE Last-Translator: FULL NAME Language-Team: LANGUAGE MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 8bit oofay itletayzope.app.form-4.0.2/src/zope/app/form/browser/tests/support.py0000644000175000017500000000726111340453312023727 0ustar sidneisidnei############################################################################## # # Copyright (c) 2003 Zope Corporation 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. # ############################################################################## """General test support. $Id: support.py 107413 2009-12-31 00:31:07Z faassen $ """ import re from zope.configuration import xmlconfig from zope.formlib.tests.support import (VerifyResults, patternExists) def registerEditForm(schema, widgets={}): """Registers an edit form for the specified schema. widgets is a mapping of field name to dict. The dict for each field must contain a 'class' item, which is the widget class, and any additional widget attributes (e.g. text field size, rows, cols, etc.) """ widgetsXml = [] for field in widgets: widgetsXml.append('') xmlconfig.string(""" %s """ % (schema.__identifier__, ''.join(widgetsXml))) def defineSecurity(class_, schema): class_ = '%s.%s' % (class_.__module__, class_.__name__) schema = schema.__identifier__ xmlconfig.string(""" """ % (class_, schema, schema)) def defineWidgetView(field_interface, widget_class, view_type): field_interface = field_interface.__identifier__ widget_class = '%s.%s' % (widget_class.__module__, widget_class.__name__) view_type = '%s.%s' % (view_type.__module__, view_type.__name__) xmlconfig.string(""" """ % (field_interface, widget_class, view_type)) def validationErrorExists(field, error_msg, source): regex = re.compile(r'%s.*?name="field.(\w+)(?:\.[\w\.]+)?"' % (error_msg,), re.DOTALL) # compile it first because Python 2.3 doesn't allow flags in findall return field in regex.findall(source) def missingInputErrorExists(field, source): return validationErrorExists(field, 'Required input is missing.', source) def invalidValueErrorExists(field, source): # assumes this error is displayed for select elements return patternExists( 'Invalid value.*name="field.%s".*' % field, source, re.DOTALL) def updatedMsgExists(source): return patternExists('

Updated .*

', source) zope.app.form-4.0.2/src/zope/app/form/browser/tests/test_form.py0000644000175000017500000000260211340453312024207 0ustar sidneisidnei############################################################################## # # Copyright (c) 2004 Zope Corporation 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. # ############################################################################## """Tests for the ZCML Documentation Module $Id: test_form.py 107401 2009-12-30 22:56:20Z faassen $ """ import unittest import doctest from zope.schema.interfaces import ITextLine from zope.component import testing from zope.app.testing import ztapi from zope.app.form.browser import TextWidget from zope.formlib.interfaces import IInputWidget def setUp(test): testing.setUp() ztapi.browserViewProviding(ITextLine, TextWidget, IInputWidget) def test_suite(): return unittest.TestSuite(( doctest.DocFileSuite('../form.txt', setUp=setUp, tearDown=testing.tearDown, optionflags=doctest.NORMALIZE_WHITESPACE), )) if __name__ == '__main__': unittest.main(defaultTest='test_suite') zope.app.form-4.0.2/src/zope/app/form/browser/tests/test_add.py0000644000175000017500000003575311340453312024011 0ustar sidneisidnei############################################################################## # # Copyright (c) 2001, 2002 Zope Corporation 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. # ############################################################################## """Test add-form $Id: test_add.py 107376 2009-12-30 19:21:24Z faassen $ """ import unittest from zope.browser.interfaces import IAdding from zope.component import getMultiAdapter from zope.component.eventtesting import getEvents from zope.component.interfaces import IFactory from zope.component.interfaces import IComponentLookup from zope.component.factory import Factory from zope.interface import Interface, implements from zope.lifecycleevent.interfaces import IObjectCreatedEvent, IObjectModifiedEvent from zope.publisher.browser import TestRequest from zope.publisher.interfaces.browser import IBrowserRequest from zope.publisher.interfaces.browser import IDefaultBrowserLayer from zope.schema import TextLine, accessors from zope.security.checker import CheckerPublic from zope.site.site import SiteManagerAdapter from zope.formlib.widget import CustomWidgetFactory from zope.app.form.browser import TextWidget as Text from zope.app.form.browser.add import AddViewFactory, AddView from zope.app.form.browser.metaconfigure import AddFormDirective from zope.app.form.browser.submit import Update from zope.app.testing import ztapi # Foo needs to be imported as globals() are checked from zope.app.form.browser.tests.test_editview import IFoo, IBar, Foo from zope.app.form.browser.tests.test_editview import FooBarAdapter from zope.component.testing import PlacelessSetup as CAPlacelessSetup from zope.component.eventtesting import PlacelessSetup as EventPlacelessSetup class PlacelessSetup(CAPlacelessSetup, EventPlacelessSetup): def setUp(self, doctesttest=None): CAPlacelessSetup.setUp(self) EventPlacelessSetup.setUp(self) class Context(object): def action(self, discriminator, callable, args=(), kw={}): self.last_action = (discriminator, callable, args, kw) class I(Interface): name = TextLine() first = TextLine() last = TextLine() email = TextLine() address = TextLine() getfoo, setfoo = accessors(TextLine()) extra1 = TextLine() extra2 = TextLine(required=False) class C(object): implements(I) def __init__(self, *args, **kw): self.args = args self.kw = kw def getfoo(self): return self._foo def setfoo(self, v): self._foo = v class V(object): name_widget = CustomWidgetFactory(Text) first_widget = CustomWidgetFactory(Text) last_widget = CustomWidgetFactory(Text) email_widget = CustomWidgetFactory(Text) address_widget = CustomWidgetFactory(Text) getfoo_widget = CustomWidgetFactory(Text) extra1_widget = CustomWidgetFactory(Text) extra2_widget = CustomWidgetFactory(Text) class FooV(object): bar_widget = CustomWidgetFactory(Text) class SampleData(object): name = u"foo" first = u"bar" last = u"baz" email = u"baz@dot.com" address = u"aa" getfoo = u"foo" extra1 = u"extra1" extra2 = u"extra2" class Test(PlacelessSetup, unittest.TestCase): def setUp(self): self._context = Context() super(Test, self).setUp() ztapi.provideAdapter(IFoo, IBar, FooBarAdapter) def _invoke_add(self, schema=I, name="addthis", permission="zope.Public", label="Add this", content_factory=C, class_=V, arguments=['first', 'last'], keyword_arguments=['email'], set_before_add=['getfoo'], set_after_add=['extra1'], fields=None): """ Call the 'add' factory to process arguments into 'args'.""" AddFormDirective(self._context, schema=schema, name=name, permission=permission, label=label, content_factory=content_factory, class_=class_, arguments=arguments, keyword_arguments=keyword_arguments, set_before_add=set_before_add, set_after_add=set_after_add, fields=fields )() def test_add_no_fields(self): _context = self._context self._invoke_add() result1 = _context.last_action self._invoke_add( fields="name first last email address getfoo extra1 extra2".split(), ) result2 = _context.last_action self.assertEqual(result1, result2) def test_add_error_handling(self): # cannot use a field in arguments if it is not mentioned in fields self.assertRaises(ValueError, self._invoke_add, fields="first email getfoo extra1".split()) # cannot use a field in keyword_arguments if it is not # mentioned in fields self.assertRaises(ValueError, self._invoke_add, fields="first last getfoo extra1".split()) # cannot use a field in set_before_add if it is not mentioned in fields self.assertRaises(ValueError, self._invoke_add, fields="first last email extra1".split()) # cannot use a field in set_after_add if it is not mentioned in fields self.assertRaises(ValueError, self._invoke_add, fields="first last email getfoo".split()) # cannot use an optional field in arguments self.assertRaises(ValueError, self._invoke_add, arguments=["extra2"]) def test_add(self, args=None): self._invoke_add() (descriminator, callable, args, kw) = self._context.last_action self.assertEqual(descriminator, ('view', IAdding, 'addthis', IBrowserRequest, IDefaultBrowserLayer)) self.assertEqual(callable, AddViewFactory) (name, schema, label, permission, layer, template, default_template, bases, for_, fields, content_factory, arguments, keyword_arguments, set_before_add, set_after_add) = args self.assertEqual(name, 'addthis') self.assertEqual(schema, I) self.assertEqual(label, 'Add this') self.assertEqual(permission, CheckerPublic) # 'zope.Public' translated self.assertEqual(layer, IDefaultBrowserLayer) self.assertEqual(template, 'add.pt') self.assertEqual(default_template, 'add.pt') self.assertEqual(bases, (V, AddView, )) self.assertEqual(for_, IAdding) self.assertEqual(" ".join(fields), "name first last email address getfoo extra1 extra2") self.assertEqual(content_factory, C) self.assertEqual(" ".join(arguments), "first last") self.assertEqual(" ".join(keyword_arguments), "email") self.assertEqual(" ".join(set_before_add), "getfoo") self.assertEqual(" ".join(set_after_add), "extra1 name address extra2") return args def test_add_content_factory_id(self, args=None): self._invoke_add(content_factory='C') (descriminator, callable, args, kw) = self._context.last_action self.assertEqual(descriminator, ('view', IAdding, 'addthis', IBrowserRequest, IDefaultBrowserLayer)) self.assertEqual(callable, AddViewFactory) (name, schema, label, permission, layer, template, default_template, bases, for_, fields, content_factory, arguments, keyword_arguments, set_before_add, set_after_add) = args self.assertEqual(name, 'addthis') self.assertEqual(schema, I) self.assertEqual(label, 'Add this') self.assertEqual(permission, CheckerPublic) # 'zope.Public' translated self.assertEqual(layer, IDefaultBrowserLayer) self.assertEqual(template, 'add.pt') self.assertEqual(default_template, 'add.pt') self.assertEqual(bases, (V, AddView, )) self.assertEqual(for_, IAdding) self.assertEqual(" ".join(fields), "name first last email address getfoo extra1 extra2") self.assertEqual(content_factory, 'C') self.assertEqual(" ".join(arguments), "first last") self.assertEqual(" ".join(keyword_arguments), "email") self.assertEqual(" ".join(set_before_add), "getfoo") self.assertEqual(" ".join(set_after_add), "extra1 name address extra2") return args def test_create(self): class Adding(object): implements(IAdding) def __init__(self, test): self.test = test def add(self, ob): self.ob = ob self.test.assertEqual( ob.__dict__, {'args': ("bar", "baz"), 'kw': {'email': 'baz@dot.com'}, '_foo': 'foo', }) return ob def nextURL(self): return "." adding = Adding(self) self._invoke_add() (descriminator, callable, args, kw) = self._context.last_action factory = AddViewFactory(*args) request = TestRequest() view = getMultiAdapter((adding, request), name='addthis') content = view.create('a',0,abc='def') self.failUnless(isinstance(content, C)) self.assertEqual(content.args, ('a', 0)) self.assertEqual(content.kw, {'abc':'def'}) def test_create_content_factory_id(self): class Adding(object): implements(IAdding) def __init__(self, test): self.test = test def add(self, ob): self.ob = ob self.test.assertEqual( ob.__dict__, {'args': ("bar", "baz"), 'kw': {'email': 'baz@dot.com'}, '_foo': 'foo', }) return ob def nextURL(self): return "." # register content factory for content factory id lookup ztapi.provideAdapter(None, IComponentLookup, SiteManagerAdapter) ztapi.provideUtility(IFactory, Factory(C), name='C') adding = Adding(self) self._invoke_add(content_factory='C') (descriminator, callable, args, kw) = self._context.last_action factory = AddViewFactory(*args) request = TestRequest() view = getMultiAdapter((adding, request), name='addthis') content = view.create('a',0,abc='def') self.failUnless(isinstance(content, C)) self.assertEqual(content.args, ('a', 0)) self.assertEqual(content.kw, {'abc':'def'}) def test_createAndAdd(self): class Adding(object): implements(IAdding) def __init__(self, test): self.test = test def add(self, ob): self.ob = ob self.test.assertEqual( ob.__dict__, {'args': ("bar", "baz"), 'kw': {'email': 'baz@dot.com'}, '_foo': 'foo', }) return ob def nextURL(self): return "." adding = Adding(self) self._invoke_add() (descriminator, callable, args, kw) = self._context.last_action factory = AddViewFactory(*args) request = TestRequest() view = getMultiAdapter((adding, request), name='addthis') view.createAndAdd(SampleData.__dict__) self.assertEqual(adding.ob.extra1, "extra1") self.assertEqual(adding.ob.extra2, "extra2") self.assertEqual(adding.ob.name, "foo") self.assertEqual(adding.ob.address, "aa") self.assertEqual(len(getEvents(IObjectCreatedEvent)), 1) self.assertEqual(len(getEvents(IObjectModifiedEvent)), 1) def test_createAndAdd_w_adapter(self): class Adding(object): implements(IAdding) def __init__(self, test): self.test = test def add(self, ob): self.ob = ob self.test.assertEqual(ob.__dict__, {'foo': 'bar'}) return ob def nextURL(self): return "." adding = Adding(self) self._invoke_add( schema=IBar, name="addthis", permission="zope.Public", label="Add this", content_factory=Foo, class_=FooV, arguments=None, keyword_arguments=None, set_before_add=["bar"], set_after_add=None, fields=None ) (descriminator, callable, args, kw) = self._context.last_action factory = AddViewFactory(*args) request = TestRequest() view = getMultiAdapter((adding, request), name='addthis') view.createAndAdd({'bar': 'bar'}) def test_hooks(self): class Adding(object): implements(IAdding) adding = Adding() self._invoke_add() (descriminator, callable, args, kw) = self._context.last_action factory = AddViewFactory(*args) request = TestRequest() request.form.update(dict([ ("field.%s" % k, v) for (k, v) in dict(SampleData.__dict__).items() ])) request.form[Update] = '' view = getMultiAdapter((adding, request), name='addthis') # Add hooks to V l=[None] def add(aself, ob): l[0] = ob self.assertEqual( ob.__dict__, {'args': ("bar", "baz"), 'kw': {'email': 'baz@dot.com'}, '_foo': 'foo', }) return ob V.add = add V.nextURL = lambda self: 'next' try: self.assertEqual(view.update(), '') self.assertEqual(view.errors, ()) self.assertEqual(l[0].extra1, "extra1") self.assertEqual(l[0].extra2, "extra2") self.assertEqual(l[0].name, "foo") self.assertEqual(l[0].address, "aa") self.assertEqual(request.response.getHeader("Location"), "next") # Verify that calling update again doesn't do anything. l[0] = None self.assertEqual(view.update(), '') self.assertEqual(l[0], None) finally: # Uninstall hooks del V.add del V.nextURL def test_suite(): return unittest.makeSuite(Test) if __name__=='__main__': unittest.main(defaultTest='test_suite') zope.app.form-4.0.2/src/zope/app/form/browser/submit.py0000644000175000017500000000157311340453312022354 0ustar sidneisidnei############################################################################## # # Copyright (c) 2002 Zope Corporation 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. # ############################################################################## """Standard submit button names Update -- Name of the standard update submit button $Id: submit.py 26748 2004-07-24 05:51:58Z pruggera $ """ __docformat__ = 'restructuredtext' Next = "NEXT_SUBMIT" Previous = "PREVIOUS_SUBMIT" Update = "UPDATE_SUBMIT" zope.app.form-4.0.2/src/zope/app/form/browser/configure.zcml0000644000175000017500000000176111340453312023346 0ustar sidneisidnei zope.app.form-4.0.2/src/zope/app/form/browser/i18n.txt0000644000175000017500000001010411340453312022005 0ustar sidneisidnei==================== Internationalization ==================== Forms are fully internationalized. The field names, descriptions, labels, and hints are all automatically translated if they are made i18n messages in the schema. Let's take this simple add form... >>> print http(r""" ... GET /addfieldcontent.html HTTP/1.1 ... """, handle_errors=False) HTTP/1.1 200 OK ... with an error... >>> print http(r""" ... POST /addfieldcontent.html HTTP/1.1 ... Content-Length: 670 ... Content-Type: multipart/form-data; boundary=---------------------------19588947601368617292863650127 ... ... -----------------------------19588947601368617292863650127 ... Content-Disposition: form-data; name="field.title" ... ... ... -----------------------------19588947601368617292863650127 ... Content-Disposition: form-data; name="field.description" ... ... ... -----------------------------19588947601368617292863650127 ... Content-Disposition: form-data; name="field.somenumber" ... ... 0 ... -----------------------------19588947601368617292863650127 ... Content-Disposition: form-data; name="UPDATE_SUBMIT" ... ... Hinzufxgen ... -----------------------------19588947601368617292863650127 ... Content-Disposition: form-data; name="add_input_name" ... ... ... -----------------------------19588947601368617292863650127-- ... """, handle_errors=False) HTTP/1.1 200 OK ... There are 1 input errors. ... Translated ========== And now the add form in German: >>> print http(r""" ... GET /addfieldcontent.html HTTP/1.1 ... Accept-Language: de ... """, handle_errors=False) HTTP/1.1 200 OK ...Felderinhalt hinzuf... ...Eine kurz...Titel... ...Eine ausf...Beschreibung... ...Irgendeine Zahl... ...Irgendeine Liste... The same with an input error: >>> print http(r""" ... POST /addfieldcontent.html HTTP/1.1 ... Accept-Language: de ... Content-Length: 670 ... Content-Type: multipart/form-data; boundary=---------------------------19588947601368617292863650127 ... ... -----------------------------19588947601368617292863650127 ... Content-Disposition: form-data; name="field.title" ... ... ... -----------------------------19588947601368617292863650127 ... Content-Disposition: form-data; name="field.description" ... ... ... -----------------------------19588947601368617292863650127 ... Content-Disposition: form-data; name="field.somenumber" ... ... 0 ... -----------------------------19588947601368617292863650127 ... Content-Disposition: form-data; name="UPDATE_SUBMIT" ... ... Hinzufxgen ... -----------------------------19588947601368617292863650127 ... Content-Disposition: form-data; name="add_input_name" ... ... ... -----------------------------19588947601368617292863650127-- ... """, handle_errors=False) HTTP/1.1 200 OK ...Felderinhalt hinzuf... ...1... ...Eine kurz...Titel... ...Eine ausf...Beschreibung... ...Irgendeine Zahl... Source widgets ============== Titles of terms are translated by the source widgets. Let's create a source for which the terms create message ids: >>> import zc.sourcefactory.basic >>> from zope.i18nmessageid import MessageFactory >>> _ = MessageFactory('coffee') >>> class Coffees(zc.sourcefactory.basic.BasicSourceFactory): ... def getValues(self): ... return ['arabica', 'robusta', 'liberica', 'excelsa'] ... def getTitle(self, value): ... return _(value, default='Translated %s' % value) >>> import zope.schema >>> from zope.publisher.browser import TestRequest >>> coffee = zope.schema.Choice( ... __name__ = 'coffee', ... title=u"Kinds of coffee beans", ... source=Coffees()) >>> request = TestRequest() >>> import zope.formlib.source >>> widget = zope.formlib.source.SourceDisplayWidget( ... coffee, coffee.source, request) >>> print widget() Nothing >>> from zope.formlib.interfaces import IBrowserWidget >>> IBrowserWidget.providedBy(widget) True >>> widget.setRenderedValue('arabica') >>> print widget() Translated arabica zope.app.form-4.0.2/src/zope/app/form/browser/sequencewidget.py0000644000175000017500000000164411340453312024064 0ustar sidneisidnei############################################################################## # # Copyright (c) 2004 Zope Corporation 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. # ############################################################################## """Browser widgets for sequences $Id: sequencewidget.py 107385 2009-12-30 20:25:24Z faassen $ """ # BBB implementation moved to zope.formlib.sequencewidget from zope.formlib.sequencewidget import ( SequenceWidget, TupleSequenceWidget, ListSequenceWidget, SequenceDisplayWidget) zope.app.form-4.0.2/src/zope/app/form/browser/objectwidget.py0000644000175000017500000000155511340453312023523 0ustar sidneisidnei############################################################################## # # Copyright (c) 2004 Zope Corporation 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. # ############################################################################## """Browser widgets for text-like data $Id: objectwidget.py 107385 2009-12-30 20:25:24Z faassen $ """ # implementation moved to zope.formlib.objectwidget # BBB from zope.formlib.objectwidget import ( ObjectWidgetView, ObjectWidget) zope.app.form-4.0.2/src/zope/app/form/browser/i18n.py0000644000175000017500000000020211340453312021614 0ustar sidneisidnei"""\ I18N support for zope.app.form.browser. """ # BBB implementation moved to zope.formlib.i18n from zope.formlib.i18n import _ zope.app.form-4.0.2/src/zope/app/form/browser/schemadisplay.py0000644000175000017500000000603711340453312023677 0ustar sidneisidnei############################################################################## # # Copyright (c) 2001, 2002 Zope Corporation 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 display-only pages based on schema. $Id: schemadisplay.py 106909 2009-12-22 19:05:21Z hannosch $ """ __docformat__ = 'restructuredtext' import zope.component from zope.interface import Interface from zope.publisher.interfaces.browser import IDefaultBrowserLayer from zope.publisher.browser import BrowserView from zope.schema import getFieldNamesInOrder from zope.security.checker import defineChecker, NamesChecker from zope.app.form.utility import setUpDisplayWidgets from zope.browserpage import ViewPageTemplateFile from zope.browserpage.simpleviewclass import SimpleViewClass class DisplayView(BrowserView): """Simple display-view base class. Subclasses should provide a `schema` attribute defining the schema to be displayed. """ errors = () update_status = '' label = '' # Fall-back field names computes from schema fieldNames = property(lambda self: getFieldNamesInOrder(self.schema)) def __init__(self, context, request): super(DisplayView, self).__init__(context, request) self._setUpWidgets() def _setUpWidgets(self): self.adapted = self.schema(self.context) setUpDisplayWidgets(self, self.schema, source=self.adapted, names=self.fieldNames) def setPrefix(self, prefix): for widget in self.widgets(): widget.setPrefix(prefix) def widgets(self): return [getattr(self, name+'_widget') for name in self.fieldNames] def DisplayViewFactory(name, schema, label, permission, layer, template, default_template, bases, for_, fields, fulledit_path=None, fulledit_label=None): class_ = SimpleViewClass(template, used_for=schema, bases=bases, name=name) class_.schema = schema class_.label = label class_.fieldNames = fields class_.fulledit_path = fulledit_path if fulledit_path and (fulledit_label is None): fulledit_label = "Full display" class_.fulledit_label = fulledit_label class_.generated_form = ViewPageTemplateFile(default_template) defineChecker(class_, NamesChecker(("__call__", "__getitem__", "browserDefault"), permission)) if layer is None: layer = IDefaultBrowserLayer sm = zope.component.getGlobalSiteManager() sm.registerAdapter(class_, (for_, layer), Interface, name) zope.app.form-4.0.2/src/zope/app/form/browser/meta.zcml0000644000175000017500000000336711340453312022317 0ustar sidneisidnei zope.app.form-4.0.2/src/zope/app/form/browser/editview.py0000644000175000017500000001233711340453312022671 0ustar sidneisidnei############################################################################## # # Copyright (c) 2001, 2002 Zope Corporation 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. # ############################################################################## """Edit View Classes $Id: editview.py 107371 2009-12-30 18:36:02Z faassen $ """ __docformat__ = 'restructuredtext' from datetime import datetime import transaction import zope.component from zope.interface import Interface from zope.schema import getFieldNamesInOrder from zope.publisher.interfaces.browser import IDefaultBrowserLayer from zope.publisher.browser import BrowserView from zope.security.checker import defineChecker, NamesChecker from zope.event import notify from zope.lifecycleevent import ObjectModifiedEvent from zope.lifecycleevent import Attributes from zope.browserpage import ViewPageTemplateFile from zope.browserpage.simpleviewclass import SimpleViewClass from zope.formlib.interfaces import WidgetsError from zope.app.form.utility import setUpEditWidgets, applyWidgetsChanges from zope.app.form.browser.i18n import _ from zope.app.form.browser.submit import Update class EditView(BrowserView): """Simple edit-view base class Subclasses should provide a `schema` attribute defining the schema to be edited. The automatically generated widgets are available by name through the attributes `*_widget`. (E.g. ``view.title_widget for the title widget``) """ errors = () update_status = None label = '' # Fall-back field names computes from schema fieldNames = property(lambda self: getFieldNamesInOrder(self.schema)) # Fall-back template generated_form = ViewPageTemplateFile('edit.pt') def __init__(self, context, request): super(EditView, self).__init__(context, request) self._setUpWidgets() def _setUpWidgets(self): self.adapted = self.schema(self.context) setUpEditWidgets(self, self.schema, source=self.adapted, names=self.fieldNames) def setPrefix(self, prefix): for widget in self.widgets(): widget.setPrefix(prefix) def widgets(self): return [getattr(self, name+'_widget') for name in self.fieldNames] def changed(self): # This method is overridden to execute logic *after* changes # have been made. pass def update(self): if self.update_status is not None: # We've been called before. Just return the status we previously # computed. return self.update_status status = '' content = self.adapted if Update in self.request: changed = False try: changed = applyWidgetsChanges(self, self.schema, target=content, names=self.fieldNames) # We should not generate events when an adapter is used. # That's the adapter's job. if changed and self.context is self.adapted: description = Attributes(self.schema, *self.fieldNames) notify(ObjectModifiedEvent(content, description)) except WidgetsError, errors: self.errors = errors status = _("An error occurred.") transaction.doom() else: setUpEditWidgets(self, self.schema, source=self.adapted, ignoreStickyValues=True, names=self.fieldNames) if changed: self.changed() formatter = self.request.locale.dates.getFormatter( 'dateTime', 'medium') status = _("Updated on ${date_time}", mapping={'date_time': formatter.format(datetime.utcnow())}) self.update_status = status return status def EditViewFactory(name, schema, label, permission, layer, template, default_template, bases, for_, fields, fulledit_path=None, fulledit_label=None): class_ = SimpleViewClass(template, used_for=schema, bases=bases, name=name) class_.schema = schema class_.label = label class_.fieldNames = fields class_.fulledit_path = fulledit_path if fulledit_path and (fulledit_label is None): fulledit_label = "Full edit" class_.fulledit_label = fulledit_label class_.generated_form = ViewPageTemplateFile(default_template) defineChecker(class_, NamesChecker(("__call__", "__getitem__", "browserDefault", "publishTraverse"), permission)) if layer is None: layer = IDefaultBrowserLayer s = zope.component.getGlobalSiteManager() s.registerAdapter(class_, (for_, layer), Interface, name) zope.app.form-4.0.2/src/zope/app/form/browser/subedit.pt0000644000175000017500000000257311340453312022504 0ustar sidneisidnei
Edit something

Full edit

  • Error Type: Error text
Extra top
Extra bottom
zope.app.form-4.0.2/src/zope/app/form/browser/textwidgets.py0000644000175000017500000000236411340453312023423 0ustar sidneisidnei############################################################################## # # Copyright (c) 2004 Zope Corporation 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. # ############################################################################## """Browser widgets with text-based input $Id: textwidgets.py 107385 2009-12-30 20:25:24Z faassen $ """ # BBB implementation moved to zope.formlib.textwidgets from zope.formlib.textwidgets import ( escape, TextWidget, Bytes, BytesWidget, BytesDisplayWidget, ASCII, ASCIIWidget, ASCIIDisplayWidget, URIDisplayWidget, TextAreaWidget, BytesAreaWidget, ASCIIAreaWidget, PasswordWidget, FileWidget, IntWidget, FloatWidget, DecimalWidget, DatetimeWidget, DateWidget, DateI18nWidget, DatetimeI18nWidget, DateDisplayWidget, DatetimeDisplayWidget) zope.app.form-4.0.2/src/zope/app/form/browser/widgets.txt0000644000175000017500000001652411340453312022710 0ustar sidneisidnei============================================================ Simple example showing ObjectWidget and SequenceWidget usage ============================================================ The following implements a Poll product (add it as zope/app/demo/poll) which has poll options defined as: label A `TextLine` holding the label of the option description Another `TextLine` holding the description of the option Simple stuff. Our Poll product holds an editable list of the `PollOption` instances. This is shown in the ``poll.py`` source below:: from persistent import Persistent from interfaces import IPoll, IPollOption from zope.interface import implements, classImplements class PollOption(Persistent, object): implements(IPollOption) class Poll(Persistent, object): implements(IPoll) def getResponse(self, option): return self._responses[option] def choose(self, option): self._responses[option] += 1 self._p_changed = 1 def get_options(self): return self._options def set_options(self, options): self._options = options self._responses = {} for option in self._options: self._responses[option.label] = 0 options = property(get_options, set_options, None, 'fiddle options') And the Schemas are defined in the ``interfaces.py`` file below:: from zope.interface import Interface from zope.schema import Object, Tuple, TextLine from zope.schema.interfaces import ITextLine from zope.i18nmessageid import MessageFactory _ = MessageFactory("poll") class IPollOption(Interface): label = TextLine(title=u'Label', min_length=1) description = TextLine(title=u'Description', min_length=1) class IPoll(Interface): options = Tuple(title=u'Options', value_type=Object(IPollOption, title=u'Poll Option')) def getResponse(option): "get the response for an option" def choose(option): 'user chooses an option' Note the use of the `Tuple` and `Object` schema fields above. The `Tuple` could optionally have restrictions on the min or max number of items - these will be enforced by the `SequenceWidget` form handling code. The `Object` must specify the schema that is used to generate its data. Now we have to specify the actual add and edit views. We use the existing AddView and EditView, but we pre-define the widget for the sequence because we need to pass in additional information. This is given in the ``browser.py`` file:: from zope.app.form.browser.editview import EditView from zope.app.form.browser.add import AddView from zope.formlib.widget import CustomWidgetFactory from zope.app.form.browser import SequenceWidget, ObjectWidget from interfaces import IPoll from poll import Poll, PollOption class PollVoteView: __used_for__ = IPoll def choose(self, option): self.context.choose(option) self.request.response.redirect('.') ow = CustomWidgetFactory(ObjectWidget, PollOption) sw = CustomWidgetFactory(SequenceWidget, subwidget=ow) class PollEditView(EditView): __used_for__ = IPoll options_widget = sw class PollAddView(AddView): __used_for__ = IPoll options_widget = sw Note the creation of the widget via a `CustomWidgetFactory`. So, whenever the options_widget is used, a new ``SequenceWidget(subwidget=CustomWidgetFactory(ObjectWidget, PollOption))`` is created. The subwidget argument indicates that each item in the sequence should be represented by the indicated widget instead of their default. If the contents of the sequence were just `Text` fields, then the default would be just fine - the only odd cases are Sequence and Object Widgets because they need additional arguments when they're created. Each item in the sequence will be represented by a ``CustomWidgetFactory(ObjectWidget, PollOption)`` - thus a new ``ObjectWidget(context, request, PollOption)`` is created for each one. The `PollOption` class ("factory") is used to create new instances when new data is created in add forms (or edit forms when we're adding new items to a Sequence). Tying all this together is the ``configure.zcml``:: Note the use of the ``class`` attribute on the ``addform`` and ``editform`` elements. Otherwise, nothing much exciting here. Finally, we have some additional views... ``results.zpt``:: Poll results
Poll results
OptionResultsDescription
Option Result Option
``vote.zpt``:: Poll voting
Poll voting
Option Option
zope.app.form-4.0.2/src/zope/app/form/__init__.py0000644000175000017500000000152011340453312021115 0ustar sidneisidnei############################################################################## # # Copyright (c) 2001, 2002 Zope Corporation 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. # ############################################################################## """Generic Widget base classes $Id: __init__.py 107385 2009-12-30 20:25:24Z faassen $ """ __docformat__ = 'restructuredtext' # BBB from zope.formlib.widget import Widget, InputWidget, CustomWidgetFactory zope.app.form-4.0.2/src/zope/app/form/tests/0000755000175000017500000000000011340453312020150 5ustar sidneisidneizope.app.form-4.0.2/src/zope/app/form/tests/utils.py0000644000175000017500000000605311340453312021666 0ustar sidneisidnei############################################################################## # # Copyright (c) 2001, 2002 Zope Corporation 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. # ############################################################################## """Utilities for testing form machinery $Id: utils.py 29405 2005-03-07 18:22:16Z poster $ """ from zope.interface.interfaces import IMethod from zope.security.interfaces import ForbiddenAttribute, Unauthorized import zope.security.checker from zope.schema import getFieldsInOrder class DummyChecker(object): """a checker for testing that requires explicit declarations requires explicit declaration of what is and is not authorized; does not require testing machinery to set up an interaction or a request. To instantiate, pass two dictionaries, the first for get access attribute protection, and the second for set access attribute protection. keys should be the attribute names, and values should be boolean True and False, where True indicates authorized and False, unauthorized. Any attributes that are not explicitly set and, in the case of get protection, are not in the zope.security.checker._available_by_default list, will cause ForbiddenAttribute to be raised when the name is checked, as with the real zope.security checkers. """ def __init__(self, getnames, setnames): self.getnames = getnames self.setnames = setnames def check_getattr(self, obj, name): if name not in zope.security.checker._available_by_default: try: val = self.getnames[name] except KeyError: raise ForbiddenAttribute else: if not val: raise Unauthorized check = check_getattr def check_setattr(self, obj, name): try: val = self.setnames[name] except KeyError: raise ForbiddenAttribute else: if not val: raise Unauthorized def proxy(self, value): return value def SchemaChecker(schema, readonly=False): """returns a checker that allows read and write access to fields in schema. """ get = {} set = {} for name, field in getFieldsInOrder(schema): get[name] = True if not field.readonly: if IMethod.providedBy(field): get[field.writer.__name__] = True else: set[name] = True if readonly: for nm in set: set[nm] = False return DummyChecker(get, set) def securityWrap(ob, schema, readonly=False): return zope.security.checker.Proxy(ob, SchemaChecker(schema, readonly)) zope.app.form-4.0.2/src/zope/app/form/tests/test_utility.py0000644000175000017500000012571111340453312023273 0ustar sidneisidnei############################################################################## # # Copyright (c) 2001, 2002 Zope Corporation 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 Utilities Tests $Id: test_utility.py 107401 2009-12-30 22:56:20Z faassen $ """ import doctest import zope.security.checker from zope.interface import Interface, implements from zope.component import testing from zope.component.interfaces import ComponentLookupError from zope.publisher.browser import TestRequest, BrowserView from zope.security.interfaces import ForbiddenAttribute, Unauthorized from zope.schema import Field, Int, accessors from zope.schema.interfaces import IField, IInt from zope.app.testing import ztapi from zope.formlib.widget import Widget from zope.formlib.interfaces import IWidget, IInputWidget, IDisplayWidget from zope.formlib.interfaces import ConversionError, InputErrors, WidgetsError from zope.formlib.interfaces import IWidgetFactory from zope.app.form.utility import no_value, setUpWidget, setUpWidgets from zope.app.form.utility import setUpEditWidgets, setUpDisplayWidgets from zope.app.form.utility import getWidgetsData, viewHasInput from zope.app.form.utility import applyWidgetsChanges from zope.app.form.tests import utils request = TestRequest() class IFoo(IField): pass class Foo(Field): implements(IFoo) class IBar(IField): pass class Bar(Field): implements(IBar) class IBaz(IInt): pass class Baz(Int): implements(IBaz) class IContent(Interface): foo = Foo() bar = Bar() class Content(object): implements(IContent) __Security_checker__ = utils.SchemaChecker(IContent) foo = 'Foo' class IFooWidget(IWidget): pass class IBarWidget(IWidget): pass class FooWidget(Widget): implements(IFooWidget) def getPrefix(self): return self._prefix # exposes _prefix for testing def getRenderedValue(self): return self._data # exposes _data for testing def renderedValueSet(self): return self._renderedValueSet() # for testing class BarWidget(Widget): implements(IBarWidget) def getRenderedValue(self): return self._data # exposes _data for testing def renderedValueSet(self): return self._renderedValueSet() # for testing class BazWidget(Widget): def getRenderedValue(self): return self._data # exposes _data for testing def renderedValueSet(self): return self._renderedValueSet() # for testing class IExtendedContent(IContent): getBaz, setBaz = accessors(Baz()) getAnotherBaz, setAnotherBaz = accessors(Baz()) shazam = Foo() class ExtendedContent(Content): implements(IExtendedContent) _baz = _anotherbaz = shazam = None def getBaz(self): return self._baz def setBaz(self, value): self._baz = value def getAnotherBaz(self): return self._anotherbaz def setAnotherBaz(self, value): self._anotherbaz = value extended_checker = utils.DummyChecker( {'foo':True, 'bar': True, 'getBaz': True, 'setBaz': True, 'getAnotherBaz': True, 'setAnotherBaz': False, 'shazam': False}, {'foo':True, 'bar': False, 'shazam': True}) def setUp(): """Setup for tests.""" testing.setUp() ztapi.browserView(IFoo, '', FooWidget, providing=IFooWidget) ztapi.browserView(IBar, '', BarWidget, providing=IBarWidget) def tearDown(): testing.tearDown() def assertRaises(exceptionType, callable, *args): try: callable(*args) return False except Exception, e: return isinstance(e, exceptionType) class TestSetUpWidget(object): def test_typical(self): """Documents and tests the typical uses of setUpWidget. >>> setUp() setUpWidget ensures that the appropriate widget exists as an attribute of a view. There are four required arguments to the function: >>> view = BrowserView(Content(), request) >>> name = 'foo' >>> field = IContent['foo'] >>> typeView = IFooWidget setUpWidget will add the appropriate widget as attribute to view named 'foo_widget'. >>> hasattr(view, 'foo_widget') False >>> setUpWidget(view, name, field, typeView) >>> hasattr(view, 'foo_widget') True >>> IFooWidget.providedBy(view.foo_widget) True If the view already has an attribute with that name, it attempts to use the existing value to create a widget. Two types are supported: - IWidgetFactory - IWidget If the existing attribute value implements IWidgetFactory, it is used to create a widget: >>> widget = FooWidget(IContent['foo'], request) >>> class Factory(object): ... implements(IWidgetFactory) ... def __call__(self, request, context): ... return widget >>> setattr(view, 'foo_widget', Factory()) >>> view.foo_widget is widget False >>> setUpWidget(view, name, field, typeView) >>> view.foo_widget is widget True If the existing attribute value implements IWidget, it is used without modification: >>> setattr(view, 'foo_widget', widget) >>> IWidget.providedBy(widget) True >>> setUpWidget(view, name, field, typeView) >>> view.foo_widget is widget True We now have to cleanup, so that these tests can be run in a loop. We modified the 'IContent' interface saying that 'foo' is not mandatory, so we have to change that back. >>> IContent['foo'].required = True >>> tearDown() """ def test_validation(self): """Documents and tests validation performed by setUpWidget. >>> setUp() setUpWidget ensures that the the view has an attribute that implements IWidget. If setUpWidget cannot configure a widget, it raises a TypeError. E.g., if a view already has a widget attribute of the name + '_widget' that does not implement IWidgetFactory or IWidget, setUpWidget raises a TypeError: >>> view = BrowserView(Content(), request) >>> setattr(view, 'foo_widget', 'not a widget') >>> assertRaises(TypeError, setUpWidget, ... view, 'foo', IContent['foo'], IFooWidget) True Similarly, if a view has a widget attribute that implements IWidgetFactory, the object created by the factory must implement IWidget. >>> class Factory(object): ... implements(IWidgetFactory) ... def __call__(self, request, context): ... return 'not a widget' >>> setattr(view, 'foo_widget', Factory()) >>> assertRaises(TypeError, setUpWidget, ... view, 'foo', IContent['foo'], IFooWidget) True >>> tearDown() """ def test_context(self): """Documents and tests the role of context in setUpWidget. >>> setUp() setUpWidget configures a widget by associating it to a bound field, which is a copy of a schema field that is bound to an object. The object the field is bound to can be explicitly specified in the setUpWidget 'context' argument. By default, the context used by setUpWidget is the view context: >>> context = Content() >>> view = BrowserView(context, request) >>> setUpWidget(view, 'foo', IContent['foo'], IFooWidget) >>> view.foo_widget.context.context is context True Alternatively, you can specify a context explicitly: >>> view = BrowserView(context, request) >>> altContext = Content() >>> setUpWidget(view, 'foo', IContent['foo'], IFooWidget, ... context=altContext) >>> view.foo_widget.context.context is context False >>> view.foo_widget.context.context is altContext True >>> tearDown() """ def test_widgetLookup(self): """Documents and tests how widgets are looked up by type. >>> setUp() If the view does not already have a widget configured for the specified field name, setUpWidget will look up a widget using an interface specified for the widgetType argument. Widgets are typically looked up for IInputWidget and IDisplayWidget types. To illustrate this, we'll create two widgets, one for editing and another for displaying IFoo attributes. Each widget is registered as a view providing the appropriate widget type. >>> class EditFooWidget(Widget): ... implements(IInputWidget) ... def hasInput(self): ... return False >>> ztapi.browserViewProviding(IFoo, EditFooWidget, IInputWidget) >>> class DisplayFooWidget(Widget): ... implements(IDisplayWidget) >>> ztapi.browserViewProviding(IFoo, DisplayFooWidget, ... IDisplayWidget) A call to setUpWidget will lookup the widgets based on the specified type. >>> view = BrowserView(Content(), request) >>> setUpWidget(view, 'foo', IContent['foo'], IInputWidget) >>> IInputWidget.providedBy(view.foo_widget) True >>> delattr(view, 'foo_widget') >>> setUpWidget(view, 'foo', IContent['foo'], IDisplayWidget) >>> IDisplayWidget.providedBy(view.foo_widget) True A ComponentError is raised if a widget is not registered for the specified type: >>> class IUnregisteredWidget(IWidget): ... pass >>> delattr(view, 'foo_widget') >>> assertRaises(ComponentLookupError, setUpWidget, ... view, 'foo', IContent['foo'], IUnregisteredWidget) True >>> tearDown() """ def test_prefix(self): """Documents and tests the specification of widget prefixes. >>> setUp() Widgets support a prefix that can be used to group related widgets on a view. To specify the prefix for a widget, specify in the call to setUpWidget: >>> view = BrowserView(Content(), request) >>> setUpWidget(view, 'foo', IContent['foo'], IFooWidget, ... prefix='mygroup') >>> view.foo_widget.getPrefix() 'mygroup.' >>> tearDown() """ def test_value(self): """Documents and tests values and setUpWidget. >>> setUp() setUpWidget configures the widget with the value specified in the 'value' argument: >>> view = BrowserView(Content(), request) >>> setUpWidget(view, 'foo', IContent['foo'], IFooWidget, ... value='Explicit Widget Value') >>> view.foo_widget.renderedValueSet() True >>> view.foo_widget.getRenderedValue() 'Explicit Widget Value' The utility module provides a marker object 'no_value' that can be used as setUpWidget's 'value' argument to indicate that a value doesn't exist for the bound field. This may seem a bit unusual since None is typically used for this purpose. However, None is a valid value for many fields and does not indicate 'no value'. When no_value is specified in a call to setUpWidget, the effected widget is not configured with a value: >>> delattr(view, 'foo_widget') >>> setUpWidget(view, 'foo', IContent['foo'], IFooWidget, ... value=no_value) >>> view.foo_widget.renderedValueSet() False This is the also default behavior when the value argument is omitted: >>> delattr(view, 'foo_widget') >>> setUpWidget(view, 'foo', IContent['foo'], IFooWidget) >>> view.foo_widget.renderedValueSet() False Note that when None is specified for 'value', the widget is configured with None: >>> delattr(view, 'foo_widget') >>> setUpWidget(view, 'foo', IContent['foo'], IFooWidget, ... value=None) >>> view.foo_widget.renderedValueSet() True >>> view.foo_widget.getRenderedValue() is None True >>> tearDown() """ def test_stickyValues(self): """Documents and tests setUpWidget's handling of sticky values. >>> setUp() setUpWidget supports the concept of 'sticky values'. A sticky value is a value displayed by a widget that should persist across multiple across multiple object edit sessions. Sticky values ensure that invalid user is available for the user to modify rather than being replaced by some other value. setUpWidget inferst that a widget has a sticky value if: - The widget implements IInputWidget - The widget returns True for its hasInput method To illustrate, we'll create and register an edit widget for foo that has input: >>> class EditFooWidget(Widget): ... implements(IInputWidget) ... _data = "Original Value" ... def hasInput(self): return True ... def getRenderedValue(self): return self._data >>> ztapi.browserView(IFoo, '', EditFooWidget, ... providing=IInputWidget) Specifying a value to setUpWidget would typically cause that value to be set for the widget: >>> view = BrowserView(Content(), request) >>> setUpWidget(view, 'foo', IContent['foo'], IInputWidget, ... value="A New Value") However, because EditFooWidget has input (i.e. has a 'sticky' value), setUpWidget will not overwrite its value: >>> view.foo_widget._data 'Original Value' You can use setUpWidget's 'ignoreStickyValues' argument to override this behavior and force the widget's value to be overwritten with the 'value' argument: >>> delattr(view, 'foo_widget') >>> setUpWidget(view, 'foo', IContent['foo'], IInputWidget, ... value="A New Value", ignoreStickyValues=True) >>> view.foo_widget.getRenderedValue() 'A New Value' >>> tearDown() """ class TestSetUpWidgets(object): def test_typical(self): """Tests the typical use of setUpWidgets. >>> setUp() The simplest use of setUpWidget configures a view with widgets of a particular type for a schema: >>> view = BrowserView(Content(), request) >>> setUpWidgets(view, IContent, IWidget) The view now has two widgets, one for each field in the specified schema: >>> IWidget.providedBy(view.foo_widget) True >>> IWidget.providedBy(view.bar_widget) True Because we did not provide initial values, the widget values are not configured: >>> view.foo_widget.renderedValueSet() False >>> view.bar_widget.renderedValueSet() False To specify initial values for the widgets, we can use the 'initial' argument: >>> view = BrowserView(Content(), request) >>> initial = {'foo': 'Value of Foo', 'bar': 'Value of Bar'} >>> setUpWidgets(view, IContent, IWidget, initial=initial) >>> view.foo_widget.getRenderedValue() 'Value of Foo' >>> view.bar_widget.getRenderedValue() 'Value of Bar' >>> tearDown() """ def test_names(self): """Documents and tests the use of names in setUpWidgets. >>> setUp() The names argument can be used to configure a specific set of widgets for a view: >>> view = BrowserView(Content(), request) >>> IContent.names() ['foo', 'bar'] >>> setUpWidgets(view, IContent, IWidget, names=('bar',)) >>> hasattr(view, 'foo_widget') False >>> hasattr(view, 'bar_widget') True >>> tearDown() """ def test_delegation(self): """Tests setUpWidgets' use of setUpWidget. >>> setUp() setUpWidgets delegates several of its arguments to multiple calls to setUpWidget - one call for each widget being configured. The arguments passed directly through to calls to setUpWidget are: view viewType prefix ignoreStickyValues context To illustrate this, we'll replace setUpWidget in the utility module and capture arguments passed to it when setUpWidgets is called. >>> def setUpWidget(view, name, field, viewType, value=None, ... prefix=None, ignoreStickyValues=False, ... context=None): ... print "view: %s" % view.__class__ ... print "name: %s" % name ... print "field: %s" % field.__class__ ... print "viewType: %s" % viewType.__class__ ... if value is no_value: ... print "value: not specified" ... else: ... print "value: %s" % value ... print "prefix %s" % prefix ... print "ignoreStickyValues: %s" % ignoreStickyValues ... print "context: %s" % context ... print '---' >>> import zope.formlib.utility >>> setUpWidgetsSave = zope.formlib.utility.setUpWidget >>> zope.formlib.utility.setUpWidget = setUpWidget When we call setUpWidgets, we should see that setUpWidget is called for each field in the specified schema: >>> view = BrowserView(Content(), request) >>> setUpWidgets(view, IContent, IWidget, 'prefix', True, ... initial={ "bar":"Bar" }, ... context="Alt Context") view: name: foo field: viewType: value: not specified prefix prefix ignoreStickyValues: True context: Alt Context --- view: name: bar field: viewType: value: Bar prefix prefix ignoreStickyValues: True context: Alt Context --- >>> zope.formlib.utility.setUpWidget = setUpWidgetsSave >>> tearDown() """ def test_forbiddenAttributes(self): """Tests that forbidden attributes cause an error in widget setup. >>> setUp() If an attribute cannot be read from a source object because it's forbidden, the ForbiddenAttribute error is allowed to pass through to the caller. We'll create a field that raises a ForbiddenError itself to simulate what would happen when a proxied object's attribute is accessed without the required permission. >>> class AlwaysForbidden(Field): ... def get(self, source): ... raise ForbiddenAttribute(source, self.__name__) We'll also create a schema using this field: >>> class IMySchema(Interface): ... tryme = AlwaysForbidden() When we use setUpEditWidgets to configure a view with IMySchema: >>> view = BrowserView('some context', TestRequest()) >>> setUpEditWidgets(view, IMySchema) Traceback (most recent call last): ForbiddenAttribute: ('some context', 'tryme') The same applies to setUpDisplayWidgets: >>> setUpDisplayWidgets(view, IMySchema) Traceback (most recent call last): ForbiddenAttribute: ('some context', 'tryme') >>> tearDown() """ class TestFormSetUp(object): def test_setUpEditWidgets(self): """Documents and tests setUpEditWidgets. >>> setUp() setUpEditWidgets configures a view to collect field values from a user. The function looks up widgets of type IInputWidget for the specified schema. We'll first create and register widgets for the schema fields for which we want input: >>> class InputWidget(Widget): ... implements(IInputWidget) ... def hasInput(self): ... return False ... def getRenderedValue(self): return self._data >>> ztapi.browserViewProviding(IFoo, InputWidget, IInputWidget) >>> ztapi.browserViewProviding(IBar, InputWidget, IInputWidget) Next we'll configure a view with a context object: >>> context = Content() >>> context.foo = 'abc' >>> context.bar = 'def' >>> view = BrowserView(context, request) A call to setUpEditWidgets with the view: >>> setUpEditWidgets(view, IContent) ['foo', 'bar'] configures the view with widgets that accept input for the context field values: >>> isinstance(view.foo_widget, InputWidget) True >>> view.foo_widget.getRenderedValue() 'abc' >>> isinstance(view.bar_widget, InputWidget) True >>> view.bar_widget.getRenderedValue() 'def' setUpEditWidgets provides a 'source' argument that provides an alternate source of values to be edited: >>> view = BrowserView(context, request) >>> source = Content() >>> source.foo = 'abc2' >>> source.bar = 'def2' >>> setUpEditWidgets(view, IContent, source=source) ['foo', 'bar'] >>> view.foo_widget.getRenderedValue() 'abc2' >>> view.bar_widget.getRenderedValue() 'def2' If a field is read only, setUpEditWidgets will use a display widget (IDisplayWidget) intead of an input widget to display the field value. >>> class DisplayWidget(Widget): ... implements(IDisplayWidget) >>> ztapi.browserViewProviding(IFoo, DisplayWidget, IDisplayWidget) >>> save = IContent['foo'].readonly # save readonly value >>> IContent['foo'].readonly = True >>> delattr(view, 'foo_widget') >>> setUpEditWidgets(view, IContent) ['foo', 'bar'] >>> isinstance(view.foo_widget, DisplayWidget) True >>> IContent['foo'].readonly = save # restore readonly value By default, setUpEditWidgets raises Unauthorized if it is asked to set up a field to which the user does not have permission to access or to change. In the definition of the ExtendedContent interface, notice the __Security_checker__ attribute, which stubs out a checker that allows the user to view the bar attribute, but not set it, and call getAnotherBaz but not setAnotherBaz. >>> view.context = context = zope.security.checker.Proxy( ... ExtendedContent(), extended_checker) >>> setUpEditWidgets(view, IExtendedContent, names=['bar']) ... # can' write to bar Traceback (most recent call last): ... Unauthorized: bar >>> setUpEditWidgets( ... view, IExtendedContent, names=['getAnotherBaz']) ... # can't access the setter, setAnotherBaz Traceback (most recent call last): ... Unauthorized: setAnotherBaz >>> setUpEditWidgets( ... view, IExtendedContent, names=['shazam']) ... # can't even access shazam Traceback (most recent call last): ... Unauthorized Two optional flags can change this behavior. degradeDisplay=True causes the form machinery to skip fields silently that the user may not access. In this case, the return value of setUpEditWidgets-- a list of the field names set up--will be different that the names provided to the function. >>> delattr(view, 'foo_widget') >>> delattr(view, 'bar_widget') >>> ztapi.browserViewProviding(IBaz, InputWidget, IInputWidget) >>> setUpEditWidgets( ... view, IExtendedContent, names=['foo', 'shazam', 'getBaz'], ... degradeDisplay=True) ['foo', 'getBaz'] >>> IInputWidget.providedBy(view.foo_widget) True >>> IInputWidget.providedBy(view.getBaz_widget) True >>> view.shazam_widget Traceback (most recent call last): ... AttributeError: 'BrowserView' object has no attribute 'shazam_widget' Similarly, degradeInput=True causes the function to degrade to display widgets for any fields that the current user cannot change, but can see. >>> delattr(view, 'foo_widget') >>> delattr(view, 'getBaz_widget') >>> ztapi.browserViewProviding(IBar, DisplayWidget, IDisplayWidget) >>> ztapi.browserViewProviding(IBaz, DisplayWidget, IDisplayWidget) >>> setUpEditWidgets( ... view, IExtendedContent, ... names=['foo', 'bar', 'getBaz', 'getAnotherBaz'], ... degradeInput=True) ['foo', 'bar', 'getBaz', 'getAnotherBaz'] >>> IInputWidget.providedBy(view.foo_widget) True >>> IDisplayWidget.providedBy(view.bar_widget) True >>> IInputWidget.providedBy(view.getBaz_widget) True >>> IDisplayWidget.providedBy(view.getAnotherBaz_widget) True Note that if the user cannot view the current value then they cannot view the input widget. The two flags can then, of course, be used together. >>> delattr(view, 'foo_widget') >>> delattr(view, 'bar_widget') >>> delattr(view, 'getBaz_widget') >>> delattr(view, 'getAnotherBaz_widget') >>> setUpEditWidgets( ... view, IExtendedContent, ... names=['foo', 'bar', 'shazam', 'getBaz', 'getAnotherBaz'], ... degradeInput=True) Traceback (most recent call last): ... Unauthorized >>> setUpEditWidgets( ... view, IExtendedContent, ... names=['foo', 'bar', 'shazam', 'getBaz', 'getAnotherBaz'], ... degradeInput=True, degradeDisplay=True) ['foo', 'bar', 'getBaz', 'getAnotherBaz'] >>> IInputWidget.providedBy(view.foo_widget) True >>> IDisplayWidget.providedBy(view.bar_widget) True >>> IInputWidget.providedBy(view.getBaz_widget) True >>> IDisplayWidget.providedBy(view.getAnotherBaz_widget) True >>> view.shazam_widget Traceback (most recent call last): ... AttributeError: 'BrowserView' object has no attribute 'shazam_widget' >>> tearDown() """ def test_setUpDisplayWidgets(self): """Documents and tests setUpDisplayWidgets. >>> setUp() setUpDisplayWidgets configures a view for use as a display only form. The function looks up widgets of type IDisplayWidget for the specified schema. We'll first create and register widgets for the schema fields we want to edit: >>> class DisplayWidget(Widget): ... implements(IDisplayWidget) ... def getRenderedValue(self): return self._data >>> ztapi.browserViewProviding(IFoo, DisplayWidget, IDisplayWidget) >>> ztapi.browserViewProviding(IBar, DisplayWidget, IDisplayWidget) Next we'll configure a view with a context object: >>> context = Content() >>> context.foo = 'abc' >>> context.bar = 'def' >>> view = BrowserView(context, request) A call to setUpDisplayWidgets with the view: >>> setUpDisplayWidgets(view, IContent) ['foo', 'bar'] configures the view with widgets that display the context fields: >>> isinstance(view.foo_widget, DisplayWidget) True >>> view.foo_widget.getRenderedValue() 'abc' >>> isinstance(view.bar_widget, DisplayWidget) True >>> view.bar_widget.getRenderedValue() 'def' Like setUpEditWidgets, setUpDisplayWidgets accepts a 'source' argument that provides an alternate source of values to be edited: >>> view = BrowserView(context, request) >>> source = Content() >>> source.foo = 'abc2' >>> source.bar = 'def2' >>> setUpDisplayWidgets(view, IContent, source=source) ['foo', 'bar'] >>> view.foo_widget.getRenderedValue() 'abc2' >>> view.bar_widget.getRenderedValue() 'def2' Also like setUpEditWidgets, the degradeDisplay flag allows widgets to silently disappear if they are unavailable. >>> view.context = context = zope.security.checker.Proxy( ... ExtendedContent(), extended_checker) >>> delattr(view, 'foo_widget') >>> delattr(view, 'bar_widget') >>> ztapi.browserViewProviding(IBaz, DisplayWidget, IDisplayWidget) >>> setUpDisplayWidgets( ... view, IExtendedContent, ... names=['foo', 'bar', 'shazam', 'getBaz', 'getAnotherBaz']) Traceback (most recent call last): ... Unauthorized >>> setUpDisplayWidgets( ... view, IExtendedContent, ... names=['foo', 'bar', 'shazam', 'getBaz', 'getAnotherBaz'], ... degradeDisplay=True) ['foo', 'bar', 'getBaz', 'getAnotherBaz'] >>> IDisplayWidget.providedBy(view.foo_widget) True >>> IDisplayWidget.providedBy(view.bar_widget) True >>> IDisplayWidget.providedBy(view.getBaz_widget) True >>> IDisplayWidget.providedBy(view.getAnotherBaz_widget) True >>> view.shazam_widget Traceback (most recent call last): ... AttributeError: 'BrowserView' object has no attribute 'shazam_widget' >>> tearDown() """ class TestForms(object): def test_viewHasInput(self): """Tests viewHasInput. >>> setUp() viewHasInput returns True if any of the widgets for a set of fields have user input. This method is typically invoked on a view that has been configured with one setUpEditWidgets. >>> class InputWidget(Widget): ... implements(IInputWidget) ... input = None ... def hasInput(self): ... return self.input is not None >>> ztapi.browserViewProviding(IFoo, InputWidget, IInputWidget) >>> ztapi.browserViewProviding(IBar, InputWidget, IInputWidget) >>> view = BrowserView(Content(), request) >>> setUpEditWidgets(view, IContent) ['foo', 'bar'] Because InputWidget is configured to not have input by default, the view does not have input: >>> viewHasInput(view, IContent) False But if we specify input for at least one widget: >>> view.foo_widget.input = 'Some Value' >>> viewHasInput(view, IContent) True >>> tearDown() """ def test_applyWidgetsChanges(self): """Documents and tests applyWidgetsChanges. >>> setUp() applyWidgetsChanges updates the view context, or an optional alternate context, with widget values. This is typically called when a form is submitted. We'll first create a simple edit widget that can be used to update an object: >>> class InputWidget(Widget): ... implements(IInputWidget) ... input = None ... valid = True ... def hasInput(self): ... return input is not None ... def applyChanges(self, object): ... if not self.valid: ... raise ConversionError('invalid input') ... field = self.context ... field.set(object, self.input) ... return True >>> ztapi.browserViewProviding(IFoo, InputWidget, IInputWidget) >>> ztapi.browserViewProviding(IBar, InputWidget, IInputWidget) Before calling applyWidgetsUpdate, we need to configure a context and a view with edit widgets: >>> context = Content() >>> view = BrowserView(context, request) >>> setUpEditWidgets( ... view, IContent, context=context, names=('foo',)) ['foo'] We now specify new widget input and apply the changes: >>> view.foo_widget.input = 'The quick brown fox...' >>> context.foo 'Foo' >>> applyWidgetsChanges(view, IContent, names=('foo',)) True >>> context.foo 'The quick brown fox...' By default, applyWidgetsChanges applies the new widget values to the view context. Alternatively, we can provide a 'target' argument to be updated: >>> target = Content() >>> target.foo 'Foo' >>> applyWidgetsChanges(view, IContent, target=target, ... names=('foo',)) True >>> target.foo 'The quick brown fox...' applyWidgetsChanges is typically used in conjunction with one of the setUp utility functions. If applyWidgetsChanges is called using a view that was not previously configured with a setUp function, or was not otherwise configured with widgets for each of the applicable fields, an AttributeError will be raised: >>> view = BrowserView(context, request) >>> applyWidgetsChanges(view, IContent, names=('foo',)) Traceback (most recent call last): AttributeError: 'BrowserView' object has no attribute 'foo_widget' When applyWidgetsChanges is called with multiple form fields, some with valid data and some with invalid data, *changes may be applied*. For instance, below see that context.foo changes from 'Foo' to 'a' even though trying to change context.bar fails. Generally, ZODB transactional behavior is expected to correct this sort of problem. >>> context = Content() >>> view = BrowserView(context, request) >>> setUpEditWidgets(view, IContent, names=('foo', 'bar')) ['foo', 'bar'] >>> view.foo_widget.input = 'a' >>> view.bar_widget.input = 'b' >>> view.bar_widget.valid = False >>> context.foo 'Foo' >>> getattr(context, 'bar', 'not really') 'not really' >>> applyWidgetsChanges(view, IContent, names=('foo', 'bar')) Traceback (most recent call last): WidgetsError: ConversionError: ('invalid input', None) >>> context.foo 'a' >>> getattr(context, 'bar', 'not really') 'not really' >>> tearDown() """ class TestGetWidgetsData(object): def test_typical(self): """Documents and tests the typical use of getWidgetsData. >>> setUp() getWidgetsData retrieves the current values from widgets on a view. For this test, we'll create a simple edit widget and register it for the schema field types: >>> class InputWidget(Widget): ... implements(IInputWidget) ... input = None ... def hasInput(self): ... return self.input is not None ... def getInputValue(self): ... return self.input >>> ztapi.browserViewProviding(IFoo, InputWidget, IInputWidget) >>> ztapi.browserViewProviding(IBar, InputWidget, IInputWidget) We use setUpEditWidgets to configure a view with widgets for the IContent schema: >>> view = BrowserView(Content(), request) >>> setUpEditWidgets(view, IContent) ['foo', 'bar'] The simplest form of getWidgetsData requires a view and a schema: >>> try: ... result = getWidgetsData(view, IContent) ... except Exception, e: ... print 'getWidgetsData failed' ... e getWidgetsData failed MissingInputError: ('foo', u'', 'the field is required') MissingInputError: ('bar', u'', 'the field is required') We see that getWidgetsData raises a MissingInputError if a required field does not have input from a widget.: >>> view.foo_widget.input = 'Input for foo' >>> view.bar_widget.input = 'Input for bar' >>> result = getWidgetsData(view, IContent) The result of getWidgetsData is a map of field names to widget values. >>> keys = result.keys(); keys.sort(); keys ['bar', 'foo'] >>> result['foo'] 'Input for foo' >>> result['bar'] 'Input for bar' If a field is not required, however: >>> IContent['foo'].required = False we can omit input for its widget: >>> view.foo_widget.input = None >>> result = getWidgetsData(view, IContent) >>> 'foo' in result False Note that when a widget indicates that is does not have input, its results are omitted from getWidgetsData's return value. Users of getWidgetsData should explicitly check for field values before accessing them: >>> for name in IContent: ... if name in result: ... print (name, result[name]) ('bar', 'Input for bar') You can also specify an optional 'names' argument (a tuple) to request a subset of the schema fields: >>> result = getWidgetsData(view, IContent, names=('bar',)) >>> result.keys() ['bar'] >>> tearDown() """ def test_widgetsErrorException(self): """Documents and tests WidgetsError. WidgetsError wraps one or more errors, which are specified as a sequence in the 'errors' argument: >>> error = WidgetsError(('foo',)) >>> error str: foo WidgetsError also provides a 'widgetsData' attribute, which is a map of valid field values, keyed by field name, that were obtained in the same read operation that generated the errors: >>> error = WidgetsError(('foo',), widgetsData={'bar': 'Bar'}) >>> error.widgetsData {'bar': 'Bar'} The most typical use of this error is when reading a set of widget values -- the read operation can generate more than one error, as well as a set of successfully read values: >>> values = {'foo': 'Foo'} >>> errors = [] >>> widgetsData = {} >>> for name in ('foo', 'bar'): # some list of values to read ... try: ... widgetsData[name] = values[name] # read operation ... except Exception, e: ... errors.append(e) # capture all errors >>> if errors: ... widgetsError = WidgetsError(errors, widgetsData) ... raise widgetsError Traceback (most recent call last): WidgetsError: KeyError: 'bar' The handler of error can access all of the widget error as well as the widget values read: >>> for error in widgetsError: ... error.__class__.__name__ 'KeyError' >>> widgetsError.widgetsData {'foo': 'Foo'} """ def test_suite(): return doctest.DocTestSuite() zope.app.form-4.0.2/src/zope/app/form/tests/__init__.py0000644000175000017500000000007511340453312022263 0ustar sidneisidnei# # This file is necessary to make this directory a package. zope.app.form-4.0.2/src/zope/app/form/tests/test_macros.pt0000644000175000017500000000035411340453312023042 0ustar sidneisidnei
zope.app.form-4.0.2/src/zope/app/form/ftesting.zcml0000644000175000017500000000267711340453312021534 0ustar sidneisidnei zope.app.form-4.0.2/src/zope.app.form.egg-info/0000755000175000017500000000000011340453337020505 5ustar sidneisidneizope.app.form-4.0.2/src/zope.app.form.egg-info/not-zip-safe0000644000175000017500000000000111340453337022733 0ustar sidneisidnei zope.app.form-4.0.2/src/zope.app.form.egg-info/top_level.txt0000644000175000017500000000000511340453337023232 0ustar sidneisidneizope zope.app.form-4.0.2/src/zope.app.form.egg-info/PKG-INFO0000644000175000017500000001641011340453337021604 0ustar sidneisidneiMetadata-Version: 1.0 Name: zope.app.form Version: 4.0.2 Summary: The Original Zope 3 Form Framework Home-page: http://pypi.python.org/pypi/zope.app.form Author: Zope Corporation and Contributors Author-email: zope-dev@zope.org License: ZPL 2.1 Description: This package provides the old form framework for Zope 3. It also implements a few high-level ZCML directives for declaring forms. More advanced alternatives are implemented in ``zope.formlib`` and ``z3c.form``. The widgets that were defined in here were moved to ``zope.formlib``. Version 4.0 and newer are maintained for backwards compatibility reasons only. Detailed documentation: ======= CHANGES ======= 4.0.2 (2010-01-22) ================== - Seems like 4.0.1 was released already. Brown bag. 4.0.1 (2010-01-08) ================== - Import 'escape' for backwards compatibility as packages turn out to be importing this too, even though it's actually from the Python standard library. - Widget documentation is now on PyPI too. 4.0 (2010-01-08) ================ - The widget implementations have been moved to zope.formlib. This makes this package depend on zope.formlib. The dependency of zope.formlib on this package has been broken. 3.12.1 (2009-12-22) =================== - Added missing zope.datetime dependency. 3.12.0 (2009-12-22) =================== - Use zope.browserpage in favor of zope.app.pagetemplate. 3.11.1 (2009-12-22) =================== - Prefer zope.testing.doctest over doctestunit and adjust test output to newer zope.schema release. 3.11.0 (2009-12-18) =================== - Use zope.component.testing in favor of zope.app.testing where possible. - Define dummy standard_macros for test purposes. This reduces the test dependencies by zope.app.basicskin and zope.browserresource. - Removed the zope.app.container and zope.app.publisher testing dependencies. - Refactored code to remove zope.app.component dependency. - Made the tests independent of zope.app.locales. - Reduce zope.app test dependencies by avoiding zope.app.securitypolicy and zope.app.zcmlfiles. 3.10.0 (2009-12-17) =================== - Avoid the ``zope.app.basicskin`` dependency, by defining our own FormMacros. 3.9.0 (2009-10-08) ================== - Internationalized 'Invalid value' used with ConversionError - Added dependency on transaction and test dependency on zope.app.component. - Moved dependencies on ZODB3 and zope.location to the test extra. - Reduced the dependency on zope.app.publisher to a dependency on zope.browsermenu plus a test dependency on zope.browserpage. 3.8.1 (2009-07-23) ================== - Fix unittest failure due to translation update. 3.8.0 (2009-05-24) ================== - Use standard properties instead of `zope.cachedescriptors`. - Require `zope.browser` 1.1 instead of `zope.app.container` for IAdding. 3.7.3 (2009-05-11) ================== - Fixed invalid markup. 3.7.2 (2009-03-12) ================== - Fixed bug where OrderedMultiSelectWidget did not respect the widgets size attribute. - Fixed bug in SequenceWidget where it crashed while trying to iterate a missing_value (None in most of cases) on _getRenderedValue. - Adapt to removal of deprecated interfaces from zope.component.interfaces. The IView was moved to zope.publisher and we use our custom IWidgetFactory interface instead of removed zope.component.interfaces.IViewFactory. - Fix tests to work on Python 2.6. 3.7.1 (2009-01-31) ================== - Adapt to the upcoming zope.schema release 3.5.1 which will also silence the spurious `set` failures. 3.7.0 (2008-12-11) ================== - use zope.browser.interfaces.ITerms instead of zope.app.form.browser.interfaces - Depending on zope.schema>=3.5a1 which uses the builtin ``set`` instead of the ``sets`` module. 3.6.4 (2008-11-26) ================== - The URIDisplayWidget doesn't render an anchor for empty/None values. 3.6.3 (2008-10-15) ================== - Get rid of deprecated usage of LayerField from zope.app.component.back35, replaced by zope.configuration.fields.GlobalInterface. 3.6.2 (2008-09-08) ================== - Fixed restructured text in doc tests to unbreak the PyPI page. (3.6.1 skipped due to a typo) 3.6.0 (2008-08-22) ================== - Dropdown widgets display an item for the missing value even if the field is required when no value is selected. See zope/app/form/browser/README.txt on how to switch this off for BBB. - Source select widgets for required fields are now required as well. They used not to be required on the assumption that some value would be selected by the browser, which had always been wrong except for dropdown widgets. 3.5.0 (2008-06-05) ================== - Translate the title on SequenceWidget's "Add " button. - No longer uses zapi. 3.4.2 (2008-02-07) ================== - Made display widgets for sources translate message IDs correctly. 3.4.1 (2007-10-31) ================== - Resolve ``ZopeSecurityPolicy`` deprecation warning. 3.4.0 (2007-10-24) ================== - ``zope.app.form`` now supports Python2.5 - Initial release independent of the main Zope tree. Before 3.4 ========== This package was part of the Zope 3 distribution and did not have its own CHANGES.txt. For earlier changes please refer to either our subversion log or the CHANGES.txt of earlier Zope 3 releases. Keywords: zope3 form widget zcml 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 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zope.app.form-4.0.2/src/zope.app.form.egg-info/requires.txt�����������������������������������������0000644�0001750�0001750�00000000624�11340453337�023107� 0����������������������������������������������������������������������������������������������������ustar �sidnei��������������������������sidnei�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������setuptools transaction zope.formlib >= 4.0 zope.browser>=1.1 zope.browserpage>=3.10.1 zope.browsermenu zope.component zope.configuration zope.datetime zope.exceptions zope.i18n zope.interface zope.proxy zope.publisher zope.schema>=3.5.1dev zope.security [test] ZODB3 zc.sourcefactory zope.container zope.principalregistry zope.site zope.traversing zope.app.appsetup zope.app.publication zope.app.testing������������������������������������������������������������������������������������������������������������zope.app.form-4.0.2/src/zope.app.form.egg-info/namespace_packages.txt�������������������������������0000644�0001750�0001750�00000000016�11340453337�025035� 0����������������������������������������������������������������������������������������������������ustar �sidnei��������������������������sidnei�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zope zope.app ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zope.app.form-4.0.2/src/zope.app.form.egg-info/SOURCES.txt������������������������������������������0000644�0001750�0001750�00000005345�11340453337�022400� 0����������������������������������������������������������������������������������������������������ustar �sidnei��������������������������sidnei�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CHANGES.txt COPYRIGHT.txt LICENSE.txt README.txt bootstrap.py buildout.cfg setup.py src/zope/__init__.py src/zope.app.form.egg-info/PKG-INFO src/zope.app.form.egg-info/SOURCES.txt src/zope.app.form.egg-info/dependency_links.txt src/zope.app.form.egg-info/namespace_packages.txt src/zope.app.form.egg-info/not-zip-safe src/zope.app.form.egg-info/requires.txt src/zope.app.form.egg-info/top_level.txt src/zope/app/__init__.py src/zope/app/form/__init__.py src/zope/app/form/ftesting.zcml src/zope/app/form/interfaces.py src/zope/app/form/testing.py src/zope/app/form/utility.py src/zope/app/form/browser/__init__.py src/zope/app/form/browser/add.pt src/zope/app/form/browser/add.py src/zope/app/form/browser/boolwidgets.py src/zope/app/form/browser/configure.zcml src/zope/app/form/browser/display.pt src/zope/app/form/browser/edit.pt src/zope/app/form/browser/editview.py src/zope/app/form/browser/exception.py src/zope/app/form/browser/form.txt src/zope/app/form/browser/formview.py src/zope/app/form/browser/i18n.py src/zope/app/form/browser/i18n.txt src/zope/app/form/browser/interfaces.py src/zope/app/form/browser/itemswidgets.py src/zope/app/form/browser/macros.py src/zope/app/form/browser/meta.zcml src/zope/app/form/browser/metaconfigure.py src/zope/app/form/browser/metadirectives.py src/zope/app/form/browser/objectwidget.py src/zope/app/form/browser/schemadisplay.py src/zope/app/form/browser/sequencewidget.py src/zope/app/form/browser/source.py src/zope/app/form/browser/subedit.pt src/zope/app/form/browser/submit.py src/zope/app/form/browser/textwidgets.py src/zope/app/form/browser/widget.py src/zope/app/form/browser/widgets.txt src/zope/app/form/browser/tests/__init__.py src/zope/app/form/browser/tests/i18n.zcml src/zope/app/form/browser/tests/support.py src/zope/app/form/browser/tests/test_add.py src/zope/app/form/browser/tests/test_browserwidget.py src/zope/app/form/browser/tests/test_directives.py src/zope/app/form/browser/tests/test_editview.py src/zope/app/form/browser/tests/test_form.py src/zope/app/form/browser/tests/test_functional_editview.py src/zope/app/form/browser/tests/test_functional_i18n.py src/zope/app/form/browser/tests/test_widgetdirective.py src/zope/app/form/browser/tests/testconfigure.zcml src/zope/app/form/browser/tests/testeditform.pt src/zope/app/form/browser/tests/testlabeltranslation.mo src/zope/app/form/browser/tests/testlabeltranslation.po src/zope/app/form/browser/tests/widgetDirectives.zcml src/zope/app/form/browser/tests/locales/formtest.pot src/zope/app/form/browser/tests/locales/de/LC_MESSAGES/formtest.mo src/zope/app/form/browser/tests/locales/de/LC_MESSAGES/formtest.po src/zope/app/form/tests/__init__.py src/zope/app/form/tests/test_macros.pt src/zope/app/form/tests/test_utility.py src/zope/app/form/tests/utils.py�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zope.app.form-4.0.2/src/zope.app.form.egg-info/dependency_links.txt���������������������������������0000644�0001750�0001750�00000000001�11340453337�024553� 0����������������������������������������������������������������������������������������������������ustar �sidnei��������������������������sidnei����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zope.app.form-4.0.2/CHANGES.txt���������������������������������������������������������������������0000644�0001750�0001750�00000011200�11340453312�015322� 0����������������������������������������������������������������������������������������������������ustar �sidnei��������������������������sidnei�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������======= CHANGES ======= 4.0.2 (2010-01-22) ================== - Seems like 4.0.1 was released already. Brown bag. 4.0.1 (2010-01-08) ================== - Import 'escape' for backwards compatibility as packages turn out to be importing this too, even though it's actually from the Python standard library. - Widget documentation is now on PyPI too. 4.0 (2010-01-08) ================ - The widget implementations have been moved to zope.formlib. This makes this package depend on zope.formlib. The dependency of zope.formlib on this package has been broken. 3.12.1 (2009-12-22) =================== - Added missing zope.datetime dependency. 3.12.0 (2009-12-22) =================== - Use zope.browserpage in favor of zope.app.pagetemplate. 3.11.1 (2009-12-22) =================== - Prefer zope.testing.doctest over doctestunit and adjust test output to newer zope.schema release. 3.11.0 (2009-12-18) =================== - Use zope.component.testing in favor of zope.app.testing where possible. - Define dummy standard_macros for test purposes. This reduces the test dependencies by zope.app.basicskin and zope.browserresource. - Removed the zope.app.container and zope.app.publisher testing dependencies. - Refactored code to remove zope.app.component dependency. - Made the tests independent of zope.app.locales. - Reduce zope.app test dependencies by avoiding zope.app.securitypolicy and zope.app.zcmlfiles. 3.10.0 (2009-12-17) =================== - Avoid the ``zope.app.basicskin`` dependency, by defining our own FormMacros. 3.9.0 (2009-10-08) ================== - Internationalized 'Invalid value' used with ConversionError - Added dependency on transaction and test dependency on zope.app.component. - Moved dependencies on ZODB3 and zope.location to the test extra. - Reduced the dependency on zope.app.publisher to a dependency on zope.browsermenu plus a test dependency on zope.browserpage. 3.8.1 (2009-07-23) ================== - Fix unittest failure due to translation update. 3.8.0 (2009-05-24) ================== - Use standard properties instead of `zope.cachedescriptors`. - Require `zope.browser` 1.1 instead of `zope.app.container` for IAdding. 3.7.3 (2009-05-11) ================== - Fixed invalid markup. 3.7.2 (2009-03-12) ================== - Fixed bug where OrderedMultiSelectWidget did not respect the widgets size attribute. - Fixed bug in SequenceWidget where it crashed while trying to iterate a missing_value (None in most of cases) on _getRenderedValue. - Adapt to removal of deprecated interfaces from zope.component.interfaces. The IView was moved to zope.publisher and we use our custom IWidgetFactory interface instead of removed zope.component.interfaces.IViewFactory. - Fix tests to work on Python 2.6. 3.7.1 (2009-01-31) ================== - Adapt to the upcoming zope.schema release 3.5.1 which will also silence the spurious `set` failures. 3.7.0 (2008-12-11) ================== - use zope.browser.interfaces.ITerms instead of zope.app.form.browser.interfaces - Depending on zope.schema>=3.5a1 which uses the builtin ``set`` instead of the ``sets`` module. 3.6.4 (2008-11-26) ================== - The URIDisplayWidget doesn't render an anchor for empty/None values. 3.6.3 (2008-10-15) ================== - Get rid of deprecated usage of LayerField from zope.app.component.back35, replaced by zope.configuration.fields.GlobalInterface. 3.6.2 (2008-09-08) ================== - Fixed restructured text in doc tests to unbreak the PyPI page. (3.6.1 skipped due to a typo) 3.6.0 (2008-08-22) ================== - Dropdown widgets display an item for the missing value even if the field is required when no value is selected. See zope/app/form/browser/README.txt on how to switch this off for BBB. - Source select widgets for required fields are now required as well. They used not to be required on the assumption that some value would be selected by the browser, which had always been wrong except for dropdown widgets. 3.5.0 (2008-06-05) ================== - Translate the title on SequenceWidget's "Add <title>" button. - No longer uses zapi. 3.4.2 (2008-02-07) ================== - Made display widgets for sources translate message IDs correctly. 3.4.1 (2007-10-31) ================== - Resolve ``ZopeSecurityPolicy`` deprecation warning. 3.4.0 (2007-10-24) ================== - ``zope.app.form`` now supports Python2.5 - Initial release independent of the main Zope tree. Before 3.4 ========== This package was part of the Zope 3 distribution and did not have its own CHANGES.txt. For earlier changes please refer to either our subversion log or the CHANGES.txt of earlier Zope 3 releases. ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������zope.app.form-4.0.2/bootstrap.py��������������������������������������������������������������������0000644�0001750�0001750�00000003367�11340453312�016117� 0����������������������������������������������������������������������������������������������������ustar �sidnei��������������������������sidnei�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������############################################################################## # # Copyright (c) 2006 Zope Corporation 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 72703 2007-02-20 11:49:26Z jim $ """ 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) �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������