{ "info": { "author": "Plone Foundation", "author_email": "releasemanager@plone.org", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Framework :: Plone", "Framework :: Plone :: 5.2", "Framework :: Zope :: 4", "Programming Language :: Python", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7" ], "description": "=============\nplone.z3cform\n=============\n\nplone.z3cform is a library that enables the use of `z3c.form`_ in Zope.\nIt depends only on Zope and z3c.form.\n\nFor Plone integration, there is also `plone.app.z3cform`_, which can be\ninstalled to make the default form templates more Ploneish. That package\npulls in this one as a dependency.\n\nIn addition to pure interoperability support, a few patterns which are useful\nin Zope 2 applications are implemented here.\n\n.. contents:: Contents\n\nInstallation\n============\n\nTo use this package, simply install it as a dependency of the package where\nyou are using forms, via the ``install_requires`` line in ``setup.py``. Then\nloads its configuration via ZCML::\n\n \n\nStandalone forms\n================\n\nIf you are using Zope 2.12 or later, z3c.form forms will *almost* work\nout of the box. However, two obstacles remain:\n\n* The standard file upload data converter does not work with Zope 2, so\n fields (like ``zope.schema.Bytes``) using the file widget will not work\n correctly.\n* z3c.form expects request values to be decoded to unicode strings by the\n publisher, which does not happen in Zope 2.\n\nTo address the first problem, this package provides an override for the\nstandard data converter adapter (registered on the ``zope.schema.Bytes`` class\ndirectly, so as to override the default, which is registered for the less\ngeneral ``IBytes`` interface). To address the second, it applies a monkey\npatch to the ``update()`` methods of ``BaseForm`` and ``GroupForm`` from\n``z3c.form`` which performs the necessary decoding in a way that is consistent\nwith the Zope 3-style publisher.\n\nNote: If you override ``update()`` in your own form you must either call the\nbase class version or call the function ``plone.z3cform.z2.processInputs()``\non the request *before* any values in the request are used. For example::\n\n from plone.z3cform.z2 import processInputs\n from z3c.form import form\n\n ...\n\n class MyForm(form.Form):\n\n ...\n\n def update(self):\n processInputs(self.request)\n ...\n\nOther than that, you can create a form using standard `z3c.form`_ conventions.\nFor example::\n\n from zope.interface import Interface\n from zope import schema\n from z3c.form import form, button\n\n class IMyFormSchema(Interface):\n field1 = schema.TextLine(title=u\"A field\")\n field2 = schema.Int(title=u\"Another field\")\n\n class MyForm(form.Form):\n fields = field.Fields(IMyformSchema)\n\n @button.buttonAndHandler(u'Submit')\n def handleApply(self, action):\n data, errors = self.extractData()\n # do something\n\nYou can register this as a view in ZCML using the standard ````\ndirective::\n\n \n\nA default template will be used to render the form. If you want to associate\na custom template, you should do so by setting the ``template`` class variable\ninstead of using the ``template`` attribute of the ZCML directive::\n\n from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile\n\n class MyForm(form.Form):\n fields = field.Fields(IMyformSchema)\n template = ViewPageTemplateFile('mytemplate.pt')\n\n @button.buttonAndHandler(u'Submit')\n def handleApply(self, action):\n data, errors = self.extractData()\n # do something\n\nSee below for more details about standard form macros.\n\nNote that to render any of the standard widgets, you will also need to make\nsure the request is marked with ``z3c.form.interfaces.IFormLayer``, as is\nthe norm with z3c.form. If you install `plone.app.z3cform`_ in Plone, that\nis already done for you, but in other scenarios, you will need to do this\nin whichever way Zope browser layers are normally applied.\n\nLayout form wrapper\n===================\n\nIn versions of Zope prior to 2.12, z3c.form instances cannot be registered\nas views directly, because they do not support Zope 2 security (via the\nacquisition mechanism). Whilst it may be possible to support this via custom\nmix-ins, the preferred approach is to use a wrapper view, which separates the\nrendering of the form from the page layout.\n\nThere are a few other reasons why you may want to use the wrapper view, even\nin later versions of Zope:\n\n* To support both an earlier version of Zope and Zope 2.12+\n* To re-use the same form in multiple views or viewlets\n* To use the ``IPageTemplate`` adapter lookup semantics from z3c.form to\n provide a different default or override template for the overall page\n layout, while retaining (or indeed customising independently) the default\n layout of the form.\n\nWhen using the wrapper view, you do *not* need to ensure your requests are\nmarked with ``IFormLayer``, as it is applied automatically during the\nrendering of the wrapper view.\n\nThe easiest way to create a wrapper view is to call the ``wrap_form()``\nfunction::\n\n from zope.interface import Interface\n from zope import schema\n from z3c.form import form, button\n\n from plone.z3cform import layout\n\n class IMyFormSchema(Interface):\n field1 = schema.TextLine(title=u\"A field\")\n field2 = schema.Int(title=u\"Another field\")\n\n class MyForm(form.Form):\n fields = field.Fields(IMyformSchema)\n\n @button.buttonAndHandler(u'Submit')\n def handleApply(self, action):\n data, errors = self.extractData()\n # do something\n\n MyFormView = layout.wrap_form(MyForm)\n\nYou can now register the (generated) ``MyFormView`` class as a browser view::\n\n \n\nIf you want to have more control, you can define the wrapper class manually.\nYou should derive from the default version to get the correct semantics. The\nfollowing is equivalent to the ``wrap_form()`` call above::\n\n class MyFormView(layout.FormWrapper):\n form = MyForm\n\nYou can of then add additional methods to the class, use a custom page\ntemplate, and so on.\n\nThe default ``FormWrapper`` class exposes a few methods and properties:\n\n* ``update()`` is called to prepare the request and then update the wrapped\n form.\n* ``render()`` is called to render the wrapper view. If a template has\n been set (normally via the ``template`` attribute of the\n ```` directive), it will be rendered here. Otherwise,\n a default page template is found by adapting the view (``self``) and\n the request to ``zope.pagetemplate.interfaces.IPageTemplate``, in the\n same way that ``z3c.form`` does for its views. A default template is\n supplied with this package (and customised in `plone.app.z3cform`_ to\n achieve a standard Plone look and feel).\n* ``form`` is a class variable referring to the form class, as set above.\n* ``form_instance`` is an instance variable set to the current form instance\n once the view has been initialised.\n\nWhen a form is rendered in a wrapper view, the form instance is temporarily\nmarked with ``plone.z3cform.interfaces.IWrappedForm`` (unless the form is\na subform), to allow custom adapter registrations. Specifically, this is used\nto ensure that a form rendered \"standalone\" gets a full-page template applied,\nwhile a form rendered in a wrapper is rendered using a template that renders\nthe form elements only.\n\nDefault templates and macros\n============================\n\nSeveral standard templates are provided with this package. These are all\nregistered as adapters from ``(view, request)`` to ``IPageTemplate``, as is\nthe convention in z3c.form. It therefore follows that these defaults can be\ncustomised with an adapter override, e.g. for a specific browser layer. This\nis useful if you want to override the standard rendering of all forms. If you\njust want to provide a custom template for a particular form or wrapper view,\nyou can specify a template directly on the form or view, as shown above.\n\n* ``templates/layout.pt`` is the default template for the layout wrapper view.\n It uses the CMFDefault ``main_template`` and fills the ``header`` slot.\n* ``templates/wrappedform.pt`` is the default template for wrapped forms.\n It renders the ``titlelessform`` macro from the ``@@ploneform-macros`` view.\n* ``templates/subform.pt`` is the default template for sub-forms.\n It uses the macros in ``@@ploneform-macros`` view to render a heading,\n top/bottom content (verbatim) and the fields and actions of the subform (but\n does not) render the ``
`` tag itself.\n* ``templates/form.pt`` is the default template for a standalone form. It uses\n the macro ``context/@@standard_macros/page`` (supplied by Five and normally\n delegating to CMF's ``main_template``) to render a form where the form label\n is the page heading.\n\nAs hinted, this package also registers a view ``@@ploneform-macros``, which\ncontains a set of macros that be used to construct forms with a standard\nlayout, error message display, and so on. It contains the following macros:\n\n* ``form`` is a full page form, including the label (output as an ``

``),\n description, and all the elements of ``titlelessform``. It defines two\n slots: ``title`` contains the label, and ``description`` contains the\n description.\n* ``titlelessform`` includes the form ``status`` at the top, the ````\n element, and the contents of the ``fields`` and ``actions`` macros. It also\n defines four slots: ``formtop`` is just inside the opening ```` tag;\n ``formbottom``` is just inside the closing ```` tag;\n ``fields`` contains the ``fields`` macro; and ``actions`` contains the\n ``actions`` macro.\n* ``fields`` iterates over all widgets in the form and renders each, using the\n contents of the ``field`` macro. It also defines one slot, ``field`` which\n contains the ``field`` macro.\n* ``field`` renders a single field. It expects the variable ``widget`` to be\n defined in the TAL scope, referring to a z3c.form widget instance. It will\n output an error message if there is a field validation error, a label,\n a marker to say whether the field is required, the field description, and\n the widget itself (normally just an ```` element).\n* ``actions`` renders all actions (buttons) on the form. This normally results\n in a row of ```` elements.\n\nThus, to use the ``titlelessform`` macro, you could add something like the\nfollowing in a custom form template::\n\n \n\nNote that all of the templates mentioned above are customised by\n`plone.app.z3cform`_ to use standard Plone markup (but still retain the same\nmacros), so if you are using that package to configure this one, you should\nlook for the Plone-specific versions there.\n\nTemplate factories\n==================\n\nIf you want to provide an ``IPageTemplate`` adapter to customise the default\npage template used for wrapper views, forms or sub-forms, this package\nprovides helper classes to create an adapter factory for that purpose. You\nshould use these instead of ``z3c.form.form.FormTemplateFactory`` and\n(possibly) ``z3c.form.widget.WidgetTemplateFactory`` to get page templates\nwith Zope 2 semantics. These factories are also `Chameleon`_ aware, if you\nhave `five.pt`_ installed.\n\nThe most commonly used factory is\n``plone.z3cform.templates.ZopeTwoFormTemplateFactory``, which can be used to\nrender a wrapper view or a standalone form.\n\nTo render a wrapped form, you can use\n``plone.z3cform.templates.FormTemplateFactory``, which is closer to the\ndefault ``z3c.form`` version, but adds Chameleon-awareness.\n\nTo render a widget, the default ``WidgetTemplateFactory`` from z3c.form should\nsuffice, but if you need Zope 2 semantics for any reason, you can use\n``plone.z3cform.templates.ZopeTwoWidgetTemplateFactory``.\n\nAs an example, here are the default registrations from this package::\n\n import z3c.form.interfaces\n import plone.z3cform.interfaces\n\n from plone.z3cform.templates import ZopeTwoFormTemplateFactory\n from plone.z3cform.templates import FormTemplateFactory\n\n path = lambda p: os.path.join(os.path.dirname(plone.z3cform.__file__), 'templates', p)\n\n layout_factory = ZopeTwoFormTemplateFactory(path('layout.pt'),\n form=plone.z3cform.interfaces.IFormWrapper\n )\n\n wrapped_form_factory = FormTemplateFactory(path('wrappedform.pt'),\n form=plone.z3cform.interfaces.IWrappedForm,\n )\n\n # Default templates for the standalone form use case\n\n standalone_form_factory = ZopeTwoFormTemplateFactory(path('form.pt'),\n form=z3c.form.interfaces.IForm\n )\n\n subform_factory = FormTemplateFactory(path('subform.pt'),\n form=z3c.form.interfaces.ISubForm\n )\n\nThese are registered in ZCML like so::\n\n \n \n \n\n \n \n \n\nThe widget traverser\n====================\n\nIt is sometimes useful to be able to register a view on a *widget* and be\nable to traverse to that view, for example during a background AJAX request.\nAs an example of widget doing this, see `plone.formwidget.autocomplete`_.\n\nThis package provides a ``++widget++`` namespace traversal adapter which can\nbe used for this purpose. It is looked up on either the form wrapper view,\nor the form itself (in the case of standalone) forms. Thus, if you have a\nform view called ``@@my-form``, with a field called ``myfield``, you could\ntraverse to the widget for that view using::\n\n http://example.com/@@my-form/++widget++myfield\n\nThe widget may be on the form itself, or in a group (fieldset). If it exists\nin multiple groups, the first one found will be used.\n\nThe example above will yield widget, but it is probably not publishable.\nYou would therefore commonly register a view on the widget itself and use\nthat. In this case, ``self.context`` in the view is the widget instance. Such\na view could be looked up with::\n\n http://example.com/@@my-form/++widget++myfield/@@some-view\n\nA caveat about security\n-----------------------\n\nIn Zope 2.12 and later, the security machinery is aware of ``__parent__``\npointers. Thus, traversal and authorisation on ``@@some-view`` in the example\nabove will work just fine for a standard widget. In earlier versions of Zope,\nyou will need to mix acquisition into your widget (which rules out using any\nof the standard ``z3c.form`` widgets). For example::\n\n from Acquisition import Explicit\n from z3c.form.widget import Widget\n\n class MyWidget(Widget, Explicit):\n ...\n\nUnfortunately, in Zope 2.12, this will cause some problems during traversal\nunless you also mix acquisition into the view you registered on the widget\n(``@@some-view`` above). Specifically, you will get an error as the publisher\ntries to wrap the view in the widget.\n\nTo stay compatible with both Zope 2.12+ and earlier versions, you have two\noptions:\n\n* Ensure that you mix acquisition into the view on the widget\n* Ensure that the widget inherits from ``Explicit``, but does *not* provide\n the ``IAcquirer`` interface. This tricks the publisiher into relying on\n ``__parent__`` pointers in Zope 2.12.\n\nTo do the latter, you can use ``implementsOnly()``, e.g.::\n\n from zope.interface import implementsOnly\n from Acquisition import Explicit\n from z3c.form.widget import Widget\n\n ...\n\n class MyWidget(Widget, Explicit):\n implementsOnly(IMyWidget) # or just IWdget from z3c.form\n ...\n\n.. _z3c.form: http://pypi.python.org/pypi/z3c.form\n.. _plone.app.z3cform: http://pypi.python.org/pypi/plone.app.z3cform\n.. _CMF: http://www.zope.org/Products/CMF\n.. _Chameleon: http://pypi.python.org/pypi/Chameleon\n.. _five.pt: http://pypi.python.org/pypi/five.pt\n.. _plone.formwidget.autocomplete: http://pypi.python.org/pypi/plone.formwidget.autocomplete\n\nFieldsets and form extenders\n============================\n\nThe ``plone.z3cform.fieldsets`` package provides support for z3c.form groups\n(fieldsets) and other modifications via \"extender\" adapters. The idea is that\na third party component can modify the fields in the form and the way that\nthey are grouped and ordered.\n\nThis support relies on a mixin class, which is itself a subclass of\nz3c.form's ``GroupForm``::\n\n >>> from plone.z3cform.fieldsets import group, extensible\n\nTo use this, you have to mix it into another form as the *first* base class::\n\n >>> from zope.annotation import IAttributeAnnotatable\n >>> from z3c.form import form, field, tests, group\n >>> from zope.interface import Interface\n >>> from zope.interface import implementer\n >>> from zope import schema\n\n >>> class ITest(Interface):\n ... title = schema.TextLine(title=u\"Title\")\n\n >>> @implementer(ITest, IAttributeAnnotatable)\n ... class Test(object):\n ... # avoid needing an acl_users for this test in Zope 2.10\n ... __allow_access_to_unprotected_subobjects__ = 1\n ...\n ... title = u\"\"\n ... def getPhysicalRoot(self): # needed for template to acquire REQUEST in Zope 2.10\n ... return self\n\n >>> class TestForm(extensible.ExtensibleForm, form.Form):\n ... fields = field.Fields(ITest)\n\nHere, note the order of the base classes. Also note that we use an ordinary\nset of fields directly on the form. This known as the default fieldset.\n\nThis form should work as-is, i.e. we can update it. First we need to fake a\nrequest::\n\n >>> from plone.z3cform.tests import TestRequest\n\n >>> request = TestRequest()\n >>> request.other = {}\n >>> context = Test()\n >>> context.REQUEST = request\n\n >>> form = TestForm(context, request)\n >>> form.update()\n >>> form.fields.keys()\n ['title']\n\nNow let's register an adapter that adds two new fields - one in the\ndefault fieldset as the first field, and one in a new group. To do this,\nwe only need to register a named multi-adapter. However, we can use a\nconvenience base class to make it easier to manipulate the fields of the\nform::\n\n >>> from plone.z3cform.fieldsets.interfaces import IFormExtender\n >>> from zope.component import adapter\n >>> from zope.component import provideAdapter\n\n >>> class IExtraBehavior(Interface):\n ... foo = schema.TextLine(title=u\"Foo\")\n ... bar = schema.TextLine(title=u\"Bar\")\n ... baz = schema.TextLine(title=u\"Baz\")\n ... fub = schema.TextLine(title=u\"Fub\")\n ... qux = schema.TextLine(title=u\"Qux\")\n\nOne plausible implementation is to use an annotation to store this data.\n\n::\n\n >>> from zope.annotation import factory\n >>> from zope.annotation.attribute import AttributeAnnotations\n >>> from persistent import Persistent\n >>> @implementer(IExtraBehavior)\n ... @adapter(Test)\n ... class ExtraBehavior(Persistent):\n ...\n ...\n ... foo = u\"\"\n ... bar = u\"\"\n ... baz = u\"\"\n ... fub = u\"\"\n ... qux = u\"\"\n\n >>> ExtraBehavior = factory(ExtraBehavior)\n >>> provideAdapter(ExtraBehavior)\n >>> provideAdapter(AttributeAnnotations)\n\nWe can now write the extender. The base class gives us some helper methods\nto add, remove and move fields. Here, we do a bit of unnecessary work just\nto exercise these methods.\n\n::\n\n >>> @adapter(Test, TestRequest, TestForm) # context, request, form\n ... class ExtraBehaviorExtender(extensible.FormExtender):\n ...\n ... def __init__(self, context, request, form):\n ... self.context = context\n ... self.request = request\n ... self.form = form\n ...\n ... def update(self):\n ... # Add all fields from an interface\n ... self.add(IExtraBehavior, prefix=\"extra\")\n ...\n ... # Remove the fub field\n ... self.remove('fub', prefix=\"extra\")\n ...\n ... all_fields = field.Fields(IExtraBehavior, prefix=\"extra\")\n ...\n ... # Insert fub again, this time at the top\n ... self.add(all_fields.select(\"fub\", prefix=\"extra\"), index=0)\n ...\n ... # Move 'baz' above 'fub'\n ... self.move('baz', before='fub', prefix='extra', relative_prefix='extra')\n ...\n ... # Move 'foo' after 'bar' - here we specify prefix manually\n ... self.move('foo', after='extra.bar', prefix='extra')\n ...\n ... # Remove 'bar' and re-insert into a new group\n ... self.remove('bar', prefix='extra')\n ... self.add(all_fields.select('bar', prefix='extra'), group='Second')\n ...\n ... # Move 'baz' after 'bar'. This means it also moves group.\n ... self.move('extra.baz', after='extra.bar')\n ...\n ... # Remove 'qux' and re-insert into 'Second' group,\n ... # then move it before 'baz'\n ... self.remove('qux', prefix='extra')\n ... self.add(all_fields.select('qux', prefix='extra'), group='Second')\n ... self.move('qux', before='baz', prefix='extra', relative_prefix='extra')\n\n >>> provideAdapter(factory=ExtraBehaviorExtender, name=u\"test.extender\")\n\nWith this in place, let's update the form once again::\n\n >>> form = TestForm(context, request)\n >>> form.update()\n\nAt this point, we should have a set of default fields that represent the\nones set in the adapter::\n\n >>> form.fields.keys()\n ['extra.fub', 'title', 'extra.foo']\n\nAnd we should have one group created by the group factory::\n\n >>> form.groups # doctest: +ELLIPSIS\n (,)\n\nNote that the created group is of a subtype of the standard z3c.form group,\nwhich has got support for a separate label and description as well as a\ncanonical name::\n\n >>> isinstance(form.groups[0], group.Group)\n True\n\nThis should have the group fields provided by the adapter as well::\n\n >>> form.groups[0].fields.keys()\n ['extra.bar', 'extra.qux', 'extra.baz']\n\nCRUD (Create, Read, Update and Delete) forms\n============================================\n\nThis module provides an abstract base class to create CRUD forms.\nBy default, such forms provide a tabular view of multiple objects, whose\nattributes can be edited in-place.\n\nPlease refer to the ``ICrudForm`` interface for more details.\n\n >>> from plone.z3cform.crud import crud\n\nSetup\n-----\n\n >>> from plone.z3cform.tests import setup_defaults\n >>> setup_defaults()\n\n\nA simple form\n-------------\n\nFirst, let's define an interface and a class to play with:\n\n >>> from zope import interface, schema\n >>> class IPerson(interface.Interface) :\n ... name = schema.TextLine()\n ... age = schema.Int()\n\n >>> @interface.implementer(IPerson)\n ... class Person(object):\n ... def __init__(self, name=None, age=None):\n ... self.name, self.age = name, age\n ... def __repr__(self):\n ... return \"\" % (self.name, self.age)\n\nFor this test, we take the the name of our persons as keys in our\nstorage:\n\n >>> storage = {'Peter': Person(u'Peter', 16),\n ... 'Martha': Person(u'Martha', 32)}\n\nOur simple form looks like this:\n\n >>> class MyForm(crud.CrudForm):\n ... update_schema = IPerson\n ...\n ... def get_items(self):\n ... return sorted(storage.items(), key=lambda x: x[1].name)\n ...\n ... def add(self, data):\n ... person = Person(**data)\n ... storage[str(person.name)] = person\n ... return person\n ...\n ... def remove(self, id_item):\n ... id, item = id_item\n ... del storage[id]\n\nThis is all that we need to render a combined edit add form containing\nall our items:\n\n >>> class FakeContext(object):\n ... def absolute_url(self):\n ... return 'http://nohost/context'\n >>> fake_context = FakeContext()\n\n >>> from plone.z3cform.tests import TestRequest\n >>> print(MyForm(fake_context, TestRequest())()) \\\n ... # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE\n
...Martha...Peter...
\n\nEditing items with our form\n---------------------------\n\nBefore we start with editing objects, let's log all events that the\nform fires for us:\n\n >>> from zope.lifecycleevent.interfaces import IObjectModifiedEvent\n >>> from plone.z3cform.tests import create_eventlog\n >>> log = create_eventlog(IObjectModifiedEvent)\n\n >>> request = TestRequest()\n >>> request.form['crud-edit.Martha.widgets.select-empty-marker'] = u'1'\n >>> request.form['crud-edit.Peter.widgets.select-empty-marker'] = u'1'\n >>> request.form['crud-edit.Martha.widgets.name'] = u'Martha'\n >>> request.form['crud-edit.Martha.widgets.age'] = u'55'\n >>> request.form['crud-edit.Peter.widgets.name'] = u'Franz'\n >>> request.form['crud-edit.Peter.widgets.age'] = u'16'\n >>> request.form['crud-edit.form.buttons.edit'] = u'Apply changes'\n >>> html = MyForm(fake_context, request)()\n >>> \"Successfully updated\" in html\n True\n\nTwo modified events should have been fired:\n\n >>> event1, event2 = log.pop(), log.pop()\n >>> storage['Peter'] in (event1.object, event2.object)\n True\n >>> storage['Martha'] in (event1.object, event2.object)\n True\n >>> log\n []\n\nIf we don't make any changes, we'll get a message that says so:\n\n >>> html = MyForm(fake_context, request)()\n >>> \"No changes made\" in html\n True\n >>> log\n []\n\nNow that we renamed Peter to Franz, it would be also nice to have\nFranz use 'Franz' as the id in the storage, wouldn't it?\n\n >>> storage['Peter']\n \n\nWe can override the CrudForm's ``before_update`` method to perform a\nrename whenever the name of a person is changed:\n\n >>> class MyRenamingForm(MyForm):\n ... def before_update(self, item, data):\n ... if data['name'] != item.name:\n ... del storage[item.name]\n ... storage[str(data['name'])] = item\n\nLet's rename Martha to Maria. This will give her another key in our\nstorage:\n\n >>> request.form['crud-edit.Martha.widgets.name'] = u'Maria'\n >>> html = MyRenamingForm(fake_context, request)()\n >>> \"Successfully updated\" in html\n True\n >>> log.pop().object == storage['Maria']\n True\n >>> log\n []\n >>> sorted(storage.keys())\n ['Maria', 'Peter']\n\nNext, we'll submit the form for edit, but we'll make no changes.\nInstead, we'll select one time. This shouldn't do anything, since we\nclicked the 'Apply changes' button:\n\n >>> request.form['crud-edit.Maria.widgets.name'] = u'Maria'\n >>> request.form['crud-edit.Maria.widgets.age'] = u'55'\n >>> request.form['crud-edit.Maria.widgets.select'] = [u'selected']\n >>> html = MyRenamingForm(fake_context, request)()\n >>> \"No changes\" in html\n True\n >>> log\n []\n\nAnd what if we do have changes *and* click the checkbox?\n\n >>> request.form['crud-edit.Maria.widgets.age'] = u'50'\n >>> html = MyRenamingForm(fake_context, request)()\n >>> \"Successfully updated\" in html\n True\n >>> log.pop().object == storage['Maria']\n True\n >>> log\n []\n\nIf we omit the name, we'll get an error:\n\n >>> request.form['crud-edit.Maria.widgets.name'] = u''\n >>> html = MyRenamingForm(fake_context, request)()\n >>> \"There were some errors\" in html\n True\n >>> \"Required input is missing\" in html\n True\n\nWe expect an error message in the title cell of Maria:\n\n >>> checkbox_pos = html.index('crud-edit.Maria.widgets.select-empty-marker')\n >>> \"Required input is missing\" in html[checkbox_pos:]\n True\n\nDelete an item with our form\n----------------------------\n\nWe can delete an item by selecting the item we want to delete and\nclicking the \"Delete\" button:\n\n >>> request = TestRequest()\n >>> request.form['crud-edit.Peter.widgets.select'] = ['selected']\n >>> request.form['crud-edit.form.buttons.delete'] = u'Delete'\n >>> html = MyForm(fake_context, request)()\n >>> \"Successfully deleted items\" in html\n True\n >>> 'Franz' in html\n False\n >>> storage\n {'Maria': }\n\nAdd an item with our form\n-------------------------\n\n >>> from zope.lifecycleevent.interfaces import IObjectCreatedEvent\n >>> from plone.z3cform.tests import create_eventlog\n >>> log = create_eventlog(IObjectCreatedEvent)\n\n >>> request = TestRequest()\n >>> request.form['crud-add.form.widgets.name'] = u'Daniel'\n >>> request.form['crud-add.form.widgets.age'] = u'28'\n >>> request.form['crud-add.form.buttons.add'] = u'Add'\n >>> html = MyForm(fake_context, request)()\n >>> \"Item added successfully\" in html\n True\n\nAdded items should show up right away:\n\n >>> \"Daniel\" in html\n True\n\n >>> storage['Daniel']\n \n >>> log.pop().object == storage['Daniel']\n True\n >>> log\n []\n\nWhat if we try to add \"Daniel\" twice? Our current implementation of\nthe add form will simply overwrite the data:\n\n >>> save_daniel = storage['Daniel']\n >>> html = MyForm(fake_context, request)()\n >>> \"Item added successfully\" in html\n True\n >>> save_daniel is storage['Daniel']\n False\n >>> log.pop().object is storage['Daniel']\n True\n\nLet's implement a class that prevents this:\n\n >>> class MyCarefulForm(MyForm):\n ... def add(self, data):\n ... name = data['name']\n ... if name not in storage:\n ... return super(MyCarefulForm, self).add(data)\n ... else:\n ... raise schema.ValidationError(\n ... u\"There's already an item with the name '%s'\" % name)\n\n >>> save_daniel = storage['Daniel']\n >>> html = MyCarefulForm(fake_context, request)()\n >>> \"Item added successfully\" in html\n False\n >>> \"There's already an item with the name 'Daniel'\" in html\n True\n >>> save_daniel is storage['Daniel']\n True\n >>> len(log) == 0\n True\n\nRender some of the fields in view mode\n--------------------------------------\n\nWe can implement in our form a ``view_schema`` attribute, which will\nthen be used to view information in our form's table. Let's say we\nwanted the name of our persons to be viewable only in the table:\n\n >>> from z3c.form import field\n >>> class MyAdvancedForm(MyForm):\n ... update_schema = field.Fields(IPerson).select('age')\n ... view_schema = field.Fields(IPerson).select('name')\n ... add_schema = IPerson\n\n >>> print(MyAdvancedForm(fake_context, TestRequest())()) \\\n ... # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE\n
...Daniel...Maria...
\n\nWe can still edit the age of our Persons:\n\n >>> request = TestRequest()\n >>> request.form['crud-edit.Maria.widgets.age'] = u'40'\n >>> request.form['crud-edit.Daniel.widgets.age'] = u'35'\n >>> request.form['crud-edit.form.buttons.edit'] = u'Apply Changes'\n >>> html = MyAdvancedForm(fake_context, request)()\n >>> \"Successfully updated\" in html\n True\n\n >>> storage['Maria'].age\n 40\n >>> storage['Daniel'].age\n 35\n\nWe can still add a Person using both name and age:\n\n >>> request = TestRequest()\n >>> request.form['crud-add.form.widgets.name'] = u'Thomas'\n >>> request.form['crud-add.form.widgets.age'] = u'28'\n >>> request.form['crud-add.form.buttons.add'] = u'Add'\n >>> html = MyAdvancedForm(fake_context, request)()\n >>> \"Item added successfully\" in html\n True\n >>> len(storage)\n 3\n >>> storage['Thomas']\n \n\nOur form can also contain links to our items:\n\n >>> class MyAdvancedLinkingForm(MyAdvancedForm):\n ... def link(self, item, field):\n ... if field == 'name':\n ... return 'http://en.wikipedia.org/wiki/%s' % item.name\n\n >>> print(MyAdvancedLinkingForm(fake_context, TestRequest())()) \\\n ... # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE\n
...\n ...\n\nWhat if we wanted the name to be both used for linking to the item\n*and* for edit? We can just include the title field twice:\n\n >>> class MyAdvancedLinkingForm(MyAdvancedLinkingForm):\n ... update_schema = IPerson\n ... view_schema = field.Fields(IPerson).select('name')\n ... add_schema = IPerson\n\n >>> print(MyAdvancedLinkingForm(fake_context, TestRequest())()) \\\n ... # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE\n \n\nWe can now change Thomas's name and see the change reflected in the\nWikipedia link immediately:\n\n >>> request = TestRequest()\n >>> for name in 'Daniel', 'Maria', 'Thomas':\n ... request.form['crud-edit.%s.widgets.name' % name] = storage[name].name\n ... request.form['crud-edit.%s.widgets.age' % name] = storage[name].age\n >>> request.form['crud-edit.Thomas.widgets.name'] = u'Dracula'\n >>> request.form['crud-edit.form.buttons.edit'] = u'Apply Changes'\n\n >>> print(MyAdvancedLinkingForm(fake_context, request)()) \\\n ... # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE\n \n >>> storage['Thomas'].name = u'Thomas'\n\nDon't render one part\n---------------------\n\nWhat if we wanted our form to display only one part, that is, only the\nadd *or* the edit form. Our CrudForm can implement\n``editform_factory`` and ``addform_factory`` to override one or both\nforms. Seeting one of these to ``crud.NullForm`` will make them\ndisappear:\n\n >>> class OnlyEditForm(MyForm):\n ... addform_factory = crud.NullForm\n >>> html = OnlyEditForm(fake_context, TestRequest())()\n >>> 'Edit' in html, 'Add' in html\n (True, False)\n\n >>> class OnlyAddForm(MyForm):\n ... editform_factory = crud.NullForm\n >>> html = OnlyAddForm(fake_context, TestRequest())()\n >>> 'Edit' in html, 'Add' in html\n (False, True)\n\nRender only in view, and define own actions\n-------------------------------------------\n\nSometimes you want to present a list of items, possibly in view mode\nonly, and have the user select one or more of the items to perform\nsome action with them. We'll present a minimal example that does this\nhere.\n\nWe can simply leave the ``update_schema`` class attribute out (it\ndefaults to ``None``). Furthermore, we'll need to override the\nediform_factory with our custom version that provides other buttons\nthan the 'edit' and 'delete' ones:\n\n >>> from pprint import pprint\n >>> from z3c.form import button\n\n >>> class MyEditForm(crud.EditForm):\n ... @button.buttonAndHandler(u'Capitalize', name='capitalize')\n ... def handle_capitalize(self, action):\n ... self.status = u\"Please select items to capitalize first.\"\n ... selected = self.selected_items()\n ... if selected:\n ... self.status = u\"Capitalized items\"\n ... for id, item in selected:\n ... item.name = item.name.upper()\n\n >>> class MyCustomForm(crud.CrudForm):\n ... view_schema = IPerson\n ... editform_factory = MyEditForm\n ... addform_factory = crud.NullForm # We don't want an add part.\n ...\n ... def get_items(self):\n ... return sorted(storage.items(), key=lambda x: x[1].name)\n\n >>> request = TestRequest()\n >>> html = MyCustomForm(fake_context, TestRequest())()\n >>> \"Delete\" in html, \"Apply changes\" in html, \"Capitalize\" in html\n (False, False, True)\n >>> pprint(storage)\n {'Daniel': ,\n 'Maria': ,\n 'Thomas': }\n\n >>> request.form['crud-edit.Thomas.widgets.select'] = ['selected']\n >>> request.form['crud-edit.form.buttons.capitalize'] = u'Capitalize'\n >>> html = MyCustomForm(fake_context, request)()\n >>> \"Capitalized items\" in html\n True\n >>> pprint(storage)\n {'Daniel': ,\n 'Maria': ,\n 'Thomas': }\n\nWe *cannot* use any of the other buttons:\n\n >>> del request.form['crud-edit.form.buttons.capitalize']\n >>> request.form['crud-edit.form.buttons.delete'] = u'Delete'\n >>> html = MyCustomForm(fake_context, request)()\n >>> \"Successfully deleted items\" in html\n False\n >>> 'Thomas' in storage\n True\n\nCustomizing sub forms\n---------------------\n\nThe EditForm class allows you to specify an editsubform_factory-a classs\ninherits from EditSubForm. This allows you to say, override the crud-row.pt\npage template and customize the look of the fields.\n\n >>> import zope.schema\n >>> class MyCustomEditSubForm(crud.EditSubForm):\n ...\n ... def _select_field(self):\n ... \"\"\"I want to customize the field that it comes with...\"\"\"\n ... select_field = field.Field(\n ... zope.schema.TextLine(__name__='select',\n ... required=False,\n ... title=u'select'))\n ... return select_field\n\n >>> class MyCustomEditForm(MyEditForm):\n ... editsubform_factory = MyCustomEditSubForm\n\n >>> class MyCustomFormWithCustomSubForm(MyCustomForm):\n ... editform_factory = MyCustomEditForm\n\n >>> request = TestRequest()\n >>> html = MyCustomFormWithCustomSubForm(fake_context, TestRequest())()\n\nStill uses same form as before\n >>> \"Delete\" in html, \"Apply changes\" in html, \"Capitalize\" in html\n (False, False, True)\n\nJust changes the widget used for selecting...\n >>> 'type=\"checkbox\"' in html\n False\n\nUsing batching\n--------------\n\nThe CrudForm base class supports batching. When setting the\n``batch_size`` attribute to a value greater than ``0``, we'll only get\nas many items displayed per page.\n\n >>> class MyBatchingForm(MyForm):\n ... batch_size = 2\n >>> request = TestRequest()\n >>> html = MyBatchingForm(fake_context, request)()\n >>> \"Daniel\" in html, \"Maria\" in html\n (True, True)\n >>> \"THOMAS\" in html\n False\n\nMake sure, the batch link to the next page is available\n\n >>> 'crud-edit.form.page=1' in html\n True\n\nShow next page and check content\n\n >>> request = TestRequest(QUERY_STRING='crud-edit.form.page=1')\n >>> request.form['crud-edit.form.page'] = '1'\n >>> html = MyBatchingForm(fake_context, request)()\n >>> \"Daniel\" in html, \"Maria\" in html\n (False, False)\n >>> \"THOMAS\" in html\n True\n\nThe form action also includes the batch page information so\nthe correct set of subforms can be processed::\n\n >>> print(html) \\\n ... # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE\n \n ...\n
\n ...\n\nLet's change Thomas' age on the second page:\n\n >>> request.form['crud-edit.Thomas.widgets.name'] = u'Thomas'\n >>> request.form['crud-edit.Thomas.widgets.age'] = '911'\n >>> request.form['crud-edit.form.buttons.edit'] = u'Apply changes'\n >>> html = MyBatchingForm(fake_context, request)()\n >>> \"Successfully updated\" in html\n True\n >>> \"911\" in html\n True\n\nChangelog\n=========\n\n1.1.1 (2019-10-12)\n------------------\n\nBug fixes:\n\n- Fix edit/delete in paginated crud-forms [fRiSi]\n\n\n1.1.0 (2019-04-09)\n------------------\n\nNew features:\n\n- Change license to GPLv2\n [petschki]\n\n- Enable ``:record[s]`` fields in ``z2.processInputs``\n [petschki]\n\n- Cosmetic tweaks.\n [gforcada]\n\n1.0.0 (2018-11-04)\n------------------\n\nNew features:\n\n- Support for Python 3\n [pbauer, davilima6, ale-rt, jensens]\n\nBug fixes:\n\n- Test cleanup.\n [jensens]\n\n- Rename folder templates to pagetemplates, because of ZCML browser directive warnings.\n [jensens]\n\n- Removal of tuple parameter unpacking in method definition (Fixes #14)\n [ale-rt]\n\n- Provide an up-to-date bootstrap.py\n [ale-rt]\n\n- Use the adapter and implementer decorators\n [ale-rt]\n\n\n\n0.9.1 (2017-09-03)\n------------------\n\nBug fixes:\n\n- Remove deprecated __of__ calls on BrowserViews\n [MrTango]\n\n\n0.9.0 (2016-05-25)\n------------------\n\nNew:\n\n- Enable groups aka fieldsets to be orderable.\n [jensens]\n\nFixes:\n\n- Fix batching navigation in CRUD form.\n [petschki]\n\n- Added two missing German translations.\n One of those fixes https://github.com/plone/Products.CMFPlone/issues/1580\n [jensens]\n\n- QA: pep8. [maurits, thet]\n\n\n0.8.1 (2015-01-22)\n------------------\n\n- Feature: take group class from parent-form if given. If not given it uses\n the default class.\n [jensens]\n\n- Added Ukrainian translation\n [kroman0]\n\n- Added Italian translation\n [giacomos]\n\n\n0.8.0 (2012-08-30)\n------------------\n\n* Remove backwards-compatibility code for Zope < 2.12\n [davisagli]\n\n* Use plone.testing for functional test layer support.\n [hannosch]\n\n* Use ViewPageTemplateFile from zope.browserpage.\n [hannosch]\n\n* Use form action URL as given by the view, instead of implementing it\n in the template as a call to the ``getURL`` method of the request.\n [malthe]\n\n* Use plone.batching for batches instead of z3c.batching\n [tom_gross]\n\n0.7.8 - 2011-09-24\n------------------\n\n* Do not display h1 element if there is no label on view.\n [thomasdesvenain]\n\n* Add Chinese translation.\n [jianaijun]\n\n0.7.7 - 2011-06-30\n------------------\n\n* Avoid rendering a wrapped form if a redirect has already occurred after\n updating it.\n [davisagli]\n\n* Remove elements from inside the CRUD table TBODY element\n they were otherwise unused (and illegal in that location of the HTML content\n model).\n [mj]\n\n0.7.6 - 2011-05-17\n------------------\n\n* Add ability to find widgets with non-integer names in lists. This shouldn't\n generally be something that happens, and ideally should be removed if\n DataGridField looses it's 'AA' and 'TT' rows.\n [lentinj]\n\n0.7.5 - 2011-05-03\n------------------\n\n* Fix traversal tests on Zope 2.10 to handle TraversalError instead of\n LocationError.\n [elro]\n\n* Fix traversal.py syntax to be python2.4 compatible.\n\n* Revert [120798] as it breaks on Zope2.10 / Plone 3.3. We can deal with Zope\n 2.14 in 0.8.x.\n [elro]\n\n0.7.4 - 2011-05-03\n------------------\n\n* Define 'hidden' within field macro.\n [elro]\n\n* Ignore \"form.widgets.\" if ++widget++ path begins with it.\n [lentinj]\n\n* Rework traverser to handle lists and subforms\n [lentinj]\n\n* Only search a group's widgets if they exist. collective.z3cform.wizard doesn't\n create widgets for pages/groups other than the current one\n [lentinj, elro]\n\n* Deal with forward compatibility with Zope 2.14.\n\n* Adds Brazilian Portuguese translation.\n [davilima6]\n\n0.7.3 - 2011-03-02\n------------------\n\n* Handle wrong fieldnames more cleanly in the ++widget++ traverser.\n [elro]\n\n0.7.2 - 2011-02-17\n------------------\n\n* Make sure the CRUD add form doesn't use a standalone template.\n [davisagli]\n\n0.7.1 - 2011-01-18\n---------------------\n\n* Add zope.app.testing to test dependencies so that it continues to work under\n Zope 2.13.\n [esteele]\n\n0.7.0 - 2010-08-04\n------------------\n\n* Add a marker interface which can be used by widgets to defer any security\n checks they may be doing when they are set up during traversal with the\n ++widgets++ namespace\n [dukebody]\n\n* Fix re-ordering of fields not in the default fieldset. Thanks to Thomas\n Buchberger for the patch.\n [optilude]\n\n* Added Norwegian translation.\n [regebro]\n\n0.6.0 - 2010-04-20\n------------------\n\n* In the CRUD table, fix odd/even labels, which were reversed.\n [limi]\n\n* Added slots to the ``titlelessform`` macro. See ``README.txt`` for details.\n [optilude, davisagli]\n\n* Remove the distinction between wrapped and unwrapped subforms. A subform is\n always wrapped by the form that contains it, and can use a Zope 3 page\n template.\n [davisagli]\n\n* Fixed tests in Plone 3.\n [davisagli]\n\n* Fixed tests in Plone 4\n [optilude]\n\n* Made it possible to distinguish wrapped and unwrapped forms via the\n IWrappedForm marker interface.\n [optilude]\n\n* Made it possible to use z3c.form forms without a FormWrapper in Plone 4.\n [optilude]\n\n0.5.10 - 2010-02-01\n-------------------\n\n* A z3c.form.form.AddForm do a redirect in its render method.\n So we have to render the form to see if we have a redirection.\n In the case of redirection, we don't render the layout at all.\n This version remove the contents method on FormWrapper,\n it's now an attribute set during the FormWrapper.update.\n This change fixes status message not shown because it was consumed by\n the never shown rendered form.\n [vincentfretin]\n\n0.5.9 - 2010-01-08\n------------------\n\n* Fix security problem with the ++widget++ namespace\n [optilude]\n\n0.5.8 - 2009-11-24\n------------------\n\n* Don't do the rendering if there is a redirection, use the update/render\n pattern for that.\n See http://dev.plone.org/plone/ticket/10022 for an example how\n to adapt your code, in particular if you used FormWrapper with ViewletBase.\n [vincentfretin]\n\n0.5.7 - 2009-11-17\n------------------\n\n* Fix silly doctests so that they don't break in Python 2.6 / Zope 2.12\n [optilude]\n\n0.5.6 - 2009-09-25\n------------------\n\n* Added title_required msgid in macros.pt to be the same as plone.app.z3cform\n because macros.pt from plone.app.z3cform uses plone.z3cform translations.\n Added French translation and fixed German and Dutch translations\n for label_required and title_required messages.\n [vincentfretin]\n\n0.5.5 - 2009-07-26\n------------------\n\n* Removed explicit call from configure.zcml. This causes\n race condition type errors in ZCML loading when overrides are included\n later.\n [optilude]\n\n0.5.4 - 2009-04-17\n------------------\n\n* Added monkey patch to fix a bug in z3c.form's ChoiceTerms on z3c.form 1.9.0.\n [optilude]\n\n* Fix obvious bugs and dodgy naming in SingleCheckBoxWidget.\n [optilude]\n\n* Use chameleon-based page templates from five.pt if available.\n [davisagli]\n\n* Copied the basic textlines widget from z3c.form trunk for use until\n it is released.\n [davisagli]\n\n0.5.3 - 2008-12-09\n------------------\n\n* Add translation marker for batch, update translation files.\n [thefunny42]\n\n* Handle changed signature for widget extract method in z3c.form > 1.9.0\n [davisagli]\n\n* Added wildcard support to the 'before' and 'after' parameters of the\n fieldset 'move' utility function.\n [davisagli]\n\n* Fixes for Zope 2.12 compatibility.\n [davisagli]\n\n* Don't display an 'Apply changes' button if you don't define an\n update_schema.\n [thefunny42]\n\n* Declare xmlnamespace into 'layout.pt' and 'subform.pt' templates\n\n* Added support for an editsubform_factory for an EditForm so you can\n override the default behavior for a sub form now.\n\n* Changed css in crud-table.pt for a table to \"listing\" so that tables\n now look like plone tables.\n\n* Copy translation files to an english folder, so if your browser\n negociate to ``en,nl``, you will get english translations instead of\n dutch ones (like expected).\n [thefunny42]\n\n* Send an event IAfterWidgetUpdateEvent after updating display widgets\n manually in a CRUD form.\n [thefunny42]\n\n0.5.2 - 2008-08-28\n------------------\n\n* Add a namespace traversal adapter that allows traversal to widgets. This\n is useful for AJAX calls, for example.\n\n0.5.1 - 2008-08-21\n------------------\n\n* Add batching to ``plone.z3cform.crud`` CrudForm.\n\n* Look up the layout template as an IPageTemplate adapter. This means that\n it is possible for Plone to provide a \"Ploneish\" default template for forms\n that don't opt into this, without those forms having a direct Plone\n dependency.\n\n* Default to the titleless form template, since the layout template will\n provide a title anyway.\n\n* In ``plone.z3cform.layout``, allow labels to be defined per form\n instance, and not only per form class.\n\n0.5.0 - 2008-07-30\n------------------\n\n* No longer depend on <3.5 of zope.component.\n\n0.4 - 2008-07-25\n----------------\n\n* Depend on zope.component<3.5 to avoid ``TypeError(\"Missing\n 'provides' attribute\")`` error.\n\n* Allow ICrudForm.add to raise ValidationError, which allows for\n displaying a user-friendly error message.\n\n* Make the default layout template CMFDefault- compatible.\n\n0.3 - 2008-07-24\n----------------\n\n* Moved Plone layout wrapper to ``plone.app.z3cform.layout``. If you\n were using ``plone.z3cform.base.FormWrapper`` to get the Plone\n layout before, you'll have to use\n ``plone.app.z3cform.layout.FormWrapper`` instead now. (Also, make\n sure you include plone.app.z3cform's ZCML in this case.)\n\n* Move out Plone-specific subpackages to ``plone.app.z3cform``. These\n are:\n\n - wysywig: Kupu/Plone integration\n\n - queryselect: use z3c.formwidget.query with Archetypes\n\n Clean up testing code and development ``buildout.cfg`` to not pull\n in Plone anymore.\n [nouri]\n\n* Relicensed under the ZPL 2.1 and moved into the Zope repository.\n [nouri]\n\n* Add German translation.\n [saily]\n\n0.2 - 2008-06-20\n----------------\n\n* Fix usage of NumberDataConverter with zope.i18n >= 3.4 as the\n previous test setup was partial and did not register all adapters\n from z3c.form (some of them depends on zope >= 3.4)\n [gotcha, jfroche]\n\n* More tests\n [gotcha, jfroche]\n\n0.1 - 2008-05-21\n----------------\n\n* Provide and *register* default form and subform templates. These\n allow forms to be used with the style provided in this package\n without having to declare ``form = ViewPageTemplateFile('form.pt')``.\n\n This does not hinder you from overriding with your own ``form``\n attribute like usual. You can also still register a more\n specialized IPageTemplate for your form.\n\n* Add custom FileUploadDataConverter that converts a Zope 2 FileUpload\n object to a Zope 3 one before handing it to the original\n implementation. Also add support for different enctypes.\n [skatja, nouri]\n\n* Added Archetypes reference selection widget (queryselect)\n [malthe]\n\n* Moved generic Zope 2 compatibility code for z3c.form and a few\n goodies from Singing & Dancing into this new package.\n [nouri]\n\n\n\n", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/plone/plone.z3cform", "keywords": "Plone CMF Python Zope CMS Webapplication", "license": "GPL version 2", "maintainer": "", "maintainer_email": "", "name": "plone.z3cform", "package_url": "https://pypi.org/project/plone.z3cform/", "platform": "", "project_url": "https://pypi.org/project/plone.z3cform/", "project_urls": { "Homepage": "https://github.com/plone/plone.z3cform" }, "release_url": "https://pypi.org/project/plone.z3cform/1.1.1/", "requires_dist": [ "setuptools", "plone.batching", "six", "z3c.form", "zope.i18n (>=3.4)", "zope.browserpage", "zope.component", "Zope", "lxml ; extra == 'test'", "plone.testing[z2] ; extra == 'test'" ], "requires_python": "", "summary": "plone.z3cform is a library that allows use of z3c.form with Zope and the CMF.", "version": "1.1.1" }, "last_serial": 5964150, "releases": { "0.1": [ { "comment_text": "", "digests": { "md5": "7df16371757816a9eeb37100f670136e", "sha256": "f366c540a28750386c7bf5111cc694b3920e9b6b40fa2fdd30eb0ef0ad71fe91" }, "downloads": -1, "filename": "plone.z3cform-0.1.tar.gz", "has_sig": false, "md5_digest": "7df16371757816a9eeb37100f670136e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 30835, "upload_time": "2008-05-21T13:21:39", "url": "https://files.pythonhosted.org/packages/26/f5/b2cc885558a446af00b70d778ef52742d922f32647625c6ab6981ebb74e1/plone.z3cform-0.1.tar.gz" } ], "0.1b1": [ { "comment_text": "", "digests": { "md5": "e6a91b886f7d8653c2f0ebd565fbfdbb", "sha256": "2f9d96b61703df84d74d6af7cd02b985e9a960688b413e6bba8f0938e7dc8aa8" }, "downloads": -1, "filename": "plone.z3cform-0.1b1.tar.gz", "has_sig": false, "md5_digest": "e6a91b886f7d8653c2f0ebd565fbfdbb", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17151, "upload_time": "2008-04-21T15:59:08", "url": "https://files.pythonhosted.org/packages/f8/b1/2da948ccd7395ba0ee25e5b9a3d7d7e18fa1497205b6e3d721d9bc38c9b7/plone.z3cform-0.1b1.tar.gz" } ], "0.1b2": [ { "comment_text": "", "digests": { "md5": "4a66a90dc4b0df2d973ef9d5ca865fa0", "sha256": "13003775f3fcd7bdce6c5bdf3e441b12bac3737996c0d09a106644285ab379f5" }, "downloads": -1, "filename": "plone.z3cform-0.1b2.tar.gz", "has_sig": false, "md5_digest": "4a66a90dc4b0df2d973ef9d5ca865fa0", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17198, "upload_time": "2008-04-22T11:44:59", "url": "https://files.pythonhosted.org/packages/22/fb/6f062f4f8094469667e9f903b17d42bf407276c721f0900bfe6524e84a57/plone.z3cform-0.1b2.tar.gz" } ], "0.1b3": [ { "comment_text": "", "digests": { "md5": "ef83b57bacf56fb7bf9f94dd17365192", "sha256": "ecfd8048f4794b0d4a8e21d1465cf9bdcd3a96634b38b7445d7e895034d81fef" }, "downloads": -1, "filename": "plone.z3cform-0.1b3.tar.gz", "has_sig": false, "md5_digest": "ef83b57bacf56fb7bf9f94dd17365192", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 19603, "upload_time": "2008-05-08T19:04:49", "url": "https://files.pythonhosted.org/packages/ce/9e/3bf5bb26cbb2d925e44d4eaad85639fa8d7b3e33a5eb8fd0b7ae742355fa/plone.z3cform-0.1b3.tar.gz" } ], "0.1b4": [ { "comment_text": "", "digests": { "md5": "99dec3cbc026a628aed177f54f5c423c", "sha256": "021641c00a01ec5aa2c9e2488255058b5ecadf36fd39c9a61e1841f47a122548" }, "downloads": -1, "filename": "plone.z3cform-0.1b4.tar.gz", "has_sig": false, "md5_digest": "99dec3cbc026a628aed177f54f5c423c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 21998, "upload_time": "2008-05-16T14:42:30", "url": "https://files.pythonhosted.org/packages/bd/8f/dfb085f65363f52c357c543206e1628fce468735f6a48dbb3164d0f76ad6/plone.z3cform-0.1b4.tar.gz" } ], "0.1b5": [ { "comment_text": "", "digests": { "md5": "524927efa35a1f3eefe73dbca9cb221b", "sha256": "e6ff9ccffa530d2e18d544e2dd60886e2ec05cea2a702b2ea34656c88fb474b2" }, "downloads": -1, "filename": "plone.z3cform-0.1b5.tar.gz", "has_sig": false, "md5_digest": "524927efa35a1f3eefe73dbca9cb221b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 28890, "upload_time": "2008-05-17T12:30:49", "url": "https://files.pythonhosted.org/packages/79/be/8364973e83c45994882f2ec5bbc553fba562a83c3971f2b33fe075c5a035/plone.z3cform-0.1b5.tar.gz" } ], "0.2": [ { "comment_text": "", "digests": { "md5": "b52740a61d8b9013a31192d59283181d", "sha256": "6a77512b0b6d8957e4b5c1ad2263ab995b39c1b6579a022f997a3e7752fa4965" }, "downloads": -1, "filename": "plone.z3cform-0.2-py2.4.egg", "has_sig": false, "md5_digest": "b52740a61d8b9013a31192d59283181d", "packagetype": "bdist_egg", "python_version": "2.4", "requires_python": null, "size": 46186, "upload_time": "2008-06-20T16:28:38", "url": "https://files.pythonhosted.org/packages/e2/06/0069163bd1dc66481bf7164640f8d6b39b1bf0ac7ec1c86e82cabab8678d/plone.z3cform-0.2-py2.4.egg" }, { "comment_text": "", "digests": { "md5": "d87dd3887004a1090126bba5d539a6d0", "sha256": "d0f5d4bcc78bc04f329d732190a02fe9aa158af6c46450cdb7531670a91f312e" }, "downloads": -1, "filename": "plone.z3cform-0.2.tar.gz", "has_sig": false, "md5_digest": "d87dd3887004a1090126bba5d539a6d0", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 33629, "upload_time": "2008-06-20T16:29:51", "url": "https://files.pythonhosted.org/packages/56/0d/cd6fbad11ce212e22fc98b0d64c84bc04c8a23a5fa11a258cf9cf1f2481c/plone.z3cform-0.2.tar.gz" } ], "0.2b1": [ { "comment_text": "", "digests": { "md5": "c93fbde0a2abe243d700dd6763540d8a", "sha256": "6eddd3bc62a1326b1d9656daa45491604d091f5eba3383abe34292f606f6f412" }, "downloads": -1, "filename": "plone.z3cform-0.2b1.tar.gz", "has_sig": false, "md5_digest": "c93fbde0a2abe243d700dd6763540d8a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 30699, "upload_time": "2008-06-10T09:28:19", "url": "https://files.pythonhosted.org/packages/b0/8e/14f134b5e5f014d0b000d2a0c1874f5307d6bf547de9e9053ea677c13124/plone.z3cform-0.2b1.tar.gz" } ], "0.3": [ { "comment_text": "", "digests": { "md5": "045bfca68171df71e9656aab8584e68a", "sha256": "d00c12ae4e2af029e75a1d8fab517e742c0aa5b8465d327fd83dabc72e8c7797" }, "downloads": -1, "filename": "plone.z3cform-0.3.tar.gz", "has_sig": false, "md5_digest": "045bfca68171df71e9656aab8584e68a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 35618, "upload_time": "2008-07-24T10:12:35", "url": "https://files.pythonhosted.org/packages/44/a0/a54a2cc37fd793f9fb35a57dc58e50adf655e84c952124335c506d17a6cd/plone.z3cform-0.3.tar.gz" } ], "0.4": [ { "comment_text": "", "digests": { "md5": "c55c713d50f388f6d88ad5847a15d788", "sha256": "6fc4f485b82f37d372e2beaa1306600d42ed78ab9e0a84deed56188aa202e35f" }, "downloads": -1, "filename": "plone.z3cform-0.4.tar.gz", "has_sig": false, "md5_digest": "c55c713d50f388f6d88ad5847a15d788", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 37685, "upload_time": "2008-07-25T14:16:48", "url": "https://files.pythonhosted.org/packages/17/65/b69dd54d6a6ed641a94f69f82aa26f2d3358f6d563e5280d24afb34e3d9b/plone.z3cform-0.4.tar.gz" } ], "0.5.0": [ { "comment_text": "", "digests": { "md5": "cc8e89a9a540bd588ef927adf0a2ef3e", "sha256": "58751a8d64c26dcdf3ba1098f1e8b70aa7371e822592c1d6d10e2a31f8cbd85e" }, "downloads": -1, "filename": "plone.z3cform-0.5.0.tar.gz", "has_sig": false, "md5_digest": "cc8e89a9a540bd588ef927adf0a2ef3e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 36915, "upload_time": "2008-07-30T12:06:32", "url": "https://files.pythonhosted.org/packages/37/4c/fb6e0dbf583277608446d99e3048a2e4631857e6bda73bf664483c2e5acc/plone.z3cform-0.5.0.tar.gz" } ], "0.5.1": [ { "comment_text": "", "digests": { "md5": "8a2e51cdde5ea9fd571c47b6d448df5f", "sha256": "3b3618e3b7fb624f510becd6d6e9f06e7a206bb1c15cf9e6ccfe3f0b78f2c71f" }, "downloads": -1, "filename": "plone.z3cform-0.5.1.tar.gz", "has_sig": true, "md5_digest": "8a2e51cdde5ea9fd571c47b6d448df5f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 40200, "upload_time": "2008-08-21T16:01:18", "url": "https://files.pythonhosted.org/packages/a4/da/258895d3a261381bd997d84754e0cde197058ae9e0e34e3edb3c74e4eedf/plone.z3cform-0.5.1.tar.gz" } ], "0.5.10": [ { "comment_text": "", "digests": { "md5": "e445ac9eff14b99d0f612c63fc88a723", "sha256": "2bd8f5959e61c6c18de20afb37bc69da5697a04ad935d98b80a960b775b85a0b" }, "downloads": -1, "filename": "plone.z3cform-0.5.10.zip", "has_sig": false, "md5_digest": "e445ac9eff14b99d0f612c63fc88a723", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 70754, "upload_time": "2010-02-01T17:16:55", "url": "https://files.pythonhosted.org/packages/04/13/158c46887dcc4a38ef0ae6a8a38f5d964c9aa9914fcb8b7c28ffb9bc33a6/plone.z3cform-0.5.10.zip" } ], "0.5.11": [ { "comment_text": "", "digests": { "md5": "cf04dfd52dff857a54caba205665777a", "sha256": "12badf1e2b53131946eb51473996cffe1f1a90e1f1dcfb65f4e892aec510144d" }, "downloads": -1, "filename": "plone.z3cform-0.5.11.tar.gz", "has_sig": false, "md5_digest": "cf04dfd52dff857a54caba205665777a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 50933, "upload_time": "2010-07-02T16:45:38", "url": "https://files.pythonhosted.org/packages/7c/bf/acc5bde4c6082f595fb8313e20816c05ee8300c1ef9fd6714325742f6b00/plone.z3cform-0.5.11.tar.gz" } ], "0.5.12": [ { "comment_text": "", "digests": { "md5": "c80a3e941c4361fecbd2dc3262df5429", "sha256": "ac4780d5f2f4c9abe63d14265b97f2e05ee153ac266caf3f6818f8bdbb09008d" }, "downloads": -1, "filename": "plone.z3cform-0.5.12.zip", "has_sig": false, "md5_digest": "c80a3e941c4361fecbd2dc3262df5429", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 72406, "upload_time": "2011-06-08T17:42:33", "url": "https://files.pythonhosted.org/packages/36/aa/e3cb4b73112af7c31e5d823ef1061e7cf61ab0f4d80bac687d5abe89f0db/plone.z3cform-0.5.12.zip" } ], "0.5.2": [ { "comment_text": "", "digests": { "md5": "edc552b052093c9fb92464c41b61b655", "sha256": "6a7aaa3b24d78b26677abe49d8d5c6f8c82b8c3644b19bab325442afe77aa9f8" }, "downloads": -1, "filename": "plone.z3cform-0.5.2.tar.gz", "has_sig": false, "md5_digest": "edc552b052093c9fb92464c41b61b655", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 41578, "upload_time": "2008-08-28T20:24:34", "url": "https://files.pythonhosted.org/packages/31/65/18de8a8ce4474d9f3b52395931a40a3e2b3c21195dd401e1cb957800f2cd/plone.z3cform-0.5.2.tar.gz" } ], "0.5.3": [ { "comment_text": "", "digests": { "md5": "532fb6f1b212009b600e8991aa1f4e25", "sha256": "37cdb8cf22a42660da321e38d92acf698045492c6576a3926fbcf8f8e6f6722e" }, "downloads": -1, "filename": "plone.z3cform-0.5.3.tar.gz", "has_sig": false, "md5_digest": "532fb6f1b212009b600e8991aa1f4e25", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 43319, "upload_time": "2008-12-09T17:01:49", "url": "https://files.pythonhosted.org/packages/ad/0c/054eb39a332e703b3669872bff02cea39d9128dbef7f7bfd6f9fe09cf089/plone.z3cform-0.5.3.tar.gz" } ], "0.5.4": [ { "comment_text": "", "digests": { "md5": "442f7359b1fb6961b1402c1243ee7c19", "sha256": "443ce2291320eef504e5835b311cd7078bcecbe5a21fa44010091699c102544a" }, "downloads": -1, "filename": "plone.z3cform-0.5.4.tar.gz", "has_sig": false, "md5_digest": "442f7359b1fb6961b1402c1243ee7c19", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 48565, "upload_time": "2009-04-17T05:48:24", "url": "https://files.pythonhosted.org/packages/cd/c8/b08096f0942ab8c9cf49c3a2c81a29893f051cee97dea83f32bd619f8d5d/plone.z3cform-0.5.4.tar.gz" } ], "0.5.5": [ { "comment_text": "", "digests": { "md5": "0c6f0ddf7bd06f3ece6388dfd82fcc18", "sha256": "fe2836d96efc145b55f8f99e465788decd97fd042bfe5a25471c233c19657720" }, "downloads": -1, "filename": "plone.z3cform-0.5.5.tar.gz", "has_sig": false, "md5_digest": "0c6f0ddf7bd06f3ece6388dfd82fcc18", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 48720, "upload_time": "2009-07-26T07:37:26", "url": "https://files.pythonhosted.org/packages/22/61/0de3f08415eeeec84ceb88ec8d1f1a6dfa2af7c84d3fa3b404e73a2a356e/plone.z3cform-0.5.5.tar.gz" } ], "0.5.6": [ { "comment_text": "", "digests": { "md5": "bab3c3a2b7a67394fc77ff213a8523a2", "sha256": "acc72265bc07243866b724fbea0cd2dbe50330bf9932d5e82bc9a22f6a9fd8ca" }, "downloads": -1, "filename": "plone.z3cform-0.5.6.tar.gz", "has_sig": false, "md5_digest": "bab3c3a2b7a67394fc77ff213a8523a2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 48117, "upload_time": "2009-09-25T16:57:07", "url": "https://files.pythonhosted.org/packages/9e/27/12764f98ea1f6837ad15e4176e05b318a213493a823bc4691a4ff30dc0ad/plone.z3cform-0.5.6.tar.gz" } ], "0.5.7": [ { "comment_text": "", "digests": { "md5": "8a627c07a3042716b439cae4a034d955", "sha256": "28824c37a295fd281fd7605a6ab753c8a66a3bedb87edc9df73c0c5693ea0d97" }, "downloads": -1, "filename": "plone.z3cform-0.5.7.tar.gz", "has_sig": false, "md5_digest": "8a627c07a3042716b439cae4a034d955", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 48548, "upload_time": "2009-11-17T15:15:34", "url": "https://files.pythonhosted.org/packages/ed/36/8e583b3fbda3a3ab30ed7dddb2633b773135f0d1eb81ea6e5011183657ac/plone.z3cform-0.5.7.tar.gz" } ], "0.5.8": [ { "comment_text": "", "digests": { "md5": "5634440cc2480ceee476de17febb6f6b", "sha256": "767798e14b5eb125275772cf2ff488e583231f3b49fbdb035155d3e1272eed5a" }, "downloads": -1, "filename": "plone.z3cform-0.5.8.zip", "has_sig": false, "md5_digest": "5634440cc2480ceee476de17febb6f6b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 69318, "upload_time": "2009-11-24T14:28:44", "url": "https://files.pythonhosted.org/packages/3d/43/41735a87a3df6c88f7a5d8ed8b57044c2add128fef8477d8b84eac755f77/plone.z3cform-0.5.8.zip" } ], "0.5.9": [ { "comment_text": "", "digests": { "md5": "f379f2da9ab76e34447bf3bb3234d0eb", "sha256": "4edc7933bc8090c551b65da3a1d2916deff6071ef65d1c953da60a7e9f11d560" }, "downloads": -1, "filename": "plone.z3cform-0.5.9.tar.gz", "has_sig": false, "md5_digest": "f379f2da9ab76e34447bf3bb3234d0eb", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 49451, "upload_time": "2010-01-08T04:24:15", "url": "https://files.pythonhosted.org/packages/74/e4/9b94e788331614caad45f2c1793bcb04b848433d1f9f26edded019d558f2/plone.z3cform-0.5.9.tar.gz" } ], "0.6.0": [ { "comment_text": "", "digests": { "md5": "36fae1e0b96babc2caaedc4f7deeb1fa", "sha256": "63049dfd559e3d8a202e617c78a540ec304aea9d0840beb073d85812dd95601b" }, "downloads": -1, "filename": "plone.z3cform-0.6.0.zip", "has_sig": true, "md5_digest": "36fae1e0b96babc2caaedc4f7deeb1fa", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 92173, "upload_time": "2010-04-20T09:31:32", "url": "https://files.pythonhosted.org/packages/2b/56/efb5a2634ca8d0aaa484e931112765ddde521f92eb2b70d39807aa8dae1d/plone.z3cform-0.6.0.zip" } ], "0.7.0": [ { "comment_text": "", "digests": { "md5": "24d971c30a37e9e8a7205d04fac8a31b", "sha256": "2531ab7af3f8208e0ba5252c48dc85e33b3c1ce529146c0f15cdf05730677835" }, "downloads": -1, "filename": "plone.z3cform-0.7.0.zip", "has_sig": true, "md5_digest": "24d971c30a37e9e8a7205d04fac8a31b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 94494, "upload_time": "2010-08-05T07:12:35", "url": "https://files.pythonhosted.org/packages/fd/61/3988d1069ce419e5eceffbc6459dc23138580344c88f86e788f938eafc2a/plone.z3cform-0.7.0.zip" } ], "0.7.1": [ { "comment_text": "", "digests": { "md5": "7a72cdf36cc0b951f6780120998a55db", "sha256": "45741169d7c7c21b2b80f605938f7144be37637f2d0da0fa00270f31252f2aff" }, "downloads": -1, "filename": "plone.z3cform-0.7.1.zip", "has_sig": false, "md5_digest": "7a72cdf36cc0b951f6780120998a55db", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 94690, "upload_time": "2011-01-18T19:20:40", "url": "https://files.pythonhosted.org/packages/0a/51/ca6d7280f0654c47f3f13f67da60dccfea44e66a7d3bc5f62bd79434ac01/plone.z3cform-0.7.1.zip" } ], "0.7.2": [ { "comment_text": "", "digests": { "md5": "5d62c4852949a7f9425faabd00831ffb", "sha256": "f6593f595ada48d136f1969f9f4d932de13ea455135ba24a80143aadf3a5dc13" }, "downloads": -1, "filename": "plone.z3cform-0.7.2.zip", "has_sig": true, "md5_digest": "5d62c4852949a7f9425faabd00831ffb", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 95071, "upload_time": "2011-02-17T19:41:06", "url": "https://files.pythonhosted.org/packages/6e/7a/440e3ba91bc88ef6face46ed4172f39e13f65434b0e6d4acc2122b0bf6b6/plone.z3cform-0.7.2.zip" } ], "0.7.3": [ { "comment_text": "", "digests": { "md5": "7fa35dc735fa07f5ceb56a3c3031fa72", "sha256": "213371cc0981a4737b95e3b49b4639c7dbc62b068ced4e513880d1c5cedbdb8d" }, "downloads": -1, "filename": "plone.z3cform-0.7.3.zip", "has_sig": false, "md5_digest": "7fa35dc735fa07f5ceb56a3c3031fa72", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 94969, "upload_time": "2011-03-02T18:35:11", "url": "https://files.pythonhosted.org/packages/2f/b4/15851643432f67f290f4f023a9a0d7c82c1bf03d98a021caaa88b1ad6cee/plone.z3cform-0.7.3.zip" } ], "0.7.4": [ { "comment_text": "", "digests": { "md5": "94c7b09dd41c9a8b31cb7e3a0a2f9934", "sha256": "3308de4131e16fb718639736799cc7195e9ab8ade5ca82fa7cb89353bdfcd738" }, "downloads": -1, "filename": "plone.z3cform-0.7.4.zip", "has_sig": false, "md5_digest": "94c7b09dd41c9a8b31cb7e3a0a2f9934", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 98407, "upload_time": "2011-05-03T20:46:57", "url": "https://files.pythonhosted.org/packages/d4/ce/3812b37f8c58a1d349e90c1e571776a858f8b30b322f2da53e3aee0e8483/plone.z3cform-0.7.4.zip" } ], "0.7.5": [ { "comment_text": "", "digests": { "md5": "260fcc0ca0c38aaabad1888a83701790", "sha256": "ee7672681d3a9477453055914f2011cd41d9c6bf9a18e73c45128861aa26b7e6" }, "downloads": -1, "filename": "plone.z3cform-0.7.5.zip", "has_sig": false, "md5_digest": "260fcc0ca0c38aaabad1888a83701790", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 98886, "upload_time": "2011-05-03T22:29:53", "url": "https://files.pythonhosted.org/packages/4f/00/c915c663d08595209625506788e482224106267bf8750cd47d93a853adae/plone.z3cform-0.7.5.zip" } ], "0.7.6": [ { "comment_text": "", "digests": { "md5": "e6df3743950b683ff7cbaa98081175a1", "sha256": "f8e7dc8eb4e19669d99ef2396c39147e0016278f50f3d8cc486d32759bf3266b" }, "downloads": -1, "filename": "plone.z3cform-0.7.6.zip", "has_sig": false, "md5_digest": "e6df3743950b683ff7cbaa98081175a1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 99397, "upload_time": "2011-05-17T18:55:15", "url": "https://files.pythonhosted.org/packages/fd/75/7de1e30bdbbcfac23367f41736fdb8af4423af3b9bda461c9b5d5affa339/plone.z3cform-0.7.6.zip" } ], "0.7.7": [ { "comment_text": "", "digests": { "md5": "c5ca153fa22da4e330415cf912587d8d", "sha256": "1eacc37926d1a5003a66bcfd4477bae77d71807c2ed7bfe0dbc2e96d6b72520f" }, "downloads": -1, "filename": "plone.z3cform-0.7.7.zip", "has_sig": false, "md5_digest": "c5ca153fa22da4e330415cf912587d8d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 99786, "upload_time": "2011-07-01T02:21:04", "url": "https://files.pythonhosted.org/packages/8d/95/8a648f2247fe0bf0d4e799ace1eaa89fb22575f78bdcffb6f581a513e73d/plone.z3cform-0.7.7.zip" } ], "0.7.8": [ { "comment_text": "", "digests": { "md5": "da891365156a5d5824d4e504465886a2", "sha256": "f227374bfc48eb0daa702d9ddaed4cafb3fde4f959ed542c25d5542180862ef3" }, "downloads": -1, "filename": "plone.z3cform-0.7.8.zip", "has_sig": false, "md5_digest": "da891365156a5d5824d4e504465886a2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 101166, "upload_time": "2011-09-24T21:39:56", "url": "https://files.pythonhosted.org/packages/72/a2/04f4d6cb91934889b4fd6c0f34ad411dd8aabb02f03981951cc3ad320005/plone.z3cform-0.7.8.zip" } ], "0.8.0": [ { "comment_text": "", "digests": { "md5": "bdb23dd162544964d2f8f8f5f002e874", "sha256": "3cfd3cade347684e1a2d3a082a54238d1d89f2e5a5fbef7a5041afe0f22ed094" }, "downloads": -1, "filename": "plone.z3cform-0.8.0.zip", "has_sig": false, "md5_digest": "bdb23dd162544964d2f8f8f5f002e874", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 97110, "upload_time": "2012-08-30T14:51:19", "url": "https://files.pythonhosted.org/packages/e2/23/4d255535c94d0bf78af2b1f4c15aa6ae41db674993bd194a67b468e1d920/plone.z3cform-0.8.0.zip" } ], "0.8.1": [ { "comment_text": "", "digests": { "md5": "42d831b38278cf346e8d7513137a4c62", "sha256": "6a133b13f82668cf866ad87b69f180812bb1b278e706d14111cbb399d5df3487" }, "downloads": -1, "filename": "plone.z3cform-0.8.1.zip", "has_sig": false, "md5_digest": "42d831b38278cf346e8d7513137a4c62", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 107458, "upload_time": "2015-01-22T16:33:28", "url": "https://files.pythonhosted.org/packages/ab/c7/e7c14e16c945c5bb320bd4125a9d49defff37cbee2340aaf3cc962b0fbaa/plone.z3cform-0.8.1.zip" } ], "0.9.0": [ { "comment_text": "", "digests": { "md5": "1fcae39a63e001b9a9b11d29583f8682", "sha256": "cf4112036df3b1154cd9e298c567ef1d3e98ec48ef47612b2cb16601f6c025a6" }, "downloads": -1, "filename": "plone.z3cform-0.9.0.tar.gz", "has_sig": false, "md5_digest": "1fcae39a63e001b9a9b11d29583f8682", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 74113, "upload_time": "2016-05-25T12:04:41", "url": "https://files.pythonhosted.org/packages/3d/28/ae4b927c02f804f04aab44020bce825ca72f5ee080e6e1d7311c9691e28c/plone.z3cform-0.9.0.tar.gz" } ], "0.9.1": [ { "comment_text": "", "digests": { "md5": "ee5287b0d6a82fd25a3de637db6ae9fe", "sha256": "b1f315edf0edb7ce684ea204389d06669dafaff98d2fd870d9bd0c6063b0d8cb" }, "downloads": -1, "filename": "plone.z3cform-0.9.1.tar.gz", "has_sig": false, "md5_digest": "ee5287b0d6a82fd25a3de637db6ae9fe", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 76191, "upload_time": "2017-09-03T20:15:49", "url": "https://files.pythonhosted.org/packages/2e/03/d539ac1d981b814ec39097ce40b446d0a9e9d78f1e3c2164429b0e2c962f/plone.z3cform-0.9.1.tar.gz" } ], "0.9.2": [ { "comment_text": "", "digests": { "md5": "17095b3627e12c8f995a979dcf4cd991", "sha256": "3c1d7f37d5005f4581d41dda736d176de345b969fcd8de143891bb47b72d5cdb" }, "downloads": -1, "filename": "plone.z3cform-0.9.2-py2-none-any.whl", "has_sig": false, "md5_digest": "17095b3627e12c8f995a979dcf4cd991", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 81782, "upload_time": "2019-09-15T20:28:34", "url": "https://files.pythonhosted.org/packages/eb/de/391703436aaa996a052a7238419c6d4d004742b39a2ee7b40e08e6de81d1/plone.z3cform-0.9.2-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "eeb2ca2d04af0f82721596c1e4017fa7", "sha256": "77bc382a9ec350e4cc7eaf9539bb38103622d1f43bb7a460b36501a12f2754eb" }, "downloads": -1, "filename": "plone.z3cform-0.9.2.tar.gz", "has_sig": false, "md5_digest": "eeb2ca2d04af0f82721596c1e4017fa7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 74636, "upload_time": "2019-09-15T20:28:37", "url": "https://files.pythonhosted.org/packages/3f/ae/c942fac0ac24b24c291ddd4a8dcdafb5b2857d8acf0c6c690cd10031a82d/plone.z3cform-0.9.2.tar.gz" } ], "1.0.0": [ { "comment_text": "", "digests": { "md5": "4ae3f4b94e11c05a5a562493d901bc0b", "sha256": "2a66ea833dd77aaffea933f0eca6bf23c9b2aef0c887150b47f59c520b582c36" }, "downloads": -1, "filename": "plone.z3cform-1.0.0.tar.gz", "has_sig": false, "md5_digest": "4ae3f4b94e11c05a5a562493d901bc0b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 73527, "upload_time": "2018-11-04T12:24:50", "url": "https://files.pythonhosted.org/packages/ee/41/4ba60b4915f0d29c480b63545730116d5899962ba02b49863957ba49a576/plone.z3cform-1.0.0.tar.gz" } ], "1.1.0": [ { "comment_text": "", "digests": { "md5": "c4615f509fc02a824006c6ba71623c6b", "sha256": "7352d7d8c1a66de10fafdfeb3ff2cce959574127edaf8616fea4a47040833577" }, "downloads": -1, "filename": "plone.z3cform-1.1.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "c4615f509fc02a824006c6ba71623c6b", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 86957, "upload_time": "2019-04-09T14:38:23", "url": "https://files.pythonhosted.org/packages/c4/b3/da4fa4920c4453745e345b87412a2ab3f2233f026957c30ead1223a708af/plone.z3cform-1.1.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "5170de50bc76f79b137f67a5fb62c282", "sha256": "0778ec5fe53a3542100c423d5099919f62b64cc22b4ab186409e2b4e79c81be3" }, "downloads": -1, "filename": "plone.z3cform-1.1.0.tar.gz", "has_sig": false, "md5_digest": "5170de50bc76f79b137f67a5fb62c282", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 82517, "upload_time": "2019-04-09T14:38:26", "url": "https://files.pythonhosted.org/packages/38/77/3ecec2d641b1d87f27b50f26ad6e495517a95200c41a262c96ad89f98b76/plone.z3cform-1.1.0.tar.gz" } ], "1.1.1": [ { "comment_text": "", "digests": { "md5": "3388df6e04932a473f687010ea37d00d", "sha256": "16d429471852afce4ee2ca0835dafe65c0cfbfced0da2dcef6a3f308993dfcd2" }, "downloads": -1, "filename": "plone.z3cform-1.1.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "3388df6e04932a473f687010ea37d00d", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 87594, "upload_time": "2019-10-12T12:41:37", "url": "https://files.pythonhosted.org/packages/ed/99/bb61b6caccd8ebba39e317c4324291cadf4baf53c748eb04a4b1a0842257/plone.z3cform-1.1.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "4208add8578537feb25c44bc84a89c44", "sha256": "8cdad698cdcf7711c29cc12154b4634808d29e3df1dee46b663206d41fff6e4f" }, "downloads": -1, "filename": "plone.z3cform-1.1.1.tar.gz", "has_sig": false, "md5_digest": "4208add8578537feb25c44bc84a89c44", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 80732, "upload_time": "2019-10-12T12:41:41", "url": "https://files.pythonhosted.org/packages/13/74/a9b23034f1c014b8e23d2a65788a2b9453cab985e46b6a15db31dda5daf2/plone.z3cform-1.1.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "3388df6e04932a473f687010ea37d00d", "sha256": "16d429471852afce4ee2ca0835dafe65c0cfbfced0da2dcef6a3f308993dfcd2" }, "downloads": -1, "filename": "plone.z3cform-1.1.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "3388df6e04932a473f687010ea37d00d", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 87594, "upload_time": "2019-10-12T12:41:37", "url": "https://files.pythonhosted.org/packages/ed/99/bb61b6caccd8ebba39e317c4324291cadf4baf53c748eb04a4b1a0842257/plone.z3cform-1.1.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "4208add8578537feb25c44bc84a89c44", "sha256": "8cdad698cdcf7711c29cc12154b4634808d29e3df1dee46b663206d41fff6e4f" }, "downloads": -1, "filename": "plone.z3cform-1.1.1.tar.gz", "has_sig": false, "md5_digest": "4208add8578537feb25c44bc84a89c44", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 80732, "upload_time": "2019-10-12T12:41:41", "url": "https://files.pythonhosted.org/packages/13/74/a9b23034f1c014b8e23d2a65788a2b9453cab985e46b6a15db31dda5daf2/plone.z3cform-1.1.1.tar.gz" } ] }