more on GenericView; added FormController

git-svn-id: svn://svn.cy55.de/Zope3/src/cybertools/trunk@1353 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
helmutm 2006-09-20 20:39:21 +00:00
parent eea19cc7ea
commit 903c8382fb
4 changed files with 87 additions and 0 deletions

View file

@ -206,3 +206,39 @@ packages.
>>> gvc = component.getUtility(IViewConfigurator)
Processing form input
---------------------
GenericView also provides an update() method that may be called from
templates that might receive form information.
>>> view.update()
True
Real work can only be done by an adapter to GenericView that provides the
IFormController interface with its update(). There also must be a
form variable (typically coming from a hidden field) with the name
'form.action' that provides the name under which the form controller is
registered.
>>> from cybertools.browser.controller import IFormController, FormController
>>> class MyController(FormController):
... def update(self):
... print 'updating...'
>>> component.provideAdapter(MyController, (View, IBrowserRequest),
... IFormController, name='save')
>>> request = TestRequest(form={'form.action': 'save'})
>>> view = View(obj, request)
>>> view.update()
updating...
True
The update() method will only be executed once:
>>> view.update()
True

View file

@ -23,12 +23,15 @@ $Id$
"""
from zope import component
from zope.interface import Interface, implements
from zope.app.pagetemplate import ViewPageTemplateFile
from zope.cachedescriptors.property import Lazy
from cybertools.browser.configurator import IViewConfigurator, IMacroViewProperty
# layout controller: collects information about head elements, skins, portlets, etc
class Controller(object):
def __init__(self, context, request):
@ -115,3 +118,29 @@ class Macro(object):
def __call__(self):
return self.macro
# form processing:
# the part of the model/view/controller pattern that deals with
# form input
class IFormController(Interface):
""" Used as a named adapter by GenericView for processing form input.
"""
def update():
""" Processing form input...
"""
class FormController(object):
implements(IFormController)
def __init__(self, context, request):
self.view = view = context # the controller is adapted to a view
self.context = context.context
self.request = request
def update(self):
pass

View file

@ -3,6 +3,7 @@
i18n:domain="zope"
tal:define="controller nocall:view/@@controller;
resourceBase controller/resourceBase;
dummy view/update;
body view/pageBody">
<head metal:define-macro="head">

View file

@ -51,6 +51,8 @@ class GenericView(object):
template = macro = menu = skin = None
_updated = False
def setController(self, controller):
# make the (one and only controller) available via the request
viewAnnotations = self.request.annotations.setdefault('cybertools.browser', {})
@ -68,11 +70,30 @@ class GenericView(object):
def __init__(self, context, request):
self.context = context
self.request = request
#cont = self.controller # check: leads to strange AttributeError in doctest
#if cont is not None:
# self.setupController()
def __call__(self, *args, **kw):
return self.index(*args, **kw)
#def render(self, *args, **kw):
# return self.index(*args, **kw)
def update(self):
if not self._updated:
action = self.request.form.get('form.action')
if action:
fc = component.getMultiAdapter((self, self.request),
name=action)
fc.update()
self._updated = True
return True
def setupController(self):
""" May be called by __init__() if there is already a controller
or when the controller is set. May be implemented by subclass.
"""
pass
@Lazy