summaryrefslogtreecommitdiff
path: root/repoze/bfg/zcml.py
diff options
context:
space:
mode:
authorChris McDonough <chrism@agendaless.com>2009-05-21 16:01:58 +0000
committerChris McDonough <chrism@agendaless.com>2009-05-21 16:01:58 +0000
commit5a11e2ad0828b7c763d0c81211f686a85bc0324c (patch)
tree750deaa5086279a1cd0baa28c0d5bdaa17414463 /repoze/bfg/zcml.py
parent385084582eeff5f2f1a93f3b90c091dc1a4ad50e (diff)
downloadpyramid-5a11e2ad0828b7c763d0c81211f686a85bc0324c.tar.gz
pyramid-5a11e2ad0828b7c763d0c81211f686a85bc0324c.tar.bz2
pyramid-5a11e2ad0828b7c763d0c81211f686a85bc0324c.zip
- 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.
Diffstat (limited to 'repoze/bfg/zcml.py')
-rw-r--r--repoze/bfg/zcml.py19
1 files changed, 18 insertions, 1 deletions
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