summaryrefslogtreecommitdiff
path: root/repoze
diff options
context:
space:
mode:
authorChris McDonough <chrism@agendaless.com>2010-01-03 03:39:30 +0000
committerChris McDonough <chrism@agendaless.com>2010-01-03 03:39:30 +0000
commiteecdbc34962b00e35d41039af014462cf558acee (patch)
tree784bfdf054d6f4846fb1817d1ba7b01792792dcc /repoze
parent1dff935445ff293a7434f074c1f6bb7304174ec2 (diff)
downloadpyramid-eecdbc34962b00e35d41039af014462cf558acee.tar.gz
pyramid-eecdbc34962b00e35d41039af014462cf558acee.tar.bz2
pyramid-eecdbc34962b00e35d41039af014462cf558acee.zip
Features
-------- - The ``Configurator.add_view`` method now accepts an argument named ``context``. This is an alias for the older argument named ``for_``; it is preferred over ``for_``, but ``for_`` will continue to be supported "forever". - The ``view`` ZCML directive now accepts an attribute named ``context``. This is an alias for the older attribute named ``for``; it is preferred over ``for``, but ``for`` will continue to be supported "forever". - The ``Configurator.add_route`` method now accepts an argument named ``view_context``. This is an alias for the older argument named ``view_for``; it is preferred over ``view_for``, but ``view_for`` will continue to be supported "forever". - The ``route`` ZCML directive now accepts an attribute named ``view_context``. This is an alias for the older attribute named ``view_for``; it is preferred over ``view_for``, but ``view_for`` will continue to be supported "forever". Documentation and Paster Templates ---------------------------------- - All uses of the ``Configurator.add_view`` method that used its ``for_`` argument now use the ``context``argument instead. - All uses of the ``Configurator.add_route`` method that used its ``view_for`` argument now use the ``view_context``argument instead. - All uses of the ``view`` ZCML directive that used its ``for`` attribute now use the ``context`` attribute instead. - All uses of the ``route`` ZCML directive that used its ``view_for`` attribute now use the ``view_context`` attribute instead.
Diffstat (limited to 'repoze')
-rw-r--r--repoze/bfg/configuration.py45
-rw-r--r--repoze/bfg/paster_templates/alchemy/+package+/configure.zcml4
-rw-r--r--repoze/bfg/paster_templates/starter/+package+/configure.zcml2
-rw-r--r--repoze/bfg/paster_templates/zodb/+package+/configure.zcml2
-rw-r--r--repoze/bfg/tests/test_configuration.py43
-rw-r--r--repoze/bfg/tests/test_view.py10
-rw-r--r--repoze/bfg/tests/test_zcml.py78
-rw-r--r--repoze/bfg/view.py15
-rw-r--r--repoze/bfg/zcml.py30
9 files changed, 186 insertions, 43 deletions
diff --git a/repoze/bfg/configuration.py b/repoze/bfg/configuration.py
index bce8be232..5fd5b5b1b 100644
--- a/repoze/bfg/configuration.py
+++ b/repoze/bfg/configuration.py
@@ -431,7 +431,8 @@ class Configurator(object):
request_type=None, route_name=None, request_method=None,
request_param=None, containment=None, attr=None,
renderer=None, wrapper=None, xhr=False, accept=None,
- header=None, path_info=None, custom_predicates=(), _info=u''):
+ header=None, path_info=None, custom_predicates=(),
+ context=None, _info=u''):
""" Add a :term:`view configuration` to the current
configuration state. Arguments to ``add_view`` are broken
down below into *predicate* arguments and *non-predicate*
@@ -535,7 +536,7 @@ class Configurator(object):
The :term:`view name`. Read :ref:`traversal_chapter` to
understand the concept of a view name.
- for
+ context
An object representing Python class that the :term:`context`
must be an instance of, *or* the :term:`interface` that the
@@ -543,7 +544,9 @@ class Configurator(object):
found and called. This predicate is true when the
:term:`context` is an instance of the represented class or
if the :term:`context` provides the represented interface;
- it is otherwise false.
+ it is otherwise false. This argument may also be provided
+ to ``add_view`` as ``for_`` (an older, still-supported
+ spelling).
route_name
@@ -701,12 +704,16 @@ class Configurator(object):
derived_view = self._derive_view(view, permission, predicates, attr,
renderer, wrapper, name, accept)
- r_for_ = for_
+
+ if context is None:
+ context = for_
+
+ r_context = context
r_request_type = request_type
- if r_for_ is None:
- r_for_ = Interface
- if not IInterface.providedBy(r_for_):
- r_for_ = implementedBy(r_for_)
+ if r_context is None:
+ r_context = Interface
+ if not IInterface.providedBy(r_context):
+ r_context = implementedBy(r_context)
if not IInterface.providedBy(r_request_type):
r_request_type = implementedBy(r_request_type)
@@ -733,7 +740,7 @@ class Configurator(object):
old_view = None
for view_type in (IView, ISecuredView, IMultiView):
- old_view = registered((r_for_, r_request_type), view_type, name)
+ old_view = registered((r_context, r_request_type), view_type, name)
if old_view is not None:
break
@@ -745,7 +752,7 @@ class Configurator(object):
view_iface = ISecuredView
else:
view_iface = IView
- self.registry.registerAdapter(derived_view, (for_, request_type),
+ self.registry.registerAdapter(derived_view, (context, request_type),
view_iface, name, info=_info)
else:
# XXX we could try to be more efficient here and register
@@ -763,8 +770,8 @@ class Configurator(object):
for view_type in (IView, ISecuredView):
# unregister any existing views
self.registry.adapters.unregister(
- (r_for_, r_request_type), view_type, name=name)
- self.registry.registerAdapter(multiview, (for_, request_type),
+ (r_context, r_request_type), view_type, name=name)
+ self.registry.registerAdapter(multiview, (context, request_type),
IMultiView, name, info=_info)
def add_route(self, name, path, view=None, view_for=None,
@@ -777,7 +784,8 @@ class Configurator(object):
view_containment=None, view_attr=None,
renderer=None, view_renderer=None, view_header=None,
view_accept=None, view_xhr=False,
- view_path_info=None, _info=u''):
+ view_path_info=None, view_context=None,
+ _info=u''):
""" Add a :term:`route configuration` to the current
configuration state, as well as possibly a :term:`view
configuration` to be used to specify a :term:`view callable`
@@ -910,7 +918,7 @@ class Configurator(object):
callable when this route
matches. e.g. ``mypackage.views.my_view``.
- view_for
+ view_context
A reference to a class or an :term:`interface` that the
:term:`context` of the view should match for the view named
@@ -921,7 +929,7 @@ class Configurator(object):
If the ``view`` argument is not provided, this argument has
no effect.
- This attribute can also be spelled as ``for_``.
+ This attribute can also be spelled as ``for_`` or ``view_for``.
view_permission
@@ -1017,12 +1025,15 @@ class Configurator(object):
request_iface, IRouteRequest, name=name)
if view:
- view_for = view_for or for_
+ if view_context is None:
+ view_context = view_for
+ if view_context is None:
+ view_context = for_
view_permission = view_permission or permission
view_renderer = view_renderer or renderer
self.add_view(
permission=view_permission,
- for_=view_for,
+ context=view_context,
view=view,
name='',
route_name=name,
diff --git a/repoze/bfg/paster_templates/alchemy/+package+/configure.zcml b/repoze/bfg/paster_templates/alchemy/+package+/configure.zcml
index 1c8f26e62..40b863c62 100644
--- a/repoze/bfg/paster_templates/alchemy/+package+/configure.zcml
+++ b/repoze/bfg/paster_templates/alchemy/+package+/configure.zcml
@@ -4,13 +4,13 @@
<include package="repoze.bfg.includes" />
<view
- for=".models.MyApp"
+ context=".models.MyApp"
view=".views.view_root"
renderer="templates/root.pt"
/>
<view
- for=".models.MyModel"
+ context=".models.MyModel"
view=".views.view_model"
renderer="templates/model.pt"
/>
diff --git a/repoze/bfg/paster_templates/starter/+package+/configure.zcml b/repoze/bfg/paster_templates/starter/+package+/configure.zcml
index 038f04da4..e83dd3933 100644
--- a/repoze/bfg/paster_templates/starter/+package+/configure.zcml
+++ b/repoze/bfg/paster_templates/starter/+package+/configure.zcml
@@ -4,7 +4,7 @@
<include package="repoze.bfg.includes" />
<view
- for=".models.MyModel"
+ context=".models.MyModel"
view=".views.my_view"
renderer="templates/mytemplate.pt"
/>
diff --git a/repoze/bfg/paster_templates/zodb/+package+/configure.zcml b/repoze/bfg/paster_templates/zodb/+package+/configure.zcml
index 038f04da4..e83dd3933 100644
--- a/repoze/bfg/paster_templates/zodb/+package+/configure.zcml
+++ b/repoze/bfg/paster_templates/zodb/+package+/configure.zcml
@@ -4,7 +4,7 @@
<include package="repoze.bfg.includes" />
<view
- for=".models.MyModel"
+ context=".models.MyModel"
view=".views.my_view"
renderer="templates/mytemplate.pt"
/>
diff --git a/repoze/bfg/tests/test_configuration.py b/repoze/bfg/tests/test_configuration.py
index d8b6aca99..ba306f26b 100644
--- a/repoze/bfg/tests/test_configuration.py
+++ b/repoze/bfg/tests/test_configuration.py
@@ -492,7 +492,26 @@ class ConfiguratorTests(unittest.TestCase):
result = wrapper(None, None)
self.assertEqual(result, 'OK')
+ def test_add_view_context_as_class(self):
+ from zope.interface import implementedBy
+ view = lambda *arg: 'OK'
+ class Foo:
+ pass
+ config = self._makeOne()
+ config.add_view(context=Foo, view=view)
+ foo = implementedBy(Foo)
+ wrapper = self._getViewCallable(config, foo)
+ self.assertEqual(wrapper, view)
+
+ def test_add_view_context_as_iface(self):
+ view = lambda *arg: 'OK'
+ config = self._makeOne()
+ config.add_view(context=IDummy, view=view)
+ wrapper = self._getViewCallable(config, IDummy)
+ self.assertEqual(wrapper, view)
+
def test_add_view_for_as_class(self):
+ # ``for_`` is older spelling for ``context``
from zope.interface import implementedBy
view = lambda *arg: 'OK'
class Foo:
@@ -504,12 +523,23 @@ class ConfiguratorTests(unittest.TestCase):
self.assertEqual(wrapper, view)
def test_add_view_for_as_iface(self):
+ # ``for_`` is older spelling for ``context``
view = lambda *arg: 'OK'
config = self._makeOne()
config.add_view(for_=IDummy, view=view)
wrapper = self._getViewCallable(config, IDummy)
self.assertEqual(wrapper, view)
+ def test_add_view_context_trumps_for(self):
+ # ``for_`` is older spelling for ``context``
+ view = lambda *arg: 'OK'
+ config = self._makeOne()
+ class Foo:
+ pass
+ config.add_view(context=IDummy, for_=Foo, view=view)
+ wrapper = self._getViewCallable(config, IDummy)
+ self.assertEqual(wrapper, view)
+
def test_add_view_register_secured_view(self):
from zope.interface import Interface
from repoze.bfg.interfaces import IRequest
@@ -1091,6 +1121,17 @@ class ConfiguratorTests(unittest.TestCase):
self.assertEqual(wrapper(None, None), 'OK')
self._assertRoute(config, 'name', 'path')
+ def test_add_route_with_view_context(self):
+ config = self._makeOne()
+ view = lambda *arg: 'OK'
+ config.add_route('name', 'path', view=view, view_context=IDummy)
+ request_type = self._getRouteRequestIface(config, 'name')
+ wrapper = self._getViewCallable(config, IDummy, request_type)
+ self.assertEqual(wrapper(None, None), 'OK')
+ self._assertRoute(config, 'name', 'path')
+ wrapper = self._getViewCallable(config, IOther, request_type)
+ self.assertEqual(wrapper, None)
+
def test_add_route_with_view_for(self):
config = self._makeOne()
view = lambda *arg: 'OK'
@@ -1102,7 +1143,7 @@ class ConfiguratorTests(unittest.TestCase):
wrapper = self._getViewCallable(config, IOther, request_type)
self.assertEqual(wrapper, None)
- def test_add_route_with_view_for_alias(self):
+ def test_add_route_with_for_(self):
config = self._makeOne()
view = lambda *arg: 'OK'
config.add_route('name', 'path', view=view, for_=IDummy)
diff --git a/repoze/bfg/tests/test_view.py b/repoze/bfg/tests/test_view.py
index 677c15bc8..94b896893 100644
--- a/repoze/bfg/tests/test_view.py
+++ b/repoze/bfg/tests/test_view.py
@@ -289,7 +289,7 @@ class TestBFGViewDecorator(unittest.TestCase):
decorator = self._makeOne()
self.assertEqual(decorator.name, '')
self.assertEqual(decorator.request_type, None)
- self.assertEqual(decorator.for_, None)
+ self.assertEqual(decorator.context, None)
self.assertEqual(decorator.permission, None)
def test_create_nondefaults(self):
@@ -297,7 +297,7 @@ class TestBFGViewDecorator(unittest.TestCase):
permission='foo')
self.assertEqual(decorator.name, None)
self.assertEqual(decorator.request_type, None)
- self.assertEqual(decorator.for_, None)
+ self.assertEqual(decorator.context, None)
self.assertEqual(decorator.permission, 'foo')
def test_call_function(self):
@@ -308,7 +308,7 @@ class TestBFGViewDecorator(unittest.TestCase):
self.failUnless(wrapped is foo)
settings = wrapped.__bfg_view_settings__[0]
self.assertEqual(settings['permission'], None)
- self.assertEqual(settings['for_'], None)
+ self.assertEqual(settings['context'], None)
self.assertEqual(settings['request_type'], None)
def test_call_oldstyle_class(self):
@@ -319,7 +319,7 @@ class TestBFGViewDecorator(unittest.TestCase):
self.failUnless(wrapped is foo)
settings = wrapped.__bfg_view_settings__[0]
self.assertEqual(settings['permission'], None)
- self.assertEqual(settings['for_'], None)
+ self.assertEqual(settings['context'], None)
self.assertEqual(settings['request_type'], None)
def test_call_newstyle_class(self):
@@ -330,7 +330,7 @@ class TestBFGViewDecorator(unittest.TestCase):
self.failUnless(wrapped is foo)
settings = wrapped.__bfg_view_settings__[0]
self.assertEqual(settings['permission'], None)
- self.assertEqual(settings['for_'], None)
+ self.assertEqual(settings['context'], None)
self.assertEqual(settings['request_type'], None)
def test_stacking(self):
diff --git a/repoze/bfg/tests/test_zcml.py b/repoze/bfg/tests/test_zcml.py
index b50f841c2..3cbeb05c8 100644
--- a/repoze/bfg/tests/test_zcml.py
+++ b/repoze/bfg/tests/test_zcml.py
@@ -117,6 +117,27 @@ class TestViewDirective(unittest.TestCase):
regview = reg.adapters.lookup((IDummy, IRequest), IView, name='')
self.assertEqual(regview(None, None), 'OK')
+ def test_context_trumps_for(self):
+ from repoze.bfg.threadlocal import get_current_registry
+ from repoze.bfg.interfaces import IView
+ from repoze.bfg.interfaces import IRequest
+ context = DummyContext()
+ reg = get_current_registry()
+ view = lambda *arg: 'OK'
+ class Foo:
+ pass
+ self._callFUT(context, 'repoze.view', for_=Foo, view=view,
+ context=IDummy)
+ actions = context.actions
+ self.assertEqual(len(actions), 1)
+ discrim = ('view', IDummy, '', None, IView, None, None, None, None,
+ None, False, None, None, None)
+ self.assertEqual(actions[0]['discriminator'], discrim)
+ register = actions[0]['callable']
+ register()
+ regview = reg.adapters.lookup((IDummy, IRequest), IView, name='')
+ self.assertEqual(regview(None, None), 'OK')
+
class TestNotFoundDirective(unittest.TestCase):
def setUp(self):
testing.setUp()
@@ -475,6 +496,63 @@ class TestRouteDirective(unittest.TestCase):
wrapped = reg.adapters.lookup((Interface, request_type), IView, name='')
self.failUnless(wrapped)
+ def test_with_view_and_view_context(self):
+ from repoze.bfg.threadlocal import get_current_registry
+ from repoze.bfg.interfaces import IView
+ from repoze.bfg.interfaces import IRouteRequest
+ context = DummyContext()
+ view = lambda *arg: 'OK'
+ self._callFUT(context, 'name', 'path', view=view, view_context=IDummy)
+ actions = context.actions
+ self.assertEqual(len(actions), 2)
+
+ route_action = actions[0]
+ route_action['callable']()
+ route_discriminator = route_action['discriminator']
+ self.assertEqual(route_discriminator,
+ ('route', 'name', False, None, None, None, None,None))
+ self._assertRoute('name', 'path')
+
+ view_action = actions[1]
+ reg = get_current_registry()
+ request_type = reg.getUtility(IRouteRequest, 'name')
+ view_discriminator = view_action['discriminator']
+ discrim = ('view', IDummy, '', request_type, IView, None, None, None,
+ 'name', None, False, None, None, None)
+ self.assertEqual(view_discriminator, discrim)
+ wrapped = reg.adapters.lookup((IDummy, request_type), IView, name='')
+ self.failUnless(wrapped)
+
+ def test_with_view_context_trumps_view_for(self):
+ from repoze.bfg.threadlocal import get_current_registry
+ from repoze.bfg.interfaces import IView
+ from repoze.bfg.interfaces import IRouteRequest
+ context = DummyContext()
+ view = lambda *arg: 'OK'
+ class Foo:
+ pass
+ self._callFUT(context, 'name', 'path', view=view, view_context=IDummy,
+ view_for=Foo)
+ actions = context.actions
+ self.assertEqual(len(actions), 2)
+
+ route_action = actions[0]
+ route_action['callable']()
+ route_discriminator = route_action['discriminator']
+ self.assertEqual(route_discriminator,
+ ('route', 'name', False, None, None, None, None,None))
+ self._assertRoute('name', 'path')
+
+ view_action = actions[1]
+ reg = get_current_registry()
+ request_type = reg.getUtility(IRouteRequest, 'name')
+ view_discriminator = view_action['discriminator']
+ discrim = ('view', IDummy, '', request_type, IView, None, None, None,
+ 'name', None, False, None, None, None)
+ self.assertEqual(view_discriminator, discrim)
+ wrapped = reg.adapters.lookup((IDummy, request_type), IView, name='')
+ self.failUnless(wrapped)
+
def test_with_dotted_renderer(self):
from repoze.bfg.threadlocal import get_current_registry
diff --git a/repoze/bfg/view.py b/repoze/bfg/view.py
index 8a33e246d..af3acb8b6 100644
--- a/repoze/bfg/view.py
+++ b/repoze/bfg/view.py
@@ -233,7 +233,7 @@ class bfg_view(object):
from models import MyModel
- @bfg_view(name='my_view', for_=MyModel, permission='read',
+ @bfg_view(name='my_view', context=MyModel, permission='read',
route_name='site1')
def my_view(context, request):
return 'OK'
@@ -243,7 +243,7 @@ class bfg_view(object):
import views
import models
- config.add_view(views.my_view, for_=models.MyModel, name='my_view',
+ config.add_view(views.my_view, context=models.MyModel, name='my_view',
permission='read', 'route_name='site1')
Or might replace the following ZCML ``view`` declaration::
@@ -257,13 +257,14 @@ class bfg_view(object):
/>
The following arguments are supported as arguments to
- ``bfg_view``: ``for_``, ``permission``, ``name``,
+ ``bfg_view``: ``context``, ``permission``, ``name``,
``request_type``, ``route_name``, ``request_method``,
``request_param``, ``containment``, ``xhr``, ``accept``,
``header`` and ``path_info``.
- If ``for_`` is not supplied, the interface
- ``zope.interface.Interface`` (matching any context) is used.
+ If ``context`` is not supplied, the interface
+ ``zope.interface.Interface`` (matching any context) is used. An alias
+ for ``context`` is ``for_``.
If ``permission`` is not supplied, no permission is registered for
this view (it's accessible by any caller).
@@ -456,10 +457,10 @@ class bfg_view(object):
route_name=None, request_method=None, request_param=None,
containment=None, attr=None, renderer=None, wrapper=None,
xhr=False, accept=None, header=None, path_info=None,
- custom_predicates=()):
+ custom_predicates=(), context=None):
self.name = name
self.request_type = request_type
- self.for_ = for_
+ self.context = context or for_
self.permission = permission
self.route_name = route_name
self.request_method = request_method
diff --git a/repoze/bfg/zcml.py b/repoze/bfg/zcml.py
index 6467907db..c09a52fcd 100644
--- a/repoze/bfg/zcml.py
+++ b/repoze/bfg/zcml.py
@@ -37,11 +37,17 @@ from repoze.bfg.threadlocal import get_current_registry
###################### directives ##########################
class IViewDirective(Interface):
- for_ = GlobalObject(
+ context = GlobalObject(
title=u"The interface or class this view is for.",
required=False
)
+ for_ = GlobalObject(
+ title=(u"The interface or class this view is for (alternate spelling "
+ "of ``context``)."),
+ required=False
+ )
+
permission = TextLine(
title=u"Permission",
description=u"The permission needed to use the view.",
@@ -162,6 +168,7 @@ def view(
header=None,
path_info=None,
custom_predicates=(),
+ context=None,
cacheable=True, # not used, here for b/w compat < 0.8
):
@@ -178,10 +185,12 @@ def view(
if renderer and '.' in renderer:
renderer = path_spec(_context, renderer)
+ context = context or for_
+
def register():
config = Configurator(reg, package=_context.package)
config.add_view(
- permission=permission, for_=for_, view=view, name=name,
+ permission=permission, context=context, view=view, name=name,
request_type=request_type, route_name=route_name,
request_method=request_method, request_param=request_param,
containment=containment, attr=attr, renderer=renderer,
@@ -189,7 +198,7 @@ def view(
path_info=path_info, custom_predicates=custom_predicates,
_info=_context.info)
- discriminator = ['view', for_, name, request_type, IView, containment,
+ discriminator = ['view', context, name, request_type, IView, containment,
request_param, request_method, route_name, attr,
xhr, accept, header, path_info]
@@ -211,9 +220,10 @@ class IRouteDirective(Interface):
factory = GlobalObject(title=u'context factory', required=False)
view = GlobalObject(title=u'view', required=False)
- view_for = GlobalObject(title=u'view_for', required=False)
- # alias for view_for
+ view_context = GlobalObject(title=u'view_context', required=False)
+ # aliases for view_context
for_ = GlobalObject(title=u'for', required=False)
+ view_for = GlobalObject(title=u'view_for', required=False)
view_permission = TextLine(title=u'view_permission', required=False)
# alias for view_permission
@@ -255,7 +265,7 @@ def route(_context, name, path, view=None, view_for=None,
view_request_param=None, view_containment=None, view_attr=None,
renderer=None, view_renderer=None, view_header=None,
view_accept=None, view_xhr=False,
- view_path_info=None):
+ view_path_info=None, view_context=None):
""" Handle ``route`` ZCML directives
"""
# the strange ordering of the request kw args above is for b/w
@@ -264,7 +274,9 @@ def route(_context, name, path, view=None, view_for=None,
# in the routelist will be tried
reg = get_current_registry()
- view_for = view_for or for_
+ if view_context is None:
+ view_context = view_for or for_
+
view_permission = view_permission or permission
view_renderer = view_renderer or renderer
if view_renderer and '.' in view_renderer:
@@ -284,7 +296,7 @@ def route(_context, name, path, view=None, view_for=None,
request_param=request_param,
custom_predicates=custom_predicates,
view=view,
- view_for=view_for,
+ view_context=view_context,
view_permission=view_permission,
view_request_method=view_request_method,
view_request_param=view_request_param,
@@ -315,7 +327,7 @@ def route(_context, name, path, view=None, view_for=None,
reg.registerUtility(request_iface, IRouteRequest, name=name)
_context.action(
discriminator = (
- 'view', view_for, '', request_iface, IView,
+ 'view', view_context, '', request_iface, IView,
view_containment, view_request_param, view_request_method,
name, view_attr, view_xhr, view_accept, view_header,
view_path_info),