Back to index

plone3  3.1.7
metaconfigure.py
Go to the documentation of this file.
00001 from zope.interface import Interface, alsoProvides
00002 
00003 from zope.publisher.interfaces.browser import IDefaultBrowserLayer
00004 from zope.publisher.interfaces.browser import IBrowserView
00005 
00006 from plone.portlets.interfaces import IPortletManager
00007 from plone.portlets.interfaces import IPortletRenderer
00008 
00009 from plone.app.portlets.interfaces import IPortletTypeInterface
00010 from plone.app.portlets.browser.interfaces import IPortletAdding
00011 
00012 from zope.component.zcml import adapter
00013 from zope.component.zcml import utility
00014 
00015 from zope.component.interfaces import IFactory
00016 from zope.component.factory import Factory
00017 
00018 from Products.Five.metaclass import makeClass
00019 from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
00020 from Products.Five.browser.metaconfigure import page
00021 
00022 # Keep track of which renderers we've registered so that we can artifically
00023 # subclass them in portletRendererDirective. Yes, this is evil.
00024 _default_renderers = {}
00025 
00026 def portletDirective(_context, name, interface, assignment, renderer, addview,
00027         view_permission=u"zope2.View", edit_permission="plone.app.portlets.ManageOwnPortlets", editview=None):
00028     """Register a portlet assignment type using typical options. 
00029     
00030     Portlets that consist of a simple assignment class deriving form 
00031     base.Assignment, a renderer deriving from base.Renderer, an addview
00032     using formlib and deriving from base.AddForm and an editview (optional)
00033     using formlib and deriving from base.EditForm, can use this directive
00034     to avoid having to regiter each of those components individually.
00035     
00036     In addition, we register the portlet interface using IPortletTypeInterface
00037     and an IFactory utility, in order to help the GenericSetup handler and
00038     other generic code instantiate portlets.
00039     """
00040 
00041     # Register the portlet interface as named utility so that we can find it
00042     # again (in the GS handler)
00043     
00044     alsoProvides(interface, IPortletTypeInterface)
00045     utility(_context, 
00046             provides=IPortletTypeInterface,
00047             name=name,
00048             component=interface)
00049             
00050     # Register a factory
00051     
00052     utility(_context,
00053             provides=IFactory,
00054             name=name,
00055             component=Factory(assignment))
00056 
00057     # Set permissions on the assignment class
00058     
00059     # <class class="[assignment]">
00060     #   <require 
00061     #       permission="[view_permission]"
00062     #       interface="[interface]"
00063     #       />
00064     # </class>
00065     
00066     # XXX: Is this necessary? The renderer doesn't need it, so it may
00067     # just be superfluous.
00068     
00069     # Register the renderer:
00070     
00071     # <adapter 
00072     #   factory="[renderer]"
00073     #   for="zope.interface.Interface
00074     #        zope.publisher.interfaces.browser.IDefaultBrowserLayer
00075     #        zope.publisher.interfaces.browser.IBrowserView
00076     #        plone.portlets.interfaces.IPortletManager
00077     #        [interface]
00078     #   provides="plone.portlets.interfaces.IPortletRenderer"
00079     #   />
00080     
00081     adapter(_context, (renderer,), provides=IPortletRenderer,
00082             for_=(Interface, IDefaultBrowserLayer, IBrowserView, IPortletManager, interface,))
00083     _default_renderers[interface] = renderer
00084     
00085     # Register the adding view
00086     
00087     # <browser:page 
00088     #   for="plone.app.portlets.browser.interfaces.IPortletAdding"
00089     #   name="[name]"
00090     #   class="[addview]"
00091     #   permission="[edit_permission]"
00092     #   />
00093     
00094     page(_context, 
00095          for_=IPortletAdding,
00096          name=name,
00097          class_=addview,
00098          permission=edit_permission)
00099     
00100     # Register the edit view, if applicable
00101     
00102     # <browser:page 
00103     #   for="[interface]"
00104     #   name="edit"
00105     #   class="[editview]"
00106     #   permission="[edit_permission]"
00107     #   />
00108     
00109     if editview is not None:
00110         page(_context, 
00111              for_=interface,
00112              name=u"edit",
00113              class_=editview,
00114              permission=edit_permission)
00115              
00116 def portletRendererDirective(_context, portlet, class_=None, template=None,
00117         for_=Interface, layer=IDefaultBrowserLayer, view=IBrowserView, manager=IPortletManager):
00118     """Register a custom/override portlet renderer
00119     """
00120     
00121     if class_ is None and template is None:
00122         raise TypeError("Either 'template' or 'class' must be given")
00123     if class_ is not None and template is not None:
00124         raise TypeError("'template' and 'class' cannot be specified at the same time")
00125     
00126     if template is not None:
00127         
00128         # Look up the default renderer for this portlet
00129         base_class = _default_renderers.get(portlet, None)
00130         if base_class is None:
00131             raise TypeError("Can't find default renderer for %s. "
00132                             "Perhaps the portlet has not been registered yet?" % portlet.__identifier__)
00133 
00134         # Generate a subclass with 'renderer' using this template
00135         class_ = makeClass("PortletRenderer from %s" % template, 
00136                             (base_class,), {'render' : ViewPageTemplateFile(template)})
00137     
00138     adapter(_context, (class_,), provides=IPortletRenderer,
00139                 for_=(for_, layer, view, manager, portlet,))