src/pyams_viewlet/provider.py
changeset 59 917951020682
parent 47 df022d00a9c4
equal deleted inserted replaced
58:aa51effb1d8a 59:917951020682
    14 
    14 
    15 This module provides the "provider:" TALES expression, which allows inclusion of any registered
    15 This module provides the "provider:" TALES expression, which allows inclusion of any registered
    16 content provider into a Chameleon or ZPT template.
    16 content provider into a Chameleon or ZPT template.
    17 """
    17 """
    18 
    18 
       
    19 import inspect
    19 import re
    20 import re
    20 
    21 
    21 from chameleon.astutil import Symbol
    22 from chameleon.astutil import Symbol
    22 from chameleon.tales import StringExpr
    23 from chameleon.tales import StringExpr
    23 from pyramid_zope_request import PyramidPublisherRequest
    24 from pyramid_zope_request import PyramidPublisherRequest
    24 from zope.contentprovider.interfaces import BeforeUpdateEvent, ContentProviderLookupError, \
    25 from zope.contentprovider.interfaces import BeforeUpdateEvent, ContentProviderLookupError, \
    25     IContentProvider
    26     IContentProvider
    26 from zope.contentprovider.tales import addTALNamespaceData
    27 from zope.contentprovider.tales import addTALNamespaceData
    27 from zope.location.interfaces import ILocation
    28 from zope.location.interfaces import ILocation
    28 
    29 
       
    30 from pyams_utils.factory import is_interface
    29 from pyams_utils.tales import ContextExprMixin
    31 from pyams_utils.tales import ContextExprMixin
    30 
    32 
    31 
    33 
    32 __docformat__ = 'restructuredtext'
    34 __docformat__ = 'restructuredtext'
    33 
    35 
   103             name = match.groups()[0]
   105             name = match.groups()[0]
   104         else:
   106         else:
   105             raise ContentProviderLookupError(name)
   107             raise ContentProviderLookupError(name)
   106 
   108 
   107     registry = request.registry
   109     registry = request.registry
   108     provider = registry.queryMultiAdapter((context, request, view), IContentProvider, name=name)
   110 
       
   111     # we can look into request annotations to check if a provider implementation has already
       
   112     # been provided during traversal; if not, a simple adapter lookup is done
       
   113     provider = request.annotations.get('provider:{}:factory'.format(name))
       
   114     if isinstance(provider, dict):
       
   115         for intf, factory in provider.items():
       
   116             if (is_interface(intf) and intf.providedBy(context)) or \
       
   117                     (inspect.isclass(intf) and isinstance(context, intf)):
       
   118                 provider = factory
       
   119                 break
       
   120         else:
       
   121             provider = None
       
   122     if callable(provider):
       
   123         provider = provider(context, request, view)
       
   124     if provider is None:
       
   125         provider = registry.queryMultiAdapter((context, request, view), IContentProvider,
       
   126                                               name=name)
   109 
   127 
   110     # raise an exception if the provider was not found.
   128     # raise an exception if the provider was not found.
   111     if provider is None:
   129     if provider is None:
   112         raise ContentProviderLookupError(name)
   130         raise ContentProviderLookupError(name)
   113 
   131