[Checkins] SVN: grok/branches/sylvain-grokcore-formlib/ Remove formlib form support and use grokcore.formlib instead.
Sylvain Viollon
sylvain at infrae.com
Fri Sep 26 05:15:40 EDT 2008
Log message for revision 91501:
Remove formlib form support and use grokcore.formlib instead.
Changed:
U grok/branches/sylvain-grokcore-formlib/setup.py
U grok/branches/sylvain-grokcore-formlib/src/grok/__init__.py
U grok/branches/sylvain-grokcore-formlib/src/grok/components.py
D grok/branches/sylvain-grokcore-formlib/src/grok/formlib.py
U grok/branches/sylvain-grokcore-formlib/src/grok/interfaces.py
U grok/branches/sylvain-grokcore-formlib/src/grok/meta.py
U grok/branches/sylvain-grokcore-formlib/src/grok/meta.zcml
D grok/branches/sylvain-grokcore-formlib/src/grok/templates/
U grok/branches/sylvain-grokcore-formlib/src/grok/testing.py
U grok/branches/sylvain-grokcore-formlib/versions.cfg
-=-
Modified: grok/branches/sylvain-grokcore-formlib/setup.py
===================================================================
--- grok/branches/sylvain-grokcore-formlib/setup.py 2008-09-26 08:57:40 UTC (rev 91500)
+++ grok/branches/sylvain-grokcore-formlib/setup.py 2008-09-26 09:15:39 UTC (rev 91501)
@@ -37,6 +37,7 @@
install_requires=['setuptools',
'martian >= 0.10',
'grokcore.component >= 1.5',
+ 'grokcore.formlib',
'grokcore.security',
'grokcore.view',
'simplejson',
Modified: grok/branches/sylvain-grokcore-formlib/src/grok/__init__.py
===================================================================
--- grok/branches/sylvain-grokcore-formlib/src/grok/__init__.py 2008-09-26 08:57:40 UTC (rev 91500)
+++ grok/branches/sylvain-grokcore-formlib/src/grok/__init__.py 2008-09-26 09:15:39 UTC (rev 91501)
@@ -37,6 +37,14 @@
from grokcore.view import skin
from grokcore.view import url
+from grokcore.formlib import action
+from grokcore.formlib import AutoFields
+from grokcore.formlib import Fields
+from grokcore.formlib import Form
+from grokcore.formlib import AddForm
+from grokcore.formlib import EditForm
+from grokcore.formlib import DisplayForm
+
from zope.event import notify
from zope.app.component.hooks import getSite
from zope.lifecycleevent import (
@@ -58,7 +66,7 @@
from grok.components import Traverser
from grok.components import Container, OrderedContainer
from grok.components import Site, LocalUtility, Annotation
-from grok.components import Application, Form, AddForm, EditForm, DisplayForm
+from grok.components import Application
from grok.components import Indexes
from grok.components import Role
from grok.components import RESTProtocol, IRESTLayer
@@ -68,7 +76,6 @@
from grok.directive import (local_utility, permissions, site,
viewletmanager, view, traversable, order)
-from grok.formlib import action, AutoFields, Fields
# BBB These two functions are meant for test fixtures and should be
Modified: grok/branches/sylvain-grokcore-formlib/src/grok/components.py
===================================================================
--- grok/branches/sylvain-grokcore-formlib/src/grok/components.py 2008-09-26 08:57:40 UTC (rev 91500)
+++ grok/branches/sylvain-grokcore-formlib/src/grok/components.py 2008-09-26 09:15:39 UTC (rev 91501)
@@ -13,17 +13,12 @@
##############################################################################
"""Grok components"""
-import os
import persistent
-import datetime
-import warnings
-import pytz
import simplejson
import zope.location
from zope import component
from zope import interface
-from zope.interface.common import idatetime
from zope.securitypolicy.role import Role
from zope.publisher.browser import BrowserPage
from zope.publisher.interfaces import NotFound
@@ -31,7 +26,6 @@
from zope.publisher.interfaces.browser import IBrowserPublisher
from zope.publisher.interfaces.http import IHTTPRequest
from zope.publisher.publish import mapply
-from zope.formlib import form
from zope.annotation.interfaces import IAttributeAnnotatable
from zope.app.publisher.browser import getDefaultViewName
@@ -52,7 +46,7 @@
import martian.util
import grokcore.view
-from grok import interfaces, formlib, util
+from grok import interfaces, util
class Model(Contained, persistent.Persistent):
@@ -261,137 +255,6 @@
return self.context.get(name)
-default_form_template = grokcore.view.PageTemplateFile(os.path.join(
- 'templates', 'default_edit_form.pt'))
-default_form_template.__grok_name__ = 'default_edit_form'
-default_display_template = grokcore.view.PageTemplateFile(os.path.join(
- 'templates', 'default_display_form.pt'))
-default_display_template.__grok_name__ = 'default_display_form'
-
-
-class GrokForm(object):
- """Mix-in to consolidate zope.formlib's forms with grok.View and to
- add some more useful methods.
-
- The consolidation needs to happen because zope.formlib's Forms have
- update/render methods which have different meanings than
- grok.View's update/render methods. We deal with this issue by
- 'renaming' zope.formlib's update() to update_form() and by
- disallowing subclasses to have custom render() methods."""
-
- def update(self):
- """Subclasses can override this method just like on regular
- grok.Views. It will be called before any form processing
- happens."""
-
- def update_form(self):
- """Update the form, i.e. process form input using widgets.
-
- On zope.formlib forms, this is what the update() method is.
- In grok views, the update() method has a different meaning.
- That's why this method is called update_form() in grok forms."""
- super(GrokForm, self).update()
-
- def render(self):
- """Render the form, either using the form template or whatever
- the actions returned in form_result."""
- # if the form has been updated, it will already have a result
- if self.form_result is None:
- if self.form_reset:
- # we reset, in case data has changed in a way that
- # causes the widgets to have different data
- self.resetForm()
- self.form_reset = False
- self.form_result = self._render_template()
-
- return self.form_result
-
- # Mark the render() method as a method from the base class. That
- # way we can detect whether somebody overrides render() in a
- # subclass (which we don't allow).
- render.base_method = True
-
- def __call__(self):
- mapply(self.update, (), self.request)
- if self.request.response.getStatus() in (302, 303):
- # A redirect was triggered somewhere in update(). Don't
- # continue rendering the template or doing anything else.
- return
-
- self.update_form()
- return self.render()
-
-
-class Form(GrokForm, form.FormBase, View):
- # We're only reusing the form implementation from zope.formlib, we
- # explicitly don't want to inherit the interface semantics (mostly
- # for the different meanings of update/render).
- interface.implementsOnly(interfaces.IGrokForm)
-
- template = default_form_template
-
- def applyData(self, obj, **data):
- return formlib.apply_data_event(obj, self.form_fields, data,
- self.adapters)
-
- # BBB -- to be removed in June 2007
- def applyChanges(self, obj, **data):
- warnings.warn("The 'applyChanges' method on forms is deprecated "
- "and will disappear by June 2007. Please use "
- "'applyData' instead.", DeprecationWarning, 2)
- return bool(self.applyData(obj, **data))
-
-
-class AddForm(Form):
- pass
-
-
-class EditForm(GrokForm, form.EditFormBase, View):
- # We're only reusing the form implementation from zope.formlib, we
- # explicitly don't want to inherit the interface semantics (mostly
- # for the different meanings of update/render).
- interface.implementsOnly(interfaces.IGrokForm)
-
- template = default_form_template
-
- def applyData(self, obj, **data):
- return formlib.apply_data_event(obj, self.form_fields, data,
- self.adapters, update=True)
-
- # BBB -- to be removed in June 2007
- def applyChanges(self, obj, **data):
- warnings.warn("The 'applyChanges' method on forms is deprecated "
- "and will disappear by June 2007. Please use "
- "'applyData' instead.", DeprecationWarning, 2)
- return bool(self.applyData(obj, **data))
-
- @formlib.action("Apply")
- def handle_edit_action(self, **data):
- if self.applyData(self.context, **data):
- formatter = self.request.locale.dates.getFormatter(
- 'dateTime', 'medium')
-
- try:
- time_zone = idatetime.ITZInfo(self.request)
- except TypeError:
- time_zone = pytz.UTC
-
- self.status = "Updated on %s" % formatter.format(
- datetime.datetime.now(time_zone)
- )
- else:
- self.status = 'No changes'
-
-
-class DisplayForm(GrokForm, form.DisplayFormBase, View):
- # We're only reusing the form implementation from zope.formlib, we
- # explicitly don't want to inherit the interface semantics (mostly
- # for the different meanings of update/render).
- interface.implementsOnly(interfaces.IGrokForm)
-
- template = default_display_template
-
-
class IndexesClass(object):
def __init__(self, name, bases=(), attrs=None):
if attrs is None:
Deleted: grok/branches/sylvain-grokcore-formlib/src/grok/formlib.py
===================================================================
--- grok/branches/sylvain-grokcore-formlib/src/grok/formlib.py 2008-09-26 08:57:40 UTC (rev 91500)
+++ grok/branches/sylvain-grokcore-formlib/src/grok/formlib.py 2008-09-26 09:15:39 UTC (rev 91501)
@@ -1,124 +0,0 @@
-import types
-from zope import interface, event, lifecycleevent
-from zope.interface.interfaces import IInterface
-from zope.formlib import form
-from zope.schema.interfaces import IField
-
-class action(form.action):
- """We override the action decorator we pass in our custom Action.
- """
- def __call__(self, success):
- action = Action(self.label, success=success, **self.options)
- self.actions.append(action)
- return action
-
-class Action(form.Action):
- def success(self, data):
- if self.success_handler is not None:
- return self.success_handler(self.form, **data)
-
-def Fields(*args, **kw):
- fields = []
- for key, value in kw.items():
- if IField.providedBy(value):
- value.__name__ = key
- fields.append(value)
- del kw[key]
- fields.sort(key=lambda field: field.order)
- return form.Fields(*(args + tuple(fields)), **kw)
-
-def get_auto_fields(context):
- """Get the form fields for context.
- """
- # for an interface context, we generate them from that interface
- if IInterface.providedBy(context):
- return form.Fields(context)
- # if we have a non-interface context, we're autogenerating them
- # from any schemas defined by the context
- fields = form.Fields(*most_specialized_interfaces(context))
- # we pull in this field by default, but we don't want it in our form
- fields = fields.omit('__name__')
- return fields
-
-AutoFields = get_auto_fields
-
-def most_specialized_interfaces(context):
- """Get interfaces for an object without any duplicates.
-
- Interfaces in a declaration for an object may already have been seen
- because it is also inherited by another interface. Don't return the
- interface twice, as that would result in duplicate names when creating
- the form.
- """
- declaration = interface.implementedBy(context)
- seen = []
- for iface in declaration.flattened():
- if interface_seen(seen, iface):
- continue
- seen.append(iface)
- return seen
-
-def interface_seen(seen, iface):
- """Return True if interface already is seen.
- """
- for seen_iface in seen:
- if seen_iface.extends(iface):
- return True
- return False
-
-def apply_data(context, form_fields, data, adapters=None, update=False):
- """Save form data (``data`` dict) on a ``context`` object.
-
- This is a beefed up version of zope.formlib.form.applyChanges().
- It allows you to specify whether values should be compared with
- the attributes on already existing objects or not, using the
- ``update`` parameter.
-
- Unlike zope.formlib.form.applyChanges(), it will return a
- dictionary of interfaces and their fields that were changed. This
- is necessary to appropriately send IObjectModifiedEvents.
- """
- if adapters is None:
- adapters = {}
-
- changes = {}
-
- for form_field in form_fields:
- field = form_field.field
- # Adapt context, if necessary
- interface = form_field.interface
- adapter = adapters.get(interface)
- if adapter is None:
- if interface is None:
- adapter = context
- else:
- adapter = interface(context)
- adapters[interface] = adapter
-
- name = form_field.__name__
- newvalue = data.get(name, form_field) # using form_field as marker
-
- if update:
- if ((newvalue is not form_field) and
- (field.get(adapter) != newvalue)):
- field.set(adapter, newvalue)
- changes.setdefault(interface, []).append(name)
- else:
- if newvalue is not form_field:
- field.set(adapter, newvalue)
- changes.setdefault(interface, []).append(name)
-
- return changes
-
-def apply_data_event(context, form_fields, data, adapters=None, update=False):
- """Like apply_data, but also sends an IObjectModifiedEvent.
- """
- changes = apply_data(context, form_fields, data, adapters, update)
-
- if changes:
- descriptions = []
- for interface, names in changes.items():
- descriptions.append(lifecycleevent.Attributes(interface, *names))
- event.notify(lifecycleevent.ObjectModifiedEvent(context, *descriptions))
-
- return changes
Modified: grok/branches/sylvain-grokcore-formlib/src/grok/interfaces.py
===================================================================
--- grok/branches/sylvain-grokcore-formlib/src/grok/interfaces.py 2008-09-26 08:57:40 UTC (rev 91500)
+++ grok/branches/sylvain-grokcore-formlib/src/grok/interfaces.py 2008-09-26 09:15:39 UTC (rev 91501)
@@ -20,6 +20,7 @@
from zope.app.container.interfaces import IContainer as IContainerBase
import grokcore.component.interfaces
+import grokcore.formlib.interfaces
import grokcore.security.interfaces
import grokcore.view.interfaces
@@ -45,10 +46,6 @@
JSON = interface.Attribute("Base class for JSON methods.")
REST = interface.Attribute("Base class for REST views.")
Traverser = interface.Attribute("Base class for custom traversers.")
- Form = interface.Attribute("Base class for forms.")
- AddForm = interface.Attribute("Base class for add forms.")
- EditForm = interface.Attribute("Base class for edit forms.")
- DisplayForm = interface.Attribute("Base class for display forms.")
Indexes = interface.Attribute("Base class for catalog index definitions.")
ViewletManager = interface.Attribute("Base class for viewletmanager.")
Viewlet = interface.Attribute("Base class for viewlet.")
@@ -104,14 +101,6 @@
"""
-class IGrokDecorators(grokcore.component.interfaces.IDecorators):
-
- def action(label, **options):
- """Decorator that defines an action factory based on a form
- method. The method receives the form data as keyword
- parameters."""
-
-
class IGrokEvents(interface.Interface):
IObjectCreatedEvent = interface.Attribute("")
@@ -145,7 +134,8 @@
class IGrokAPI(grokcore.security.interfaces.IGrokcoreSecurityAPI,
grokcore.view.interfaces.IGrokcoreViewAPI,
- IGrokBaseClasses, IGrokDirectives, IGrokDecorators,
+ grokcore.formlib.interfaces.IGrokcoreFormlibAPI,
+ IGrokBaseClasses, IGrokDirectives,
IGrokEvents, IGrokErrors):
# BBB this is deprecated
@@ -183,18 +173,7 @@
def getSite():
"""Get the current site."""
- def Fields(*args, **kw):
- """Return a list of formlib fields based on interfaces and/or schema
- fields."""
- def AutoFields(context):
- """Return a list of fields for context autogenerated by grok.
- """
-
- def action(label, actions=None, **options):
- """grok-specific action decorator.
- """
-
IRESTSkinType = interface.Attribute('The REST skin type')
@@ -211,105 +190,6 @@
"""Send a short message to the user."""
-class IGrokForm(IGrokView):
- """Grok form API, inspired by zope.formlib's IFormBaseCustomization.
-
- We explicitly don't inherit from IFormBaseCustomization because
- that would imply ISubPage with another definition of update() and
- render() than IGrokView has.
- """
-
- prefix = schema.ASCII(
- constraint=reConstraint(
- '[a-zA-Z][a-zA-Z0-9_]*([.][a-zA-Z][a-zA-Z0-9_]*)*',
- "Must be a sequence of not-separated identifiers"),
- description=u"""Page-element prefix
-
- All named or identified page elements in a subpage should have
- names and identifiers that begin with a subpage prefix
- followed by a dot.
- """,
- readonly=True,
- )
-
- def setPrefix(prefix):
- """Update the subpage prefix
- """
-
- label = interface.Attribute("A label to display at the top of a form")
-
- status = interface.Attribute(
- """An update status message
-
- This is normally generated by success or failure handlers.
- """)
-
- errors = interface.Attribute(
- """Sequence of errors encountered during validation
- """)
-
- form_result = interface.Attribute(
- """Return from action result method
- """)
-
- form_reset = interface.Attribute(
- """Boolean indicating whether the form needs to be reset
- """)
-
- form_fields = interface.Attribute(
- """The form's form field definitions
-
- This attribute is used by many of the default methods.
- """)
-
- widgets = interface.Attribute(
- """The form's widgets
-
- - set by setUpWidgets
-
- - used by validate
- """)
-
- def setUpWidgets(ignore_request=False):
- """Set up the form's widgets.
-
- The default implementation uses the form definitions in the
- form_fields attribute and setUpInputWidgets.
-
- The function should set the widgets attribute.
- """
-
- def validate(action, data):
- """The default form validator
-
- If an action is submitted and the action doesn't have it's own
- validator then this function will be called.
- """
-
- template = interface.Attribute(
- """Template used to display the form
- """)
-
- def resetForm():
- """Reset any cached data because underlying content may have changed
- """
-
- def error_views():
- """Return views of any errors.
-
- The errors are returned as an iterable.
- """
-
- def applyData(obj, **data):
- """Save form data to an object.
-
- This returns a dictionary with interfaces as keys and lists of
- field names as values to indicate which fields in which
- schemas had to be changed in order to save the data. In case
- the method works in update mode (e.g. on EditForms) and
- doesn't have to update an object, the dictionary is empty.
- """
-
class IREST(interface.Interface):
context = interface.Attribute("Object that the REST handler presents.")
Modified: grok/branches/sylvain-grokcore-formlib/src/grok/meta.py
===================================================================
--- grok/branches/sylvain-grokcore-formlib/src/grok/meta.py 2008-09-26 08:57:40 UTC (rev 91500)
+++ grok/branches/sylvain-grokcore-formlib/src/grok/meta.py 2008-09-26 09:15:39 UTC (rev 91501)
@@ -44,7 +44,7 @@
from martian import util
import grok
-from grok import components, formlib
+from grok import components
from grok.util import make_checker
from grok.interfaces import IRESTSkinType
from grok.interfaces import IViewletManager as IGrokViewletManager
@@ -139,25 +139,6 @@
return True
-class FormGrokker(martian.ClassGrokker):
- martian.component(components.GrokForm)
- martian.directive(grok.context)
-
- def execute(self, factory, config, context, **kw):
- # Set up form_fields from context class if they haven't been
- # configured manually already.
- if getattr(factory, 'form_fields', None) is None:
- factory.form_fields = formlib.get_auto_fields(context)
-
- if not getattr(factory.render, 'base_method', False):
- raise GrokError(
- "It is not allowed to specify a custom 'render' "
- "method for form %r. Forms either use the default "
- "template or a custom-supplied one." % factory,
- factory)
- return True
-
-
class JSONGrokker(martian.MethodGrokker):
martian.component(grok.JSON)
martian.directive(grok.context)
Modified: grok/branches/sylvain-grokcore-formlib/src/grok/meta.zcml
===================================================================
--- grok/branches/sylvain-grokcore-formlib/src/grok/meta.zcml 2008-09-26 08:57:40 UTC (rev 91500)
+++ grok/branches/sylvain-grokcore-formlib/src/grok/meta.zcml 2008-09-26 09:15:39 UTC (rev 91501)
@@ -7,6 +7,7 @@
<!-- Load the grokkers -->
<include package="grokcore.component" file="meta.zcml" />
+ <include package="grokcore.formlib" file="meta.zcml" />
<include package="grokcore.security" file="meta.zcml" />
<include package="grokcore.view" file="meta.zcml" />
<grok:grok package=".meta" />
Modified: grok/branches/sylvain-grokcore-formlib/src/grok/testing.py
===================================================================
--- grok/branches/sylvain-grokcore-formlib/src/grok/testing.py 2008-09-26 08:57:40 UTC (rev 91500)
+++ grok/branches/sylvain-grokcore-formlib/src/grok/testing.py 2008-09-26 09:15:39 UTC (rev 91501)
@@ -45,6 +45,7 @@
zcml.do_grok('grokcore.security.meta', config)
zcml.do_grok('grokcore.view.meta', config)
zcml.do_grok('grokcore.view.templatereg', config)
+ zcml.do_grok('grokcore.formlib.meta', config)
zcml.do_grok('grok.meta', config)
zcml.do_grok(module_name, config)
config.execute_actions()
Modified: grok/branches/sylvain-grokcore-formlib/versions.cfg
===================================================================
--- grok/branches/sylvain-grokcore-formlib/versions.cfg 2008-09-26 08:57:40 UTC (rev 91500)
+++ grok/branches/sylvain-grokcore-formlib/versions.cfg 2008-09-26 09:15:39 UTC (rev 91501)
@@ -6,8 +6,9 @@
ZODB3 = 3.8
docutils = 0.4
grokcore.component = 1.5.1
+grokcore.formlib = 1.0
grokcore.security = 1.0
-grokcore.view = 1.0
+grokcore.view = 1.1
martian = 0.10
mechanize = 0.1.7b
pytz = 2007k
More information about the Checkins
mailing list