Back to index

plone3  3.1.7
interfaces.py
Go to the documentation of this file.
00001 from zope.interface import Interface, Attribute
00002 from zope import schema
00003 
00004 from zope.annotation.interfaces import IAttributeAnnotatable
00005 
00006 from zope.app.container.interfaces import IContained
00007 from zope.app.container.interfaces import IContainer
00008 from zope.app.container.interfaces import IOrderedContainer
00009 from zope.app.container.interfaces import IContainerNamesContainer
00010 
00011 from zope.app.container.constraints import containers, contains
00012 from zope.contentprovider.interfaces import IContentProvider
00013 
00014 # Context - the application layer must provide these    
00015 
00016 class ILocalPortletAssignable(IAttributeAnnotatable):
00017     """Marker interface for content objects that want to have local portlet
00018     assignments.
00019     """
00020 
00021 class IPortletContext(Interface):
00022     """A context in which portlets may be rendered.
00023     
00024     No default implementation exists for this interface - it must be provided
00025     by the application in order to tell the portlets infrastructure how to
00026     render portlets.
00027     """
00028     
00029     uid = schema.TextLine(title=u"A unique id or path for this specific context",
00030                           required=True)
00031     
00032     def getParent():
00033         """Get the portlet parent of the current context.
00034         
00035         This is used to aggregate portlets by walking up the content hierarchy.
00036         
00037         This should be adaptable to IPortletContext. If there is no portlet
00038         parent (e.g. this is the site root), return None.
00039         """
00040     
00041     def globalPortletCategories(placeless=False):
00042         """Get global portlet key-value pairs, in order.
00043         
00044         When rendered, a portlet manger (column) will be filled first by
00045         contextual portlets (if the context and/or its parents provide
00046         ILocalPortletAssignable), and then by global portlets. Global portlet
00047         assignments may include portlets per user, per group, or per content
00048         type.
00049         
00050         This function should return a tuple of tuples where each inner tuple
00051         contains a category such as 'user' or 'group' and the key to use in
00052         this category. 
00053         
00054         For example, if the current content object is a 'Document', the current 
00055         user is 'fred' and he is a member of 'group1' and 'group2', this may
00056         be:
00057         
00058         (('content_type', 'Documment'),
00059          ('user', 'fred',),
00060          ('group', 'group1',),
00061          ('group', 'group2',),)
00062          
00063         In this case, all contextual portlets may be rendered first, followed
00064         by all global portlets in the content_type category assigned to 
00065         'Document', followed by user portlets for 'fred' and group portlets for
00066         'group1' and then 'group2'.
00067         
00068         If ``placeless`` is True, the categories should only include those 
00069         which are independent of the specific location. In this case, that
00070         may mean that the 'content_type' category is excluded.
00071         """
00072         
00073 # Utility interface for registrations of available portlets
00074 
00075 class IPortletType(Interface):
00076     """A registration for a portlet type.
00077     
00078     Each new type of portlet should register a utility with a unique name
00079     providing IPortletType, so that UI can find them.
00080     """
00081     
00082     title = schema.TextLine(
00083         title = u'Title',
00084         required = True)
00085    
00086     description = schema.Text(
00087         title = u'Description',
00088         required = False)
00089 
00090     addview = schema.TextLine(
00091         title = u'Add view',
00092         description = u'The name of the add view for assignments for this portlet type',
00093         required = True)
00094                 
00095     for_ = Attribute('An interface a portlet manager must have to allow this type of portlet. ' \
00096                       'May be None if there are no restrictions.')
00097         
00098 # Generic marker interface - a portlet may reference one of these
00099 
00100 class IPortletDataProvider(Interface):
00101     """A marker interface for objects providing portlet data.
00102     
00103     This can be used as a marker by implementations requiring a regular content 
00104     object to be able to be "switched on" as a portlet. Alternatively, a more
00105     specific sub-interface can provide the necessary information to render
00106     the portlet.
00107     
00108     An adapter should exist from the specific type of IPortletDataProvider to 
00109     an appropriate IPortletViewlet to render it.
00110     
00111     The data provider will also be referenced in an IPortletAssignment so that
00112     it can be retrieved on demand.
00113     """
00114 
00115 # Portlet assignment - new types of portlets may need one of these
00116 
00117 class IPortletAssignment(IContained):
00118     """Assignment of a portlet to a given portlet manager relative to a 
00119     context, user or group.
00120     
00121     Implementations of this interface will typically be persistent, stored in
00122     an IPortletStorage.
00123     
00124     The 'data' attribute may be implemented as a property that retrieves the
00125     data object on-demand.
00126     
00127     Portlet assignments are contained in and will have their __name__ attribute
00128     managed by an IPortletContextMapping, which in turn are stored inside 
00129     IPortletStorages.
00130     """
00131     
00132     title = schema.Bool(title=u'Title',
00133                         description=u'The title of this assignment as displayed to the user',
00134                         required=True)
00135         
00136     available = schema.Bool(title=u'Available',
00137                             description=u'Whether or not this portlet should be rendered',
00138                             required=True,
00139                             readonly=True)
00140     
00141     data = Attribute(u'Portlet data object')
00142     
00143 # A content provider capable of rendering portlets - each type of portlet will
00144 # need one of these
00145     
00146 class IPortletRenderer(IContentProvider):
00147     """A special implementation of a content provider which is managed
00148     by an IPortletManager.
00149     
00150     Any object providing IPortletDataProvider should be adaptable to 
00151     IPortletRenderer in order to be renderable as a portlet. (In fact,
00152     the return value of IPortletAssignment.data needs to have such an
00153     adapter, regardless of whether it actually implements IPortletDataProvider)
00154     """
00155     
00156     available = schema.Bool(title=u'Available',
00157                             description=u'Whether or not this portlet shuld be rendered',
00158                             required=True,
00159                             readonly=True)
00160     
00161 # Discovery of portlets
00162 
00163 class IPortletRetriever(Interface):
00164     """A component capable of discovering portlets assigned to it for rendering.
00165     
00166     Typically, a content object and an IPortletManager will be multi-
00167     adapted to IPortletRetriever.
00168     """
00169 
00170     def getPortlets():
00171         """Return a list of IPortletAssignment's to be rendered.
00172         
00173         Returns a list of dicts with keys 'assignment', containing the actual
00174         assignment object; 'category', containing the category the 
00175         assignment came from; 'key', being the key within this category; and
00176         'name' being the name of the assignment.
00177         """
00178 
00179 # Portlet managment
00180 
00181 class IPortletStorage(IContainer):
00182     """A component for storing global (site-wide) portlet assignments.
00183     
00184     This manages one IPortletCategoryMapping for each category of portlet, 
00185     e.g. 'user' or 'group' (the exact keys are up to the application layer).
00186     
00187     Some common keys are found in plone.portlets.constants.
00188     """
00189     contains('plone.portlets.interfaces.IPortletCategoryMapping')            
00190 
00191 class IPortletCategoryMapping(IContainer, IContained):
00192     """A mapping of the portlets assigned to a particular categories under
00193     various keys.
00194     
00195     This manages one IPortletAssignmentMapping for each key. For example,
00196     if this is the 'user' category, the keys could be user ids, each of
00197     which would be given a particular IPortletAssignmentMapping.
00198     """
00199     contains('plone.portlets.interfaces.IPortletAssignmentMapping')
00200 
00201 class IPortletAssignmentMapping(IOrderedContainer, IContainerNamesContainer, IContained):
00202     """A storage for portlet assignments.
00203     
00204     An IPortletCategoryMapping manages one of these for each category of 
00205     context. It may also be stored in an annotation on an object to manage
00206     portlets assigned to that object. In this case, a multi-adapter from
00207     ILocalPortletAssignable and IPortletManager will be able to obtain the
00208     appropriate container.
00209     """
00210     contains('plone.portlets.interfaces.IPortletAssignment')
00211     
00212     __manager__ = schema.TextLine(title=u"Name of the portlet manager this mapping belongs to")
00213     __category__ = schema.TextLine(title=u'Name of the category this mapping belongs to')
00214     
00215 
00216 class ILocalPortletAssignmentManager(Interface):
00217     """A component that can manage the display of locally assigned portlets.
00218     
00219     An ILocalPortletAssignable may be multi-adapted along with
00220     an IPortletManager to this interface, to manage how portlets will be
00221     displayed relative to this context.
00222     """
00223     
00224     def setBlacklistStatus(category, status):
00225         """Manage the blacklisting status of the given category.
00226         
00227         If status is None, the blacklist status will be obtained from a parent,
00228         defaulting to False. If status is False, the given portlet category 
00229         will always be eligible for display. If status is True, the given
00230         portlet category will always be blocked.
00231         
00232         Thus, call setBlacklistStatus('user', True) to always black out 'user'
00233         portlets in this context, or setBlacklistStatus('user', False) to 
00234         override any blacklisting done by a parent object. Calling
00235         setBlacklistStatus('user', None) will cause the status to be acquired
00236         from the parent instead (defaulting to no blacklisting).
00237         """
00238     
00239     def getBlacklistStatus(category):
00240         """Get the blacklisting status of the given category.
00241         
00242         Note that this only applies to the current context - the status is
00243         not inherited, and will default to None if not set.
00244         """
00245 
00246 class IPortletManager(IPortletStorage, IContained):
00247     """A manager for portlets.
00248     
00249     Typically, objects providing this interface will be persisted and used
00250     to manage portlet assignments. 
00251     """
00252 
00253     def getAddablePortletTypes():
00254         """Get all addable portlet types.
00255         
00256         This is achieved by looking up utilities providing IPortletType and
00257         returning those which either have no for_ attribute (globally addable
00258         portlets) or those which specify an interface available on this
00259         portlet manager instance.
00260         """
00261     
00262     def __call__(context, request, view):
00263         """Act as an adapter factory.
00264         
00265         When called, should return an IPortletManagerRenderer for rendering 
00266         this portlet manager and its portlets.
00267         
00268         The IPortletManager instance will be registered as a site-local
00269         adapter factory that the component architecture will use when it
00270         looks up adapters in the handler for a TAL provider: expression.
00271         
00272         See zope.contentprovider for more.
00273         """
00274 
00275 class IPlacelessPortletManager(IPortletManager):
00276     """A marker interface for managers for placeless portlets.
00277     
00278     A placeless portlet manager is one which does not examine the context
00279     or the context's parent. This is achieved by way of a different adapter
00280     to IPortletRetriever.
00281     """
00282 
00283 class IPortletManagerRenderer(IContentProvider):
00284     """A content provider for rendering a portlet manager.
00285     """
00286     
00287     template = Attribute(
00288         """A page template object to render the manager with.
00289 
00290         If given, this will be passed an option 'portlets' that is a list of
00291         the IPortletRenderer objects to render.
00292         
00293         If not set, the renderers will simply be called one by one, and their
00294         output will be concatenated, separated by newlines.
00295         """)
00296 
00297     visible = schema.Bool(title=u'Visible',
00298                           description=u'Whether or not this portlet manager (column) will be rendered at all',
00299                           required=True,
00300                           default=True)
00301 
00302     def filter(portlets):
00303         """Return a list of portlets to display that is a subset of
00304         the list of portlets passed in. The list contains dicts as returned
00305         by IPortletRetriever.getPortlets().
00306         """
00307         
00308     def portletsToShow():
00309         """Get a list of portlets that will be shown.
00310         
00311         Returns a list of dicts with keys corresponding to that returned by
00312         IPortletRetriever.getPortlets(), with the additional key 'renderer'
00313         containing the appropriate IPortletRenderer.
00314         """
00315 
00316     def safe_render(portlet_renderer):
00317         """Render a portlet in such a way that exceptions are not
00318         raised but rather logged and an error is shown in place of the
00319         portlet.
00320         """