Back to index

plone3  3.1.7
portlets.py
Go to the documentation of this file.
00001 from zope.interface import implements
00002 from zope.interface import Interface
00003 from zope.interface import alsoProvides
00004 from zope.interface import providedBy
00005 
00006 from zope.component import adapts
00007 from zope.component import getSiteManager
00008 from zope.component import getUtilitiesFor
00009 from zope.component import queryMultiAdapter
00010 from zope.component import queryUtility
00011 from zope.component import getUtility
00012 
00013 from zope.component.interfaces import IFactory
00014 from zope.component.interfaces import IComponentRegistry
00015 
00016 from zope.schema.interfaces import IField
00017 from zope.schema.interfaces import ICollection
00018 from zope.schema.interfaces import IFromUnicode
00019 
00020 from zope.app.container.interfaces import INameChooser
00021 
00022 from Products.GenericSetup.interfaces import IBody
00023 from Products.GenericSetup.interfaces import ISetupEnviron
00024 
00025 from Products.GenericSetup.utils import XMLAdapterBase
00026 from Products.GenericSetup.utils import _getDottedName
00027 from Products.GenericSetup.utils import _resolveDottedName
00028 
00029 from plone.portlets.interfaces import IPortletType
00030 from plone.portlets.interfaces import IPortletManager
00031 from plone.portlets.interfaces import IPortletManagerRenderer
00032 from plone.portlets.interfaces import ILocalPortletAssignmentManager
00033 from plone.portlets.interfaces import IPortletAssignmentMapping
00034 
00035 from plone.app.portlets.interfaces import IPortletTypeInterface
00036 from plone.app.portlets.utils import assignment_mapping_from_key
00037 
00038 from plone.app.portlets.exportimport.interfaces import IPortletAssignmentExportImportHandler
00039 
00040 from plone.portlets.constants import USER_CATEGORY
00041 from plone.portlets.constants import GROUP_CATEGORY
00042 from plone.portlets.constants import CONTENT_TYPE_CATEGORY
00043 from plone.portlets.constants import CONTEXT_CATEGORY
00044 
00045 from plone.portlets.manager import PortletManager
00046 from plone.portlets.storage import PortletCategoryMapping
00047 from plone.portlets.registration import PortletType
00048 
00049 def dummyGetId():
00050     return ''
00051 
00052 HAS_BLACKLIST = True
00053 try:
00054     from Products.GenericSetup.interfaces import IComponentsHandlerBlacklist
00055 except ImportError:
00056     HAS_BLACKLIST = False
00057 
00058 if HAS_BLACKLIST:
00059     class Blacklist(object):
00060         implements(IComponentsHandlerBlacklist)
00061 
00062         def getExcludedInterfaces(self):
00063             return (_getDottedName(IPortletType),
00064                     _getDottedName(IPortletManager),
00065                     _getDottedName(IPortletManagerRenderer),
00066                     )
00067 
00068 
00069 class PropertyPortletAssignmentExportImportHandler(object):
00070     """Import portlet assignment settings based on zope.schema properties
00071     """
00072     
00073     implements(IPortletAssignmentExportImportHandler)
00074     adapts(Interface)
00075     
00076     def __init__(self, assignment):
00077         self.assignment = assignment
00078         
00079     def import_assignment(self, interface, node):
00080         for child in node.childNodes:
00081             if child.nodeName == 'property':
00082                 self.import_node(interface, child)
00083     
00084     def export_assignment(self, interface, doc, node):
00085         for field_name in interface:
00086             field = interface[field_name]
00087             
00088             if not IField.providedBy(field):
00089                 continue
00090             
00091             child = self.export_field(doc, field)
00092             node.appendChild(child)
00093         
00094     # Helper methods
00095     
00096     def import_node(self, interface, child):
00097         """Import a single <property /> node
00098         """
00099         property_name = child.getAttribute('name')
00100         
00101         field = interface.get(property_name, None)
00102         if field is None:
00103             return
00104         
00105         field = field.bind(self.assignment)
00106         value = None
00107         
00108         # If we have a collection, we need to look at the value_type.
00109         # We look for <element>value</element> child nodes and get the
00110         # value from there
00111         if ICollection.providedBy(field):
00112             value_type = field.value_type
00113             value = []
00114             for element in child.childNodes:
00115                 if element.nodeName != 'element':
00116                     continue
00117                 element_value = self.extract_text(element)
00118                 value.append(self.from_unicode(value_type, element_value))
00119             value = self.field_typecast(field, value)
00120         
00121         # Otherwise, just get the value of the <property /> node
00122         else:
00123             value = self.extract_text(child)
00124             value = self.from_unicode(field, value)
00125             
00126         field.validate(value)
00127         field.set(self.assignment, value)
00128         
00129     def export_field(self, doc, field):
00130         """Turn a zope.schema field into a node and return it
00131         """
00132         field = field.bind(self.assignment)
00133         value = field.get(self.assignment)
00134         
00135         child = doc.createElement('property')
00136         child.setAttribute('name', field.__name__)
00137         
00138         if value is not None:
00139             if ICollection.providedBy(field):
00140                 for e in value:
00141                     list_element = doc.createElement('element')
00142                     list_element.appendChild(doc.createTextNode(str(e)))
00143             else:
00144                 child.appendChild(doc.createTextNode(unicode(value)))
00145             
00146         return child
00147         
00148     def extract_text(self, node):
00149         node.normalize()
00150         text = u""
00151         for child in node.childNodes:
00152             if child.nodeType == node.TEXT_NODE:
00153                 text += child.nodeValue
00154         return text
00155         
00156     def from_unicode(self, field, value):
00157         
00158         # XXX: Bool incorrectly omits to declare that it implements
00159         # IFromUnicode, even though it does.
00160         import zope.schema
00161         if IFromUnicode.providedBy(field) or isinstance(field, zope.schema.Bool):
00162             return field.fromUnicode(value)
00163         else:
00164             return self.field_typecast(field, value)
00165     
00166     def field_typecast(self, field, value):
00167         # A slight hack to force sequence types to the right type
00168         typecast = getattr(field, '_type', None)
00169         if typecast is not None:
00170             if not isinstance(typecast, (list, tuple)):
00171                 typecast = (typecast,)
00172             for tc in reversed(typecast):
00173                 if callable(tc):
00174                     try:
00175                         value = tc(value)
00176                         break
00177                     except:
00178                         pass
00179         return value
00180 
00181 class PortletsXMLAdapter(XMLAdapterBase):
00182     """In- and exporter for a local portlet configuration
00183     """
00184     implements(IBody)
00185     adapts(IComponentRegistry, ISetupEnviron)
00186     
00187     name = 'portlets'
00188     _LOGGER_ID = 'portlets'
00189     
00190     #
00191     # Main control flow
00192     #
00193     
00194     def _exportNode(self):
00195         """Export portlet managers and portlet types
00196         """
00197         node = self._doc.createElement('portlets')
00198         node.appendChild(self._extractPortlets())
00199         self._logger.info('Portlets exported')
00200         return node
00201 
00202     def _importNode(self, node):
00203         """Import portlet managers, portlet types and portlet assignments 
00204         """
00205         self._initProvider(node)
00206         self._logger.info('Portlets imported')
00207 
00208     def _initProvider(self, node):
00209         purge = self.environ.shouldPurge()
00210         if node.hasAttribute('purge'):
00211             purge = self._convertToBoolean(node.getAttribute('purge'))
00212         if purge:
00213             self._purgePortlets()
00214         self._initPortlets(node)
00215     
00216     # 
00217     # Purge
00218     # 
00219 
00220     def _purgePortlets(self):
00221         """Unregister all portlet managers and portlet types, and remove
00222         portlets assigned to the site root
00223         """
00224         
00225         # Purge portlet types
00226         
00227         registeredPortletTypes = [r.name for r in self.context.registeredUtilities()
00228                                         if r.provided == IPortletType]
00229                                     
00230         for name, portletType in getUtilitiesFor(IPortletType):
00231             if name in registeredPortletTypes:
00232                 self.context.unregisterUtility(provided=IPortletType, name=name)
00233         
00234         # Purge portlets assigned to the site root
00235         site = self.environ.getSite()
00236         
00237         for name, portletManager in getUtilitiesFor(IPortletManager):
00238             assignable = queryMultiAdapter((site, portletManager), IPortletAssignmentMapping)
00239             if assignable is not None:
00240                 for key in list(assignable.keys()):
00241                     del assignable[key]
00242 
00243         # Purge portlet manager registrations - this will also get rid of
00244         # global portlet registrations, since these utilities disappear
00245         
00246         portletManagerRegistrations = [r for r in self.context.registeredUtilities()
00247                                         if r.provided.isOrExtends(IPortletManager)]
00248         
00249         for registration in portletManagerRegistrations:
00250             self.context.unregisterUtility(provided=registration.provided,
00251                                            name=registration.name)
00252         
00253     #
00254     # Importing
00255     # 
00256         
00257     def _initPortlets(self, node):
00258         """Actually import portlet data
00259         """
00260         
00261         site = self.environ.getSite()
00262         
00263         registeredPortletTypes = [r.name for r in self.context.registeredUtilities()
00264                                     if r.provided == IPortletType]
00265                                         
00266         registeredPortletManagers = [r.name for r in self.context.registeredUtilities()
00267                                         if r.provided.isOrExtends(IPortletManager)]
00268         
00269         for child in node.childNodes:
00270             # Portlet managers
00271             if child.nodeName.lower() == 'portletmanager':
00272                 self._initPortletManagerNode(child)
00273             elif child.nodeName.lower() == 'portlet':
00274                 self._initPortletNode(child)
00275             # Portlet assignments                                
00276             elif child.nodeName.lower() == 'assignment':
00277                 self._initAssignmentNode(child)
00278             # Blacklisting (portlet blocking/unblocking)
00279             elif child.nodeName.lower() == 'blacklist':
00280                 self._initBlacklistNode(child)
00281         
00282     def _initPortletManagerNode(self, node):
00283         """Create a portlet manager from a node
00284         """
00285         name = str(node.getAttribute('name'))
00286         
00287         if node.hasAttribute('remove'):
00288             if self._convertToBoolean(node.getAttribute('remove')):
00289                 self.context.unregisterUtility(provided=IPortletManager,
00290                                                name=name)
00291                 return
00292 
00293         if node.hasAttribute('purge'):
00294             if self._convertToBoolean(node.getAttribute('purge')):
00295                 manager = getUtility(IPortletManager, name=name)
00296                 # remove global assignments
00297                 for category in manager.keys():
00298                     for portlet in manager[category].keys():
00299                         del manager[category][portlet]
00300                 # remove assignments from root
00301                 site = self.environ.getSite()
00302                 mapping = queryMultiAdapter((site, manager), IPortletAssignmentMapping)
00303                 for portlet in mapping.keys():
00304                     del mapping[portlet]
00305                 return
00306 
00307         registeredPortletManagers = [r.name for r in self.context.registeredUtilities()
00308                                         if r.provided.isOrExtends(IPortletManager)]
00309         if name not in registeredPortletManagers:
00310             managerClass = node.getAttribute('class')
00311             if managerClass:
00312                 manager = _resolveDottedName(managerClass)()
00313             else:
00314                 manager = PortletManager()
00315         
00316             managerType = node.getAttribute('type')
00317             if managerType:
00318                  alsoProvides(manager, _resolveDottedName(managerType))
00319         
00320             manager[USER_CATEGORY] = PortletCategoryMapping()
00321             manager[GROUP_CATEGORY] = PortletCategoryMapping()
00322             manager[CONTENT_TYPE_CATEGORY] = PortletCategoryMapping()
00323         
00324             self.context.registerUtility(component=manager,
00325                                          provided=IPortletManager,
00326                                          name=name)
00327     
00328     def _initPortletNode(self, node):
00329         """Create a portlet type from a node
00330         """
00331         registeredPortletTypes = [
00332           r.name for r in self.context.registeredUtilities() \
00333           if r.provided == IPortletType
00334           ]
00335         addview = str(node.getAttribute('addview'))
00336         extend = node.hasAttribute('extend')
00337         purge = node.hasAttribute('purge')
00338         
00339         #In certain cases, continue to the next node
00340         if node.hasAttribute('remove'):
00341             self._removePortlet(name=addview)
00342             return
00343         if self._checkBasicPortletNodeErrors(node, registeredPortletTypes):
00344             return
00345 
00346         #Retrieve or create the portlet type and determine the current list
00347         #of associated portlet manager interfaces (for_)
00348         if extend:
00349             #To extend a portlet type that is registered, we modify the title
00350             #and description if provided by the profile.
00351             portlet = queryUtility(IPortletType, name = addview)
00352             if str(node.getAttribute('title')):
00353                  portlet.title = str(node.getAttribute('title'))
00354             if str(node.getAttribute('description')):
00355                  portlet.description = str(node.getAttribute('description'))
00356             for_ = portlet.for_
00357         else:
00358              #Otherwise, create a new portlet type with the correct attributes.
00359              portlet = PortletType()
00360              portlet.title = str(node.getAttribute('title'))
00361              portlet.description = str(node.getAttribute('description'))
00362              portlet.addview = addview
00363              for_ = []
00364 
00365         #BBB - to cover old-style for_ attributes that equal None or a
00366         #single interface
00367         for_ = self._BBB_for(for_)
00368 
00369         #Process the node's child "for" nodes to add or remove portlet
00370         #manager interface names to the for_ list
00371         for_ = self._modifyForList(node, for_)
00372         
00373         #Store the for_ attribute, with [Interface] as the default
00374         if for_ == []:
00375             for_ = [Interface]
00376         portlet.for_ = for_
00377         
00378         if purge:
00379             self._removePortlet(addview)
00380         if not extend:
00381             self.context.registerUtility(component=portlet,
00382                                          provided=IPortletType,
00383                                          name=addview)
00384 
00385     def _initAssignmentNode(self, node):
00386         """Create an assignment from a node
00387         """
00388         site = self.environ.getSite()
00389         
00390         # 1. Determine the assignment mapping and the name
00391         manager = node.getAttribute('manager')
00392         category = node.getAttribute('category')
00393         key = node.getAttribute('key')
00394         #convert unicode to str as unicode paths are not allowed in restrictedTraverse called in assignment_mapping_from_key 
00395         key = key.encode()
00396         
00397         purge = False
00398         if node.hasAttribute('purge'):
00399             purge = self._convertToBoolean(node.getAttribute('purge'))
00400 
00401         mapping = assignment_mapping_from_key(site, manager, category, key, create=True)
00402         
00403         # 2. Either find or create the assignment
00404         
00405         assignment = None
00406         name = node.getAttribute('name')
00407         if name:
00408             assignment = mapping.get(name, None)
00409 
00410         if node.hasAttribute('remove'):
00411             if assignment is not None:
00412                 del mapping[name]
00413             return
00414 
00415         if purge:
00416             for portlet in mapping.keys():
00417                 del mapping[portlet]
00418             return
00419 
00420         type_ = node.getAttribute('type')
00421 
00422         if assignment is None:
00423             portlet_factory = getUtility(IFactory, name=type_)
00424             assignment = portlet_factory()
00425             
00426             if not name:
00427                 chooser = INameChooser(mapping)
00428                 name = chooser.chooseName(None, assignment)
00429             
00430             mapping[name] = assignment
00431 
00432         # aq-wrap it so that complex fields will work
00433         assignment = assignment.__of__(site)
00434 
00435         # 3. Use an adapter to update the portlet settings
00436         
00437         portlet_interface = getUtility(IPortletTypeInterface, name=type_)
00438         assignment_handler = IPortletAssignmentExportImportHandler(assignment)
00439         assignment_handler.import_assignment(portlet_interface, node)
00440 
00441         # 4. Handle ordering
00442         
00443         insert_before = node.getAttribute('insert-before')
00444         if insert_before:
00445             position = None
00446             keys = list(mapping.keys())
00447             
00448             if insert_before == "*":
00449                 position = 0
00450             elif insert_before in keys:
00451                 position = keys.index(insert_before)
00452             
00453             if position is not None:
00454                 keys.remove(name)
00455                 keys.insert(position, name)
00456                 mapping.updateOrder(keys)
00457         
00458     def _initBlacklistNode(self, node):
00459         """Create a blacklisting from a node
00460         """
00461         site = self.environ.getSite()
00462         
00463         manager = node.getAttribute('manager')
00464         category = node.getAttribute('category')
00465         location = str(node.getAttribute('location'))
00466         status = node.getAttribute('status')
00467         
00468         manager = getUtility(IPortletManager, name=manager)
00469         
00470         if location.startswith('/'):
00471             location = location[1:]
00472         
00473         item = site.unrestrictedTraverse(location, None)
00474         if item is None:
00475             return
00476             
00477         assignable = queryMultiAdapter((item, manager), ILocalPortletAssignmentManager)
00478         
00479         if status.lower() == 'block':
00480             assignable.setBlacklistStatus(category, True)
00481         elif status.lower() == 'show':
00482             assignable.setBlacklistStatus(category, False)
00483         elif status.lower() == 'acquire':
00484             assignable.setBlacklistStatus(category, None)
00485         
00486 
00487     #
00488     # Exporting
00489     # 
00490     
00491     def _extractPortlets(self):
00492         """Write portlet managers and types to XML
00493         """
00494         fragment = self._doc.createDocumentFragment()
00495         site = self.environ.getSite()
00496         
00497         registeredPortletTypes = [r.name for r in self.context.registeredUtilities()
00498                                             if r.provided == IPortletType]
00499         portletManagerRegistrations = [r for r in self.context.registeredUtilities()
00500                                             if r.provided.isOrExtends(IPortletManager)]
00501         
00502         portletSchemata = dict([(iface, name,) for name, iface in getUtilitiesFor(IPortletTypeInterface)])
00503         
00504         # Export portlet manager registrations
00505         
00506         for r in portletManagerRegistrations:
00507             fragment.appendChild(self._extractPortletManagerNode(r))
00508 
00509         # Export portlet type registrations
00510             
00511         for name, portletType in getUtilitiesFor(IPortletType):
00512             if name in registeredPortletTypes:
00513                 fragment.appendChild(self._extractPortletNode(name, portletType))
00514 
00515         def extractMapping(manager_name, category, key, mapping):
00516             for name, assignment in mapping.items():                        
00517                 type_ = None
00518                 for schema in providedBy(assignment).flattened():
00519                     type_ = portletSchemata.get(schema, None)
00520                     if type_ is not None:
00521                         break
00522                 
00523                 if type_ is not None:
00524                     child = self._doc.createElement('assignment')
00525                     child.setAttribute('manager', manager_name)
00526                     child.setAttribute('category', category)
00527                     child.setAttribute('key', key)
00528                     child.setAttribute('type', type_)
00529                     child.setAttribute('name', name)
00530                 
00531                     assignment = assignment.__of__(mapping)
00532                     handler = IPortletAssignmentExportImportHandler(assignment)
00533                     handler.export_assignment(schema, self._doc, child)
00534                     fragment.appendChild(child)
00535 
00536         # Export assignments in the global categories
00537         for category in (USER_CATEGORY, GROUP_CATEGORY, CONTENT_TYPE_CATEGORY,):
00538             for manager_name, manager in getUtilitiesFor(IPortletManager):
00539                 for key, mapping in manager.get(category, {}).items():
00540                     mapping = mapping.__of__(site)
00541                     extractMapping(manager_name, category, key, mapping)
00542                     
00543 
00544         # Export assignments at the root of the portal (only)
00545         for manager_name, manager in getUtilitiesFor(IPortletManager):
00546              mapping = queryMultiAdapter((site, manager), IPortletAssignmentMapping)
00547              mapping = mapping.__of__(site)
00548              extractMapping(manager_name, CONTEXT_CATEGORY, u"/", mapping)
00549 
00550         # Export blacklistings in the portal root        
00551         for manager_name, manager in getUtilitiesFor(IPortletManager):
00552             assignable = queryMultiAdapter((site, manager), ILocalPortletAssignmentManager)       
00553             if assignable is None:
00554                 continue
00555             for category in (USER_CATEGORY, GROUP_CATEGORY, CONTENT_TYPE_CATEGORY, CONTEXT_CATEGORY,):
00556                 child = self._doc.createElement('blacklist')
00557                 child.setAttribute('manager', manager_name)
00558                 child.setAttribute('category', category)
00559                 child.setAttribute('location', u"/")
00560             
00561                 status = assignable.getBlacklistStatus(category)
00562                 if status == True:
00563                     child.setAttribute('status', u'block')
00564                 elif status == False:
00565                     child.setAttribute('status', u'show')
00566                 else:
00567                     child.setAttribute('status', u'acquire')
00568                     
00569                 fragment.appendChild(child)
00570 
00571         return fragment
00572         
00573     def _extractPortletManagerNode(self, portletManagerRegistration):
00574         r = portletManagerRegistration
00575         child = self._doc.createElement('portletmanager')
00576         if r.component.__class__ is not PortletManager:
00577             child.setAttribute('class', _getDottedName(r.component.__class__))
00578         child.setAttribute('name', r.name)
00579         
00580         specificInterface = providedBy(r.component).flattened().next()
00581         if specificInterface != IPortletManager:
00582             child.setAttribute('type', _getDottedName(specificInterface))
00583         
00584         return child
00585     
00586     def _extractPortletNode(self, name, portletType):
00587         child = self._doc.createElement('portlet')
00588         child.setAttribute('addview', portletType.addview)
00589         child.setAttribute('title', portletType.title)
00590         child.setAttribute('description', portletType.description)
00591         
00592         for_ = portletType.for_
00593         #BBB
00594         for_ = self._BBB_for(for_)
00595         
00596         if for_ and for_ != [Interface]:
00597             for i in for_:
00598                 subNode = self._doc.createElement('for')
00599                 subNode.setAttribute('interface', _getDottedName(i))
00600                 child.appendChild(subNode)
00601         return child
00602         
00603     #
00604     # Helper methods
00605     # 
00606 
00607     def _checkBasicPortletNodeErrors(self, node, registeredPortletTypes):
00608         addview = str(node.getAttribute('addview'))
00609         extend = node.hasAttribute('extend')
00610         purge = node.hasAttribute('purge')
00611         exists = addview in registeredPortletTypes
00612         
00613         if extend and purge:
00614             self._logger.warning('Cannot extend and purge the same ' \
00615               'portlet type %s!' % addview)
00616             return True
00617         if extend and not exists:
00618             self._logger.warning('Cannot extend portlet type ' \
00619               '%s because it is not registered.' % addview)
00620             return True
00621         if exists and not purge and not extend:
00622             self._logger.warning('Cannot register portlet type ' \
00623               '%s because it is already registered.' % addview)
00624             return True
00625         
00626         return False
00627 
00628     def _removePortlet(self, name):
00629         if queryUtility(IPortletType, name=name):
00630             self.context.unregisterUtility(provided=IPortletType, name=name)
00631             return True
00632         else:
00633             self._logger.warning('Unable to unregister portlet type ' \
00634               '%s because it is not registered.' % name)
00635             return False
00636 
00637     def _modifyForList(self, node, for_):
00638         """Examine the "for_" nodes within a "portlet" node to populate,
00639         extend, and/or remove interface names from an existing list for_
00640         """
00641         modified_for = [_getDottedName(i) for i in for_]
00642          
00643         for subNode in node.childNodes:
00644             if subNode.nodeName.lower() == 'for':
00645                 interface_name = str(
00646                   subNode.getAttribute('interface')
00647                   )
00648                 if subNode.hasAttribute('remove'):
00649                     if interface_name in modified_for:
00650                         modified_for.remove(interface_name)
00651                     else:
00652                         addview = str(node.getAttribute('addview'))
00653                         self._logger.warning('Portlet type %s ' % addview + \
00654                           'is already not registered as addable to ' + \
00655                           'portlet managers with interface ' + \
00656                           '%s.' % interface_name)
00657                 elif interface_name not in modified_for:
00658                     modified_for.append(interface_name)
00659                 else:
00660                     addview = str(node.getAttribute('addview'))
00661                     self._logger.warning('Portlet type %s is ' % addview + \
00662                       'already registered as addable to portlet managers ' \
00663                       'with interface %s.' % interface_name)
00664         
00665         #BBB
00666         interface_name = str(node.getAttribute('for'))
00667         if interface_name:
00668             self._logger.warning('Deprecation Warning The "for" ' + \
00669               'attribute of the portlet node in portlets.xml is ' + \
00670               'deprecated and will be removed in Plone 4.0. Use children ' \
00671               'nodes of the form <for interface="foo.BarInterface" /> ' + \
00672               'instead.')
00673             modified_for.append(interface_name)
00674         
00675         modified_for = [_resolveDottedName(name) for name in modified_for \
00676           if _resolveDottedName(name) is not None] 
00677         
00678         return modified_for
00679     
00680     #BBB
00681     def _BBB_for(self, for_):
00682         if for_ is None:
00683             return [Interface]
00684         if type(for_) not in (tuple, list):
00685             return [for_]
00686         return for_
00687 
00688 def importPortlets(context):
00689     """Import portlet managers and portlets
00690     """
00691     sm = getSiteManager(context.getSite())
00692     if sm is None or not IComponentRegistry.providedBy(sm):
00693         logger = context.getLogger('portlets')
00694         logger.info("Can not register components - no site manager found.")
00695         return
00696 
00697     # This code was taken from GenericSetup.utils.import.importObjects
00698     # and slightly simplified. The main difference is the lookup of a named
00699     # adapter to make it possible to have more than one handler for the same
00700     # object, which in case of a component registry is crucial.
00701     importer = queryMultiAdapter((sm, context), IBody, name=u'plone.portlets')
00702     if importer:
00703         filename = '%s%s' % (importer.name, importer.suffix)
00704         body = context.readDataFile(filename)
00705         if body is not None:
00706             importer.filename = filename # for error reporting
00707             importer.body = body
00708 
00709 def exportPortlets(context):
00710     """Export portlet managers and portlets
00711     """
00712     sm = getSiteManager(context.getSite())
00713     if sm is None or not IComponentRegistry.providedBy(sm):
00714         logger = context.getLogger('portlets')
00715         logger.info("Nothing to export.")
00716         return
00717 
00718     # This code was taken from GenericSetup.utils.import.exportObjects
00719     # and slightly simplified. The main difference is the lookup of a named
00720     # adapter to make it possible to have more than one handler for the same
00721     # object, which in case of a component registry is crucial.
00722     exporter = queryMultiAdapter((sm, context), IBody, name=u'plone.portlets')
00723     if exporter:
00724         filename = '%s%s' % (exporter.name, exporter.suffix)
00725         body = exporter.body
00726         if body is not None:
00727             context.writeDataFile(filename, body, exporter.mime_type)