From 5a11e2ad0828b7c763d0c81211f686a85bc0324c Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 21 May 2009 16:01:58 +0000 Subject: - Class objects may now be used as view callables (both via ZCML and via use of the ``bfg_view`` decorator in Python 2.6 as a class decorator). The calling semantics when using a class as a view callable is similar to that of using a class as a Zope "browser view": the class' ``__init__`` must accept two positional parameters (conventionally named ``context``, and ``request``). The resulting instance must be callable (it must have a ``__call__`` method). When called, the instance should return a response. For example:: from webob import Response class MyView(object): def __init__(self, context, request): self.context = context self.request = request def __call__(self): return Response('hello from %s!' % self.context) See the "Views" chapter in the documentation and the ``repoze.bfg.view`` API documentation for more information. --- repoze/bfg/zcml.py | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'repoze/bfg/zcml.py') diff --git a/repoze/bfg/zcml.py b/repoze/bfg/zcml.py index 34b071676..737e2409b 100644 --- a/repoze/bfg/zcml.py +++ b/repoze/bfg/zcml.py @@ -1,3 +1,4 @@ +import inspect import types from zope.configuration import xmlconfig @@ -50,7 +51,7 @@ def view(_context, # adapts() decorations may be used against either functions or # class instances - if isinstance(view, types.FunctionType): + if inspect.isfunction(view): adapted_by = adaptedBy(view) else: adapted_by = adaptedBy(type(view)) @@ -66,6 +67,22 @@ def view(_context, # the view specification; we ignore it. pass + if inspect.isclass(view): + # If the object we've located is a class, turn it into a + # function that operates like a Zope view (when it's invoked, + # construct an instance using 'context' and 'request' as + # position arguments, then immediately invoke the __call__ + # method of the instance with no arguments; __call__ should + # return an IResponse). + _view = view + def _bfg_class_view(context, request): + inst = _view(context, request) + return inst() + _bfg_class_view.__module__ = view.__module__ + _bfg_class_view.__name__ = view.__name__ + _bfg_class_view.__doc__ = view.__doc__ + view = _bfg_class_view + if request_type is None: request_type = IRequest -- cgit v1.2.3