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) >>> 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 import component
from zope.interface import Interface, implements
from zope.app.pagetemplate import ViewPageTemplateFile from zope.app.pagetemplate import ViewPageTemplateFile
from zope.cachedescriptors.property import Lazy from zope.cachedescriptors.property import Lazy
from cybertools.browser.configurator import IViewConfigurator, IMacroViewProperty from cybertools.browser.configurator import IViewConfigurator, IMacroViewProperty
# layout controller: collects information about head elements, skins, portlets, etc
class Controller(object): class Controller(object):
def __init__(self, context, request): def __init__(self, context, request):
@ -115,3 +118,29 @@ class Macro(object):
def __call__(self): def __call__(self):
return self.macro 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" i18n:domain="zope"
tal:define="controller nocall:view/@@controller; tal:define="controller nocall:view/@@controller;
resourceBase controller/resourceBase; resourceBase controller/resourceBase;
dummy view/update;
body view/pageBody"> body view/pageBody">
<head metal:define-macro="head"> <head metal:define-macro="head">

View file

@ -51,6 +51,8 @@ class GenericView(object):
template = macro = menu = skin = None template = macro = menu = skin = None
_updated = False
def setController(self, controller): def setController(self, controller):
# make the (one and only controller) available via the request # make the (one and only controller) available via the request
viewAnnotations = self.request.annotations.setdefault('cybertools.browser', {}) viewAnnotations = self.request.annotations.setdefault('cybertools.browser', {})
@ -68,11 +70,30 @@ class GenericView(object):
def __init__(self, context, request): def __init__(self, context, request):
self.context = context self.context = context
self.request = request 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): def __call__(self, *args, **kw):
return self.index(*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): 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 pass
@Lazy @Lazy