--- a/src/pyams_utils/include.py Thu Mar 15 09:24:20 2018 +0100
+++ b/src/pyams_utils/include.py Thu Mar 15 09:25:02 2018 +0100
@@ -23,7 +23,7 @@
# import packages
from chameleon import PageTemplateFile
from pyams_utils.context import ContextSelector
-from pyams_utils.request import get_annotations, get_debug
+from pyams_utils.request import get_annotations, get_debug, RequestSelector
from pyams_utils.site import site_factory
from pyams_utils.tales import ExtensionExpr
from pyams_utils.traversing import NamespaceTraverser
@@ -50,6 +50,7 @@
# add custom subscriber predicate to filter events via supported interface(s)
config.add_subscriber_predicate('context_selector', ContextSelector)
+ config.add_subscriber_predicate('request_selector', RequestSelector)
# load registry components
config.registry.registerAdapter(AttributeAnnotations, (IAttributeAnnotatable, ), IAnnotations)
--- a/src/pyams_utils/request.py Thu Mar 15 09:24:20 2018 +0100
+++ b/src/pyams_utils/request.py Thu Mar 15 09:25:02 2018 +0100
@@ -31,6 +31,42 @@
_marker = object()
+class RequestSelector(object):
+ """Interface based request selector
+
+ This selector can be used as a subscriber predicate to define
+ an interface that the event's 'request' attribute must support for the event to be applied::
+
+ .. code-block:: python
+
+ from pyams_utils.interfaces.site import ISiteRoot
+
+ @subscriber(IBeforeTraverseEvent, request_selector=IPyAMSLayer)
+ def before_traverse_event(event):
+ '''This is an event handler for an IPyAMSRequest modification event'''
+ """
+
+ def __init__(self, ifaces, config):
+ if not isinstance(ifaces, (list, tuple, set)):
+ ifaces = (ifaces,)
+ self.interfaces = ifaces
+
+ def text(self):
+ return 'request_selector = %s' % str(self.interfaces)
+
+ phash = text
+
+ def __call__(self, event):
+ for intf in self.interfaces:
+ try:
+ if intf.providedBy(event.request):
+ return True
+ except (AttributeError, TypeError):
+ if isinstance(event.request, intf):
+ return True
+ return False
+
+
def request_property(key=None, prefix=None):
"""Define a method decorator used to store result into current request's annotations