diff -r aa51effb1d8a -r 917951020682 src/pyams_viewlet/provider.py --- a/src/pyams_viewlet/provider.py Wed Nov 18 12:58:36 2020 +0100 +++ b/src/pyams_viewlet/provider.py Wed Nov 18 12:59:20 2020 +0100 @@ -16,6 +16,7 @@ content provider into a Chameleon or ZPT template. """ +import inspect import re from chameleon.astutil import Symbol @@ -26,6 +27,7 @@ from zope.contentprovider.tales import addTALNamespaceData from zope.location.interfaces import ILocation +from pyams_utils.factory import is_interface from pyams_utils.tales import ContextExprMixin @@ -105,7 +107,23 @@ raise ContentProviderLookupError(name) registry = request.registry - provider = registry.queryMultiAdapter((context, request, view), IContentProvider, name=name) + + # we can look into request annotations to check if a provider implementation has already + # been provided during traversal; if not, a simple adapter lookup is done + provider = request.annotations.get('provider:{}:factory'.format(name)) + if isinstance(provider, dict): + for intf, factory in provider.items(): + if (is_interface(intf) and intf.providedBy(context)) or \ + (inspect.isclass(intf) and isinstance(context, intf)): + provider = factory + break + else: + provider = None + if callable(provider): + provider = provider(context, request, view) + if provider is None: + provider = registry.queryMultiAdapter((context, request, view), IContentProvider, + name=name) # raise an exception if the provider was not found. if provider is None: