def extract_mapping(manager_name, category, key, mapping): portlets_schemata = dict([ (iface, name) for name, iface in getUtilitiesFor(IPortletTypeInterface) ]) for name, assignment in mapping.items(): type_ = None schema = None for schema in providedBy(assignment).flattened(): type_ = portlets_schemata.get(schema, None) if type_ is not None: break if type_ is not None: child = PrettyDocument().createElement('assignment') child.setAttribute('manager', manager_name) child.setAttribute('category', category) child.setAttribute('key', key) child.setAttribute('type', type_) child.setAttribute('name', name) assignment = assignment.__of__(mapping) settings = IPortletAssignmentSettings(assignment) visible = settings.get('visible', True) child.setAttribute('visible', repr(visible)) handler = IPortletAssignmentExportImportHandler(assignment) handler.export_assignment(schema, PrettyDocument(), child) yield child
def testMigrateStaticTextPortlets(self): class HiddenAssignment(static.Assignment): hide = True self.setRoles(["Manager"]) self.portal.invokeFactory('Folder', id="statictest") folder = self.portal['statictest'] manager = getUtility( IPortletManager, name='plone.rightcolumn', context=folder) assignments = getMultiAdapter( (folder, manager), IPortletAssignmentMapping) hidden_portlet = HiddenAssignment() visible_portlet = static.Assignment() assignments['hidden'] = hidden_portlet assignments['visible'] = visible_portlet migrateStaticTextPortlets(self.portal) self.assertFalse( IPortletAssignmentSettings(hidden_portlet).get( 'visible', True)) self.assertTrue( IPortletAssignmentSettings(visible_portlet).get( 'visible', True))
def test_should_remove_tag_if_context_can_not_be_found(self): portal = self.layer['portal'] rightcol = getUtility(IPortletManager, name=u'plone.rightcolumn', context=portal) right = getMultiAdapter((portal, rightcol,), IPortletAssignmentMapping, context=portal) staticportlet = static.Assignment(header=u"Static Portlet", text=u"TEXT INPUT") right[u'staticportlet'] = staticportlet settings = IPortletAssignmentSettings(staticportlet) visible = settings.get('visible', True) settings['visible'] = False class FakeContent: def UID(self): return '1' page = portal[portal.invokeFactory('Document', 'testpage')] hash = portletHash(rightcol, staticportlet, FakeContent()) field = page.getField('text') portletmarkup = portletMarkup(hash) field.set(page, portletmarkup, mimetype='text/html') page.setTitle('Blah') page.reindexObject() transaction.commit() self.browser.open('http://nohost/plone/testpage') self.failUnless("TEXT INPUT" not in self.browser.contents) self.failUnless('<img class="TINYMCEPORTLET mce-only' not in self.browser.contents)
def toggle_visibility(self, name): assignments = aq_inner(self.context) settings = IPortletAssignmentSettings(assignments[name]) visible = settings.get('visible', True) settings['visible'] = not visible self.request.response.redirect(self._nextUrl()) return ''
def getPortlets(self): if IPortletContext.providedBy(self.context): pcontext = self.context else: pcontext = queryAdapter(self.context, IPortletContext) if pcontext is None: return [] assignments = [] for category, key in pcontext.globalPortletCategories(True): mapping = self.storage.get(category, None) if mapping is not None: for assignment in mapping.get(key, {}).values(): try: settings = IPortletAssignmentSettings(assignment) except Exception: logException(u'Error during retrieving assignment ' 'settings. Context: "%s", Category: "%s", Key: ' '"%s", Assignment Class: "%s", Assignment ID: "%s"' % ('/'.join(self.context.getPhysicalPath()), category, key, str(assignment.__class__), assignment.__name__), context=self.context) continue if not settings.get('visible', True): continue assignments.append({'category': category, 'key': key, 'name': assignment.__name__, 'assignment': assignment }) return assignments
def toggle_visibility(self, name): self.authorize() assignments = aq_inner(self.context) settings = IPortletAssignmentSettings(assignments[name]) visible = settings.get('visible', True) settings['visible'] = not visible return self.finish_portlet_change()
def test_portlet_visibility_settings(self): assignment = self.layer['right_portlets'].get('title2', False) settings = PersistentMapping({'visible': False}) IPortletAssignmentSettings(assignment).data = settings # get the data adapter = getAdapter(self.layer['folder1'], IDataCollector, name="portlet_data_adapter") data = adapter.getData() jsondata = json.dumps(utils.decode_for_json(data)) data = utils.encode_after_json(json.loads(jsondata)) self.assertEqual(settings, data['plone.rightcolumn']['title2']['settings']) # set the data adapter2 = getAdapter(self.layer['folder2'], IDataCollector, name="portlet_data_adapter") adapter2.setData(data, metadata=None) new_assignment = self.layer['right_portlets'].get('title2', False) self.assertEqual(settings, IPortletAssignmentSettings(new_assignment).data)
def extractMapping(manager_name, category, key, mapping): for name, assignment in mapping.items(): type_ = None for schema in providedBy(assignment).flattened(): type_ = portletSchemata.get(schema, None) if type_ is not None: break if type_ is not None: child = self._doc.createElement('assignment') child.setAttribute('manager', manager_name) child.setAttribute('category', category) child.setAttribute('key', key) child.setAttribute('type', type_) child.setAttribute('name', name) assignment = assignment.__of__(mapping) settings = IPortletAssignmentSettings(assignment) visible = settings.get('visible', True) child.setAttribute('visible', repr(visible)) handler = IPortletAssignmentExportImportHandler(assignment) handler.export_assignment(schema, self._doc, child) fragment.appendChild(child)
def getPortlets(self): if IPortletContext.providedBy(self.context): pcontext = self.context else: pcontext = queryAdapter(self.context, IPortletContext) if pcontext is None: return [] assignments = [] for category, key in pcontext.globalPortletCategories(True): mapping = self.storage.get(category, None) if mapping is not None: for assignment in mapping.get(key, {}).values(): try: settings = IPortletAssignmentSettings(assignment) except TypeError: # Portlet does not exist any longer continue else: if not settings.get('visible', True): continue assignments.append({'category': category, 'key': key, 'name': assignment.__name__, 'assignment': assignment }) return assignments
def panels_for_assignments(self, assignments, manager, base_url): # todo: do we use a special cat for panels? category = self.__parent__.category key = self.__parent__.key data = [] for idx in range(len(assignments)): name = assignments[idx].__name__ if hasattr(assignments[idx], '__Broken_state__'): name = assignments[idx].__Broken_state__['__name__'] # Todo: we can define an edit view for panels - for overlay etc. - IF needed... editview = queryMultiAdapter((assignments[idx], self.request), name='edit', default=None) if editview is None: editviewName = '' else: editviewName = '%s/%s/edit' % (base_url, name) panel_hash = hashPortletInfo( dict( manager=manager.__name__, category=category, key=key, name=name, )) try: settings = IPortletAssignmentSettings(assignments[idx]) visible = settings.get('visible', True) except TypeError: visible = False data.append({ 'title': assignments[idx].title, 'editview': editviewName, 'hash': panel_hash, 'name': name, 'up_url': '%s/@@move-panel-up' % (base_url), 'down_url': '%s/@@move-panel-down' % (base_url), 'delete_url': '%s/@@delete-panel' % (base_url), 'duplicate_url': '%s/@@duplicate-panel' % (base_url), 'hide_url': '%s/@@toggle-visibility' % (base_url), 'show_url': '%s/@@toggle-visibility' % (base_url), 'visible': visible, 'has_assignments': len(assignments[idx]), }) if len(data) > 0: data[0]['up_url'] = data[-1]['down_url'] = None return data
def toggle_visibility(self, portlethash, viewname): info = unhashPortletInfo(portlethash) assignments = assignment_mapping_from_key(self.context, info['manager'], info['category'], info['key']) IPortletPermissionChecker(assignments.__of__(aq_inner(self.context)))() assignment = assignments[info['name']] settings = IPortletAssignmentSettings(assignment) visible = settings.get('visible', True) settings['visible'] = not visible return self._render_column(info, viewname)
def portlets_for_assignments(self, assignments, manager, base_url): category = self.__parent__.category key = self.__parent__.key data = [] for idx in range(len(assignments)): name = assignments[idx].__name__ if hasattr(assignments[idx], '__Broken_state__'): name = assignments[idx].__Broken_state__['__name__'] editview = queryMultiAdapter((assignments[idx], self.request), name='edit', default=None) if editview is None: editviewName = '' else: editviewName = '%s/%s/edit' % (base_url, name) settingsviewName = '%s/%s/edit-portlet-metadata' % (base_url, name) portlet_hash = hashPortletInfo( dict( manager=manager.__name__, category=category, key=key, name=name, )) try: settings = IPortletAssignmentSettings(assignments[idx]) visible = settings.get('visible', True) except TypeError: visible = False data.append({ 'title': assignments[idx].title, 'editview': editviewName, 'hash': portlet_hash, 'name': name, 'up_url': '%s/@@move-portlet-up' % base_url, 'down_url': '%s/@@move-portlet-down' % base_url, 'delete_url': '%s/@@delete-portlet' % base_url, 'metadata_url': settingsviewName, 'hide_url': '%s/@@toggle-visibility' % base_url, 'show_url': '%s/@@toggle-visibility' % base_url, 'visible': visible, }) if len(data) > 0: data[0]['up_url'] = data[-1]['down_url'] = None return data
def portlets(self): data = {} portlet_managers = getUtilitiesFor(IPortletManager, context=self.context) for (name, manager) in portlet_managers: mapping = getMultiAdapter((self.context, manager), IPortletAssignmentMapping) for (id, assignment) in mapping.items(): renderer = getMultiAdapter( ( self.context, self.request, self, manager, assignment ), IPortletRenderer ) if renderer.__of__(self.context).available: try: settings = IPortletAssignmentSettings(assignment) visible = settings.get('visible', True) except TypeError: visible = False if visible: if not data.has_key(name): data[name] = [] config = dict(assignment.__dict__) for k in config.keys(): if k.startswith('__') or k in ('assignment_context_path',): del config[k] data[name].append({ 'id' : id, 'klass' : assignment.__class__.__module__, 'title' : assignment.title, 'config' : config, }) return data
def __call__(self): # The parent object is the Plone content object here; we get # it from the acquisition chain. parent = self.context.aq_inner.aq_parent.aq_parent panel = self.context portlets = [] for assignment in panel: settings = IPortletAssignmentSettings(assignment) if not settings.get('visible', True): continue try: portlet = getMultiAdapter( (parent, self.request, self, panel, assignment), IPortletRenderer) except ComponentLookupError: logging.getLogger("panels").info( "unable to look up renderer for '%s.%s'." % (assignment.__class__.__module__, assignment.__class__.__name__)) continue info = { 'manager': "panels", 'category': CONTEXT_CATEGORY, 'key': '/'.join(panel.getPhysicalPath()), 'name': assignment.__name__, 'renderer': portlet, 'settings': settings, 'assignment': assignment } hashPortletInfo(info) portlet.update() try: available = portlet.available except Exception as e: logging.getLogger('panels').info( "available threw an exception for %s (%s %s)" % (assignment.__name__, type(e), str(e))) continue if available: result = self.portlet(**info) portlets.append(result) return render(portlets, self.context.layout, self.request)
def test_invoke_edit_form(self): mapping = PortletAssignmentMapping() request = self.folder.REQUEST mapping['foo'] = news.Assignment(count=5) editview = getMultiAdapter((mapping['foo'], request), name='edit') editview.update() editview.applyChanges(data={'count': 6, EXTENDER_PREFIX+'.css_class': 'my-class'}) portlet_assignment = mapping.values()[0] settings = IPortletAssignmentSettings(portlet_assignment) self.assertEqual(portlet_assignment.count, 6) # We have not extended our storage adapter, so nothing gets saved: self.assertIsNone(settings.get('css_class', None)) # Register our schemaextender gsm = getGlobalSiteManager() gsm.registerAdapter(PortletCssClassAdapter, (IPortletAssignment,)) gsm.registerAdapter(PortletCssClassFormExtender, (Interface, IDefaultBrowserLayer, IPortletEditForm), IFormExtender, 'portletcssclass.extender') mapping = PortletAssignmentMapping() request = self.folder.REQUEST mapping['foo'] = news.Assignment(count=5) editview = getMultiAdapter((mapping['foo'], request), name='edit') editview.update() editview.applyChanges(data={'count': 6, EXTENDER_PREFIX+'.css_class': 'my-class'}) portlet_assignment = mapping.values()[0] settings = IPortletAssignmentSettings(portlet_assignment) gsm.unregisterAdapter(PortletCssClassFormExtender, (Interface, IDefaultBrowserLayer, IPortletEditForm), IFormExtender, 'portletcssclass.extender') gsm.unregisterAdapter(PortletCssClassAdapter, (IPortletAssignment,)) self.assertEqual(portlet_assignment.count, 6) # The prefix is used for the form field, not for the stored data: self.assertEqual(settings.get('css_class'), 'my-class')
def test_invoke_add_form(self): portlet = getUtility(IPortletType, name='portlets.News') mapping = self.portal.restrictedTraverse( '++contextportlets++plone.leftcolumn') for m in mapping.keys(): del mapping[m] addview = mapping.restrictedTraverse('+/' + portlet.addview) addview.update() addview.createAndAdd(data={'count': 5, EXTENDER_PREFIX+'.css_class': 'my-class'}) portlet_assignment = mapping.values()[0] settings = IPortletAssignmentSettings(portlet_assignment) self.assertEqual(portlet_assignment.count, 5) # We have not extended our storage adapter, so nothing gets saved: self.assertIsNone(settings.get('css_class', None)) # Register our schemaextender gsm = getGlobalSiteManager() gsm.registerAdapter(PortletCssClassAdapter, (IPortletAssignment,)) gsm.registerAdapter(PortletCssClassFormExtender, (Interface, IDefaultBrowserLayer, IPortletAddForm), IFormExtender, 'portletcssclass.extender') for m in mapping.keys(): del mapping[m] addview = mapping.restrictedTraverse('+/' + portlet.addview) addview.update() addview.createAndAdd(data={'count': 5, EXTENDER_PREFIX+'.css_class': 'my-class'}) portlet_assignment = mapping.values()[0] settings = IPortletAssignmentSettings(portlet_assignment) gsm.unregisterAdapter(PortletCssClassFormExtender, (Interface, IDefaultBrowserLayer, IPortletAddForm), IFormExtender, 'portletcssclass.extender') gsm.unregisterAdapter(PortletCssClassAdapter, (IPortletAssignment,)) self.assertEqual(portlet_assignment.count, 5) # The prefix is used for the form field, not for the stored data: self.assertEqual(settings.get('css_class'), 'my-class')
def global_portlets(self, category, prefix): """ Return the list of global portlets from a given category for the current context. Invisible (hidden) portlets are excluded. """ context = aq_inner(self.context) # get the portlet context pcontext = IPortletContext(self.context) portal_state = getMultiAdapter((context, self.request), name=u'plone_portal_state') # noqa base_url = portal_state.portal_url() portlets = [] for cat, key in pcontext.globalPortletCategories(False): if cat == category: mapping = self.manager.get(category, None) assignments = [] if mapping is not None: is_visible = lambda a: IPortletAssignmentSettings(a).get( 'visible', True) # noqa assignments.extend([ a for a in mapping.get(key, {}).values() if is_visible(a) ]) if assignments: edit_url = '%s/++%s++%s+%s' % (base_url, prefix, self.manager.__name__, key) portlets.extend( self.portlets_for_assignments(assignments, self.manager, edit_url)) return portlets
def _lazyLoadPortlets(self, manager): retriever = getMultiAdapter((self.context, manager), IPortletRetriever) items = [] for p in self.filter(retriever.getPortlets()): renderer = self._dataToPortlet(p['assignment'].data) info = p.copy() info['manager'] = self.manager.__name__ info['renderer'] = renderer hashPortletInfo(info) # Record metadata on the renderer renderer.__portlet_metadata__ = info.copy() del renderer.__portlet_metadata__['renderer'] try: isAvailable = renderer.available except ConflictError: raise except Exception, e: isAvailable = False logger.exception( "Error while determining renderer availability of portlet " "(%r %r %r): %s" % (p['category'], p['key'], p['name'], str(e))) info['available'] = isAvailable assignments = info['assignment'].__parent__ settings = IPortletAssignmentSettings(assignments[info['name']]) info['settings'] = settings items.append(info)
def portlets_for_assignments(self, assignments, manager, base_url): category = self.__parent__.category key = self.__parent__.key data = [] for idx in range(len(assignments)): name = assignments[idx].__name__ if hasattr(assignments[idx], '__Broken_state__'): name = assignments[idx].__Broken_state__['__name__'] editview = queryMultiAdapter( (assignments[idx], self.request), name='edit', default=None) if editview is None: editviewName = '' else: editviewName = '%s/%s/edit' % (base_url, name) settingsviewName = '%s/%s/edit-portlet-metadata' % (base_url, name) portlet_hash = hashPortletInfo( dict(manager=manager.__name__, category=category, key=key, name=name,)) try: settings = IPortletAssignmentSettings(assignments[idx]) visible = settings.get('visible', True) except TypeError: visible = False data.append({ 'title': assignments[idx].title, 'editview': editviewName, 'hash': portlet_hash, 'name': name, 'up_url': '%s/@@move-portlet-up' % (base_url), 'down_url': '%s/@@move-portlet-down' % (base_url), 'delete_url': '%s/@@delete-portlet' % (base_url), 'metadata_url': settingsviewName, 'hide_url': '%s/@@toggle-visibility' % (base_url), 'show_url': '%s/@@toggle-visibility' % (base_url), 'visible': visible, }) if len(data) > 0: data[0]['up_url'] = data[-1]['down_url'] = None return data
def export_local_portlets(obj): """Serialize portlets for one content object Code mostly taken from https://github.com/plone/plone.restapi/pull/669 """ portlets_schemata = { iface: name for name, iface in getUtilitiesFor(IPortletTypeInterface) } items = {} for manager_name, manager in getUtilitiesFor(IPortletManager): mapping = queryMultiAdapter((obj, manager), IPortletAssignmentMapping) if mapping is None: continue mapping = mapping.__of__(obj) for name, assignment in mapping.items(): portlet_type = None schema = None for schema in providedBy(assignment).flattened(): portlet_type = portlets_schemata.get(schema, None) if portlet_type is not None: break if portlet_type is None: continue assignment = assignment.__of__(mapping) settings = IPortletAssignmentSettings(assignment) if manager_name not in items: items[manager_name] = [] values = {} for name in schema.names(): value = getattr(assignment, name, None) if RelationValue is not None and isinstance( value, RelationValue): value = value.to_object.UID() elif isinstance(value, RichTextValue): value = { "data": json_compatible(value.raw), "content-type": json_compatible(value.mimeType), "encoding": json_compatible(value.encoding), } value = json_compatible(value) values[name] = value items[manager_name].append({ "type": portlet_type, "visible": settings.get("visible", True), "assignment": values, }) return items
def portlets_for_assignments(self, assignments, manager, base_url): category = self.__parent__.category key = self.__parent__.key portal = self.context.portal_url.getPortalObject() view = portal.restrictedTraverse('@@plone') data = [] for idx in range(len(assignments)): name = assignments[idx].__name__ editview = queryMultiAdapter( (assignments[idx], self.request), name='edit', default=None) if editview is None: editviewName = '' else: editviewName = '%s/%s/edit' % (base_url, name) portlet_hash = hashPortletInfo( dict(manager=manager.__name__, category=category, key=key, name=name,)) settings = IPortletAssignmentSettings(assignments[idx]) renderer = getMultiAdapter( (self.context, self.request, view, manager, assignments[idx]), IPortletRenderer) data.append({ 'title' : assignments[idx].title, 'editview' : editviewName, 'hash' : portlet_hash, 'renderer' : renderer.__of__(self.context), 'up_url' : '%s/@@move-portlet-up?name=%s' % (base_url, name), 'down_url' : '%s/@@move-portlet-down?name=%s' % (base_url, name), 'delete_url' : '%s/@@delete-portlet?name=%s' % (base_url, name), 'hide_url' : '%s/@@toggle-visibility?name=%s' % (base_url, name), 'show_url' : '%s/@@toggle-visibility?name=%s' % (base_url, name), 'visible' : settings.get('visible', True), }) if len(data) > 0: data[0]['up_url'] = data[-1]['down_url'] = None return data
def __call__(self): # The parent object is the Plone content object here; we get # it from the acquisition chain. parent = self.context.aq_inner.aq_parent.aq_parent panel = self.context portlets = [] for assignment in panel: settings = IPortletAssignmentSettings(assignment) if not settings.get('visible', True): continue try: portlet = getMultiAdapter( (parent, self.request, self, panel, assignment), IPortletRenderer) except ComponentLookupError: logging.getLogger("panels").info( "unable to look up renderer for '%s.%s'." % ( assignment.__class__.__module__, assignment.__class__.__name__ ) ) continue info = { 'manager': panel.__name__, 'category': CONTEXT_CATEGORY, 'key': '/'.join(parent.getPhysicalPath()), 'name': assignment.__name__, 'renderer': portlet, } hashPortletInfo(info) portlet.update() if portlet.available: result = self.portlet(**info) portlets.append(result) return render(portlets, self.context.layout, self.request)
def portlets_for_assignments(self, assignments, manager, base_url): category = self.__parent__.category key = self.__parent__.key data = [] for idx in range(len(assignments)): name = assignments[idx].__name__ if hasattr(assignments[idx], "__Broken_state__"): name = assignments[idx].__Broken_state__["__name__"] editview = queryMultiAdapter((assignments[idx], self.request), name="edit", default=None) if editview is None: editviewName = "" else: editviewName = "%s/%s/edit" % (base_url, name) portlet_hash = hashPortletInfo(dict(manager=manager.__name__, category=category, key=key, name=name)) try: settings = IPortletAssignmentSettings(assignments[idx]) visible = settings.get("visible", True) except TypeError: visible = False data.append( { "title": assignments[idx].title, "editview": editviewName, "hash": portlet_hash, "name": name, "up_url": "%s/@@move-portlet-up" % (base_url), "down_url": "%s/@@move-portlet-down" % (base_url), "delete_url": "%s/@@delete-portlet" % (base_url), "hide_url": "%s/@@toggle-visibility" % (base_url), "show_url": "%s/@@toggle-visibility" % (base_url), "visible": visible, } ) if len(data) > 0: data[0]["up_url"] = data[-1]["down_url"] = None return data
def getPortlets(self): """Work out which portlets to display, returning a list of dicts describing assignments to render. """ manager = self.storage.__name__ pcontext = IPortletContext(self.context, None) if pcontext is None: return [] assignable = ILocalPortletAssignable(self.context, None) if assignable is None: return [] annotations = IAnnotations(assignable, None) if annotations is None: return [] local = annotations.get(CONTEXT_ASSIGNMENT_KEY, None) if local is None: return [] localManager = local.get(manager, None) if localManager is None: return [] assignments = [] for assignment in localManager.values(): try: settings = IPortletAssignmentSettings(assignment) except TypeError: # Portlet does not exist any longer continue if not settings.get('visible', True): continue assignments.append(assignment) return [{ 'category': CONTEXT_CATEGORY, 'key': pcontext.uid, 'name': a.__name__, 'assignment': a } for a in assignments]
def getPortlets(self): """Work out which portlets to display, returning a list of dicts describing assignments to render. """ manager = self.storage.__name__ pcontext = IPortletContext(self.context, None) if pcontext is None: return [] assignable = ILocalPortletAssignable(self.context, None) if assignable is None: return [] annotations = IAnnotations(assignable, None) if annotations is None: return [] local = annotations.get(CONTEXT_ASSIGNMENT_KEY, None) if local is None: return [] localManager = local.get(manager, None) if localManager is None: return [] assignments = [] for assignment in localManager.values(): if PLONE4: try: settings = IPortletAssignmentSettings(assignment) except TypeError: # Portlet does not exist any longer continue if not settings.get('visible', True): continue assignments.append(assignment) return [{'category': CONTEXT_CATEGORY, 'key': pcontext.uid, 'name': a.__name__, 'assignment': a} for a in assignments]
def get_portlets(self): portlets_schemata = { iface: name for name, iface in getUtilitiesFor(IPortletTypeInterface) } portlets = {} for manager_name, manager in getUtilitiesFor(IPortletManager): mapping = queryMultiAdapter( (self.context, manager), IPortletAssignmentMapping ) if mapping is None: continue mapping = mapping.__of__(self.context) for name, assignment in mapping.items(): type_ = None schema = None for schema in providedBy(assignment).flattened(): type_ = portlets_schemata.get(schema, None) if type_ is not None: break if type_ is None: continue assignment = assignment.__of__(mapping) settings = IPortletAssignmentSettings(assignment) if manager_name not in portlets: portlets[manager_name] = [] title = getattr(assignment, "title", "") or getattr( assignment, "header", "" ) portlets[manager_name].append( { "type": type_, "title": title, "visible": settings.get("visible", True), "assignment": { name: getattr(assignment, name, None) for name in schema.names() }, } ) self["portlets"] = portlets
def portlets_for_assignments(self, assignments, manager, base_url): data = [] for idx in range(len(assignments)): name = assignments[idx].__name__ editview = queryMultiAdapter( (assignments[idx], self.request), name='edit', default=None) if editview is None: editviewName = '' else: editviewName = '%s/%s/edit' % (base_url, name) settings = IPortletAssignmentSettings(assignments[idx]) data.append({ 'title': assignments[idx].title, 'editview': editviewName, 'visible': settings.get('visible', True), }) return data
def exportAssignments(self, obj): assignments = [] for manager_name, manager in self.portlet_managers: mapping = queryMultiAdapter( (obj, manager), IPortletAssignmentMapping) if mapping is None: continue mapping = mapping.__of__(obj) if len(mapping.items()) > 0: for name, assignment in mapping.items(): type_ = None for schema in providedBy(assignment).flattened(): type_ = self.portlet_schemata.get(schema, None) if type_ is not None: break if type_ is not None: child = self.doc.createElement('assignment') child.setAttribute('manager', manager_name) child.setAttribute('category', CONTEXT_CATEGORY) child.setAttribute('key', '/'.join( obj.getPhysicalPath())) child.setAttribute('type', type_) child.setAttribute('name', name) settings = IPortletAssignmentSettings(assignment) if not settings.get('visible', True): child.setAttribute('visible', 'False') assignment = assignment.__of__(mapping) # use existing adapter for exporting a portlet assignment # noqa handler = IPortletAssignmentExportImportHandler(assignment) # noqa handler.export_assignment(schema, self.doc, child) assignments.append(child) return assignments
def exportAssignments(self, obj): assignments = [] for manager_name, manager in self.portlet_managers: mapping = queryMultiAdapter((obj, manager), IPortletAssignmentMapping) if mapping is None: continue mapping = mapping.__of__(obj) if len(mapping.items()) > 0: for name, assignment in mapping.items(): type_ = None for schema in providedBy(assignment).flattened(): type_ = self.portlet_schemata.get(schema, None) if type_ is not None: break if type_ is not None: child = self.doc.createElement('assignment') child.setAttribute('manager', manager_name) child.setAttribute('category', CONTEXT_CATEGORY) child.setAttribute('key', '/'.join(obj.getPhysicalPath())) child.setAttribute('type', type_) child.setAttribute('name', name) settings = IPortletAssignmentSettings(assignment) if not settings.get('visible', True): child.setAttribute('visible', 'False') assignment = assignment.__of__(mapping) # use existing adapter for exporting a portlet assignment # noqa handler = IPortletAssignmentExportImportHandler( assignment) # noqa handler.export_assignment(schema, self.doc, child) assignments.append(child) return assignments
def getColumn(self, name, group='AnonymousUsers'): column = getUtility(IPortletManager, name=name) category = column[GROUP_CATEGORY] mapping = category.get(group, None) if mapping is None: return u'' context = aq_inner(self.context) assignments = [] for assignment in mapping.values(): settings = IPortletAssignmentSettings(assignment) if not settings.get('visible', True): continue assignments.append({'category': GROUP_CATEGORY, 'key': group, 'name': assignment.__name__, 'assignment': assignment }) renderer = HomePageColumnsRenderer(context, self.request, self, column) renderer.assignments = assignments renderer.update() return renderer.render()
def __call__(self, context): portlets = [] if hasattr(context, 'portlets'): portlets = context.portlets for portlet in portlets: if not portlet in context.__parent__: context.portlets.remove(portlet) possible = {} for k, v in context.__parent__.items(): if v == context: continue settings = IPortletAssignmentSettings(v) if k in portlets: possible[k] = v if settings.get('visible', True): possible[k] = v if k in portlets: context.portlets.remove(k) return SimpleVocabulary( [SimpleTerm(value=k, token=base64.b64encode(k), title=v.title) for k, v in possible.items()])
def test_portlet_renders_in_tiny_mce(self): portal = self.layer['portal'] rightcol = getUtility(IPortletManager, name=u'plone.rightcolumn', context=portal) right = getMultiAdapter((portal, rightcol,), IPortletAssignmentMapping, context=portal) staticportlet = static.Assignment(header=u"Static Portlet", text=u"TEXT INPUT") right[u'staticportlet'] = staticportlet settings = IPortletAssignmentSettings(staticportlet) visible = settings.get('visible', True) settings['visible'] = False page = portal[portal.invokeFactory('Document', 'testpage')] hash = portletHash(rightcol, staticportlet, portal) field = page.getField('text') portletmarkup = portletMarkup(hash) field.set(page, portletmarkup, mimetype='text/html') page.setTitle('Blah') page.reindexObject() transaction.commit() self.browser.open('http://nohost/plone/testpage') self.failUnless("TEXT INPUT" in self.browser.contents)
def migrate_portlets_for_object(obj, path): portlet_managers = getUtilitiesFor(IPortletManager, context=obj) for portlet_manager_name, portlet_manager in portlet_managers: assignments = queryMultiAdapter( (obj, portlet_manager), IPortletAssignmentMapping, context=obj) if assignments is None: continue for portlet_id, portlet in assignments.items(): if IStaticPortlet.providedBy(portlet) and \ getattr(portlet, 'hide', False): logger.info( 'Found hidden static text portlet %s at %s' % (portlet_id, path)) settings = IPortletAssignmentSettings(portlet) settings['visible'] = False
def testAssignmentSettings(self): mapping = assignment_mapping_from_key(self.portal, manager_name=u"test.testcolumn", category=CONTEXT_CATEGORY, key="/") assignment = mapping['test.portlet1'] settings = IPortletAssignmentSettings(assignment) self.assertTrue(settings.get('visible', True)) assignment = mapping['test.portlet2'] settings = IPortletAssignmentSettings(assignment) self.assertFalse(settings.get('visible', True))
def test_invoke_edit_form(self): mapping = PortletAssignmentMapping() request = self.folder.REQUEST mapping['foo'] = news.Assignment(count=5) editview = getMultiAdapter((mapping['foo'], request), name='edit') editview.update() editview.applyChanges(data={ 'count': 6, EXTENDER_PREFIX + '.css_class': 'my-class' }) portlet_assignment = mapping.values()[0] settings = IPortletAssignmentSettings(portlet_assignment) self.assertEqual(portlet_assignment.count, 6) # We have not extended our storage adapter, so nothing gets saved: self.assertIsNone(settings.get('css_class', None)) # Register our schemaextender gsm = getGlobalSiteManager() gsm.registerAdapter(PortletCssClassAdapter, (IPortletAssignment, )) gsm.registerAdapter( PortletCssClassFormExtender, (Interface, IDefaultBrowserLayer, IPortletEditForm), IFormExtender, 'portletcssclass.extender') mapping = PortletAssignmentMapping() request = self.folder.REQUEST mapping['foo'] = news.Assignment(count=5) editview = getMultiAdapter((mapping['foo'], request), name='edit') editview.update() editview.applyChanges(data={ 'count': 6, EXTENDER_PREFIX + '.css_class': 'my-class' }) portlet_assignment = mapping.values()[0] settings = IPortletAssignmentSettings(portlet_assignment) gsm.unregisterAdapter( PortletCssClassFormExtender, (Interface, IDefaultBrowserLayer, IPortletEditForm), IFormExtender, 'portletcssclass.extender') gsm.unregisterAdapter(PortletCssClassAdapter, (IPortletAssignment, )) self.assertEqual(portlet_assignment.count, 6) # The prefix is used for the form field, not for the stored data: self.assertEqual(settings.get('css_class'), 'my-class')
def test_portlets_with_settings(self): # IPortletAssignmentSettings creates settings in the annotations ori_assignment = self.layer['right_portlets'].get('title2', False) ori_settings = getAdapter(ori_assignment, IPortletAssignmentSettings) ori_settings['foo'] = 'bar' # extract the data adapter = getAdapter(self.layer['folder1'], IDataCollector, name="portlet_data_adapter") getterdata = adapter.getData() getterdata = utils.decode_for_json(getterdata) jsondata = json.dumps(getterdata) # set the data on the folder2 data = json.loads(jsondata) data = utils.encode_after_json(data) adapter2 = getAdapter(self.layer['folder2'], IDataCollector, name="portlet_data_adapter") adapter2.setData(data, metadata=None) # test the assignment settings new_assignment = self.layer['right_portlets'].get('title2', False) new_settings = getAdapter(new_assignment, IPortletAssignmentSettings) self.assertEqual(new_settings['foo'], 'bar') assignment_annotations = new_assignment.__annotations__ self.assertTrue( isinstance(assignment_annotations, OOBTree), 'annotations are not OOBTree but %s' % type(assignment_annotations)) settings = assignment_annotations.get(ASSIGNMENT_SETTINGS_KEY) self.assertTrue( IPortletAssignmentSettings.providedBy(settings), 'Portlet settings is not PortletAssignmentSettings but %s' % (type(settings)))
def test_invoke_add_form(self): portlet = getUtility(IPortletType, name='portlets.News') mapping = self.portal.restrictedTraverse( '++contextportlets++plone.leftcolumn') for m in mapping.keys(): del mapping[m] addview = mapping.restrictedTraverse('+/' + portlet.addview) addview.update() addview.createAndAdd(data={ 'count': 5, EXTENDER_PREFIX + '.css_class': 'my-class' }) portlet_assignment = mapping.values()[0] settings = IPortletAssignmentSettings(portlet_assignment) self.assertEqual(portlet_assignment.count, 5) # We have not extended our storage adapter, so nothing gets saved: self.assertIsNone(settings.get('css_class', None)) # Register our schemaextender gsm = getGlobalSiteManager() gsm.registerAdapter(PortletCssClassAdapter, (IPortletAssignment, )) gsm.registerAdapter(PortletCssClassFormExtender, (Interface, IDefaultBrowserLayer, IPortletAddForm), IFormExtender, 'portletcssclass.extender') for m in mapping.keys(): del mapping[m] addview = mapping.restrictedTraverse('+/' + portlet.addview) addview.update() addview.createAndAdd(data={ 'count': 5, EXTENDER_PREFIX + '.css_class': 'my-class' }) portlet_assignment = mapping.values()[0] settings = IPortletAssignmentSettings(portlet_assignment) gsm.unregisterAdapter( PortletCssClassFormExtender, (Interface, IDefaultBrowserLayer, IPortletAddForm), IFormExtender, 'portletcssclass.extender') gsm.unregisterAdapter(PortletCssClassAdapter, (IPortletAssignment, )) self.assertEqual(portlet_assignment.count, 5) # The prefix is used for the form field, not for the stored data: self.assertEqual(settings.get('css_class'), 'my-class')
def test_portlets_with_settings(self): # IPortletAssignmentSettings creates settings in the annotations ori_assignment = self.layer['right_portlets'].get('title2', False) ori_settings = getAdapter(ori_assignment, IPortletAssignmentSettings) ori_settings['foo'] = 'bar' # extract the data adapter = getAdapter(self.layer['folder1'], IDataCollector, name="portlet_data_adapter") getterdata = adapter.getData() getterdata = utils.decode_for_json(getterdata) jsondata = json.dumps(getterdata) # set the data on the folder2 data = json.loads(jsondata) data = utils.encode_after_json(data) adapter2 = getAdapter(self.layer['folder2'], IDataCollector, name="portlet_data_adapter") adapter2.setData(data, metadata=None) # test the assignment settings new_assignment = self.layer['right_portlets'].get('title2', False) new_settings = getAdapter(new_assignment, IPortletAssignmentSettings) self.assertEqual(new_settings['foo'], 'bar') assignment_annotations = new_assignment.__annotations__ self.assertTrue( isinstance(assignment_annotations, OOBTree), 'annotations are not OOBTree but %s' % type( assignment_annotations)) settings = assignment_annotations.get(ASSIGNMENT_SETTINGS_KEY) self.assertTrue( IPortletAssignmentSettings.providedBy(settings), 'Portlet settings is not PortletAssignmentSettings but %s' % ( type(settings)))
def is_visible(a): try: return IPortletAssignmentSettings(a).get('visible', True) except TypeError: # Assignment is broken return False
def getPortlets(self): """Work out which portlets to display, returning a list of dicts describing assignments to render. """ if IPortletContext.providedBy(self.context): pcontext = self.context else: pcontext = queryAdapter(self.context, IPortletContext) if pcontext is None: return [] # Holds a list of (category, key, assignment). categories = [] # Keeps track of the blacklisting status for global categores # (user, group, content type). The status is either True (blocked) # or False (not blocked). blacklisted = {} # This is the name of the manager (column) we're rendering manager = self.storage.__name__ # 1. Fetch blacklisting status for each global category # First, find out which categories we will need to determine # blacklist status for for category, key in pcontext.globalPortletCategories(False): blacklisted[category] = None # Then walk the content hierarchy to find out what blacklist status # was assigned. Note that the blacklist is tri-state; if it's None it # means no assertion has been made (i.e. the category has neither been # whitelisted or blacklisted by this object or any parent). The first # item to give either a blacklisted (True) or whitelisted (False) # value for a given item will set the appropriate value. Parents of # this item that also set a black- or white-list value will then be # ignored. # Whilst walking the hierarchy, we also collect parent portlets, # until we hit the first block. current = self.context currentpc = pcontext blacklistFetched = set() parentsBlocked = False while current is not None and currentpc is not None: if ILocalPortletAssignable.providedBy(current): assignable = current else: assignable = queryAdapter(current, ILocalPortletAssignable) if assignable is not None: if IAnnotations.providedBy(assignable): annotations = assignable else: annotations = queryAdapter(assignable, IAnnotations) if not parentsBlocked: local = annotations.get(CONTEXT_ASSIGNMENT_KEY, None) if local is not None: localManager = local.get(manager, None) if localManager is not None: categories.extend([(CONTEXT_CATEGORY, currentpc.uid, a) for a in localManager.values()]) lpam = getMultiAdapter((assignable, self.storage), ILocalPortletAssignmentManager) if lpam.getBlacklistStatus(CONTEXT_CATEGORY): parentsBlocked = True for cat, cat_status in blacklisted.items(): local_status = lpam.getBlacklistStatus(cat) if local_status is not None: blacklistFetched.add(cat) if cat_status is None: blacklisted[cat] = local_status # We can abort if parents are blocked and we've fetched all # blacklist statuses if parentsBlocked and len(blacklistFetched) == len(blacklisted): break # Check the parent - if there is no parent, we will stop current = currentpc.getParent() if current is not None: if IPortletContext.providedBy(current): currentpc = current else: currentpc = queryAdapter(current, IPortletContext) # Get all global mappings for non-blacklisted categories for category, key in pcontext.globalPortletCategories(False): if not blacklisted[category]: mapping = self.storage.get(category, None) if mapping is not None: for a in mapping.get(key, {}).values(): categories.append((category, key, a, )) assignments = [] for category, key, assignment in categories: try: settings = IPortletAssignmentSettings(assignment) if not settings.get('visible', True): continue except TypeError: # Portlet does not exist any longer continue assignments.append({'category': category, 'key': key, 'name': str(assignment.__name__), 'assignment': assignment }) return assignments
def __init__(self, context, request): super(DisplayPanelView, self).__init__(context, request) # todo: move away from init # The parent object is the Plone content object here; we get # it from the acquisition chain. # The panel can be rendered in different contexts, where the length of # the chain to the Plone content object is not obvious; # on portlet edit forms for instance, where we have a panel of # portlets below the edit form. # So to get the content object we go up in the aq chain, until we are # out of the chain of portlet assignments, panels etc. parent = self.context.aq_inner while True: parent = parent.aq_parent if not (IPanel.providedBy(parent) or IPortletAssignment.providedBy(parent) or IPortletAssignmentMapping.providedBy(parent)): break panel = self.context portlets = [] for assignment in panel: settings = IPortletAssignmentSettings(assignment) if not settings.get('visible', True): continue try: portlet = getMultiAdapter((parent, self.request, self, panel, assignment.__of__(panel)), IPortletRenderer) except ComponentLookupError: logging.getLogger("panels").info( "unable to look up renderer for '%s.%s'." % (assignment.__class__.__module__, assignment.__class__.__name__)) continue info = { 'manager': "panels", 'category': CONTEXT_CATEGORY, 'key': str('/'.join(parent.getPhysicalPath())), 'name': assignment.__name__, 'renderer': portlet, 'settings': settings, 'assignment': assignment } # todo: check new impl. of portlet rendering hashPortletInfo(info) portlet.__portlet_metadata__ = info.copy() del portlet.__portlet_metadata__['renderer'] portlet.update() try: available = portlet.available except ConflictError: raise except Exception as err: logging.getLogger('panels').info( "available threw an exception for %s (%s %s)" % (assignment.__name__, type(err), str(err))) continue info['available'] = available portlets.append(info) self.portlets = portlets
def _initAssignmentNode(self, node): """Create an assignment from a node """ site = self.environ.getSite() # 1. Determine the assignment mapping and the name manager = node.getAttribute('manager') category = node.getAttribute('category') key = node.getAttribute('key') # convert unicode to str as unicode paths are not allowed in # restrictedTraverse called in assignment_mapping_from_key if six.PY2: key = key.encode() purge = False if node.hasAttribute('purge'): purge = self._convertToBoolean(node.getAttribute('purge')) mapping = assignment_mapping_from_key(site, manager, category, key, create=True) # 2. Either find or create the assignment assignment = None name = node.getAttribute('name') if name: name = str(name) assignment = mapping.get(name, None) __traceback_info__ = "Assignment name: " + name if node.hasAttribute('remove'): if assignment is not None: del mapping[name] return if purge: for portlet in mapping.keys(): del mapping[portlet] return type_ = str(node.getAttribute('type')) if assignment is None: portlet_factory = getUtility(IFactory, name=type_) assignment = portlet_factory() if not name: chooser = INameChooser(mapping) name = chooser.chooseName(None, assignment) mapping[name] = assignment # aq-wrap it so that complex fields will work assignment = assignment.__of__(site) # set visibility setting visible = node.getAttribute('visible') if visible: settings = IPortletAssignmentSettings(assignment) settings['visible'] = self._convertToBoolean(visible) # 3. Use an adapter to update the portlet settings portlet_interface = getUtility(IPortletTypeInterface, name=type_) assignment_handler = IPortletAssignmentExportImportHandler(assignment) assignment_handler.import_assignment(portlet_interface, node) # 4. Handle ordering insert_before = node.getAttribute('insert-before') if insert_before: position = None keys = list(mapping.keys()) if insert_before == "*": position = 0 elif insert_before in keys: position = keys.index(insert_before) if position is not None: keys.remove(name) keys.insert(position, name) mapping.updateOrder(keys)
def __setattr__(self, attr, value): settings = IPortletAssignmentSettings(self.context) settings[attr] = value
def __getattr__(self, attr): settings = IPortletAssignmentSettings(self.context) return settings.get(attr, None)
def __call__(self): # The parent object is the Plone content object here; we get # it from the acquisition chain. # The panel can be rendered in different contexts, where the length of # the chain to the Plone content object is not obvious; # on portlet edit forms for instance, where we have a panel of # portlets below the edit form. # So to get the content object we go up in the aq chain, until we are # out of the chain of portlet assignments, panels etc. parent = self.context.aq_inner while True: parent = parent.aq_parent if not (IPanel.providedBy(parent) or IPortletAssignment.providedBy(parent) or IPortletAssignmentMapping.providedBy(parent)): break panel = self.context portlets = [] for assignment in panel: settings = IPortletAssignmentSettings(assignment) if not settings.get('visible', True): continue try: portlet = getMultiAdapter( (parent, self.request, self, panel, assignment), IPortletRenderer) except ComponentLookupError: logging.getLogger("panels").info( "unable to look up renderer for '%s.%s'." % ( assignment.__class__.__module__, assignment.__class__.__name__ ) ) continue info = { 'manager': "panels", 'category': CONTEXT_CATEGORY, 'key': str('/'.join(parent.getPhysicalPath())), 'name': assignment.__name__, 'renderer': portlet, 'settings': settings, 'assignment': assignment } hashPortletInfo(info) portlet.__portlet_metadata__ = info.copy() del portlet.__portlet_metadata__['renderer'] portlet.update() try: available = portlet.available except ConflictError: raise except Exception as e: logging.getLogger('panels').info( "available threw an exception for %s (%s %s)" % ( assignment.__name__, type(e), str(e) ) ) continue if available: result = self.portlet(**info) portlets.append(result) return render( portlets, self.context.layout, self.request )
def hidePortlet(context, portletName, columnName='plone.leftcolumn'): manager = getUtility(IPortletManager, columnName) assignmentMapping = getMultiAdapter((context, manager), IPortletAssignmentMapping) settings = IPortletAssignmentSettings(assignmentMapping[portletName]) settings['visible'] = False
def setData(self, portletsdata, metadata): """create or updates portlet informations """ for manager_name in portletsdata.keys(): column = queryUtility(IPortletManager, name=manager_name, context=self.object) if column is None: continue # ok we have a portlet manager # get all current assigned portlets portlets = getMultiAdapter(( self.object, column, ), IPortletAssignmentMapping, context=self.object) p_ids = [p for p in portlets._data.keys()] # get new order order = portletsdata[manager_name]['order'] and \ portletsdata[manager_name]['order'].split(',') or [] # set blackliststatus blacklist = getMultiAdapter((self.object, column), ILocalPortletAssignmentManager) blacklistdata = portletsdata[manager_name]['blackliststatus'] blacklist.setBlacklistStatus(GROUP_CATEGORY, blacklistdata[GROUP_CATEGORY]) blacklist.setBlacklistStatus(USER_CATEGORY, blacklistdata[USER_CATEGORY]) blacklist.setBlacklistStatus(CONTENT_TYPE_CATEGORY, blacklistdata[CONTENT_TYPE_CATEGORY]) blacklist.setBlacklistStatus(CONTEXT_CATEGORY, blacklistdata[CONTEXT_CATEGORY]) # bit clean up del portletsdata[manager_name]['blackliststatus'] del portletsdata[manager_name]['order'] # remove all currenlty assigned portlets from manager for p_id in p_ids: del portlets._data[p_id] for portlet_id in portletsdata[manager_name].keys(): portletfielddata = portletsdata[manager_name][portlet_id] # get Assignment portlet_module = modules[portletfielddata['module']] portlet_class = getattr( portlet_module, portletfielddata['assignment_class_name']) settings = portletfielddata.get('settings', None) # prepare data to pass as arguments del portletfielddata['module'] del portletfielddata['assignment_class_name'] del portletfielddata['settings'] annotations = portletfielddata.get('__annotations__', None) if '__annotations__' in portletfielddata: del portletfielddata['__annotations__'] # check for dicts for k, v in portletfielddata.items(): if isinstance(v, dict): # so we have one, now we have to turn the # serialized data into an object # this is generic, but currently only in use # by the image portlet klass = modules[v['module']].__dict__[v['klass_name']] for argname in ('file', 'data'): if argname in v['kwargs']: v['kwargs'][argname] = base64.decodestring( v['kwargs'][argname]) imgobj = klass(**v['kwargs']) portletfielddata[k] = imgobj portlets[portlet_id] = portlet_class(**portletfielddata) # XXX boolean value fix # for some reason boolean types cannpt be passed with **... # use setattr for k, v in portletfielddata.items(): if isinstance(v, bool): setattr(portlets[portlet_id], k, v) if annotations: portlets[portlet_id].__annotations__ = annotations # portlet settings (visibility) portlet_assignment = portlets[portlet_id] IPortletAssignmentSettings(portlet_assignment).data = settings # set new order afterwards portlets._order = PersistentList(order)
def getData(self): """returns all important data data form {'column': {portlet: {key:value} } . . . . {'blackliststatus': {category:True}, {'order': ['portlet 1', 'portlet 2']} } } """ data = {} plone_portlet_manager = [] # gets all portlet managers used on this object annotations = getattr(self.object, '__annotations__', None) if not annotations: return data has_portlets = 'plone.portlets.contextassignments' in annotations has_blacklist = 'plone.portlets.categoryblackliststatus' in annotations if not has_portlets and not has_blacklist: return data if has_portlets: plone_portlet_manager += self.object.__annotations__[ 'plone.portlets.contextassignments'].keys() if has_blacklist: plone_portlet_manager += self.object.__annotations__[ 'plone.portlets.categoryblackliststatus'].keys() EXCLUDED_FIELDS = ['__name__', '__parent__'] # XXX this is a static list, replace by a configlet option # the list contains all not serializable portlets (__module__) blacklisted_portlets = [ 'collective.dancing.browser.portlets.channelsubscribe' ] for manager_name in plone_portlet_manager: column = queryUtility(IPortletManager, name=manager_name, context=self.object) if column is None: continue # ok we have a portlet manager data[manager_name] = {} # get blackliststatus blacklist = getMultiAdapter((self.object, column), ILocalPortletAssignmentManager) data[manager_name]['blackliststatus'] = {} blacklistdata = data[manager_name]['blackliststatus'] blacklistdata[GROUP_CATEGORY] = blacklist.getBlacklistStatus( GROUP_CATEGORY) blacklistdata[USER_CATEGORY] = blacklist.getBlacklistStatus( USER_CATEGORY) blacklistdata[CONTENT_TYPE_CATEGORY] = \ blacklist.getBlacklistStatus(CONTENT_TYPE_CATEGORY) blacklistdata[CONTEXT_CATEGORY] = \ blacklist.getBlacklistStatus(CONTEXT_CATEGORY) portlets = getMultiAdapter(( self.object, column, ), IPortletAssignmentMapping, context=self.object) # portlets order - dicts are unsorted data[manager_name]['order'] = ','.join(portlets._order) for portlet_id in portlets.keys(): portlet_assignment = portlets[portlet_id] # continue if portlet is blacklisted if portlet_assignment.__module__ in blacklisted_portlets: continue # we habe a portlet data[manager_name][portlet_assignment.__name__] = {} data[manager_name][portlet_assignment.__name__]['module'] = \ portlet_assignment.__class__.__module__ data[manager_name][portlet_assignment.__name__]['assignment_class_name'] = \ portlet_assignment.__class__.__name__ # portlet settings (visibility) settings = IPortletAssignmentSettings(portlet_assignment).data data[manager_name][ portlet_assignment.__name__]['settings'] = settings # get all data for field in portlet_assignment.__dict__.keys(): if field not in EXCLUDED_FIELDS: field_value = getattr(portlet_assignment, field, '') # image field - image.portlet integration if isinstance(field_value, OFSImage): # same way as in AT field serializer field_value = { 'module': OFSImage.__module__, 'klass_name': OFSImage.__name__, 'kwargs': { 'file': base64.encodestring(field_value.data), 'id': field_value.id(), 'title': field_value.title } } elif (HAS_NAMEDFILE and INamedFile.providedBy(field_value)): klass = type(field_value) field_value = { 'module': klass.__module__, 'klass_name': klass.__name__, 'kwargs': { 'data': base64.encodestring(field_value.data), 'filename': field_value.filename, 'contentType': field_value.contentType } } data[manager_name][ portlet_assignment.__name__][field] = field_value return data
def register_portlets(obj, item): """Register portlets fror one object Code adapted from plone.app.portlets.exportimport.portlets.PortletsXMLAdapter Work in progress... """ site = api.portal.get() request = getRequest() results = 0 for manager_name, portlets in item.get("portlets", {}).items(): manager = getUtility(IPortletManager, manager_name) mapping = queryMultiAdapter((obj, manager), IPortletAssignmentMapping) namechooser = INameChooser(mapping) for portlet_data in portlets: # 1. Create the assignment assignment_data = portlet_data["assignment"] portlet_type = portlet_data["type"] portlet_factory = getUtility(IFactory, name=portlet_type) assignment = portlet_factory() name = namechooser.chooseName(None, assignment) mapping[name] = assignment logger.info("Added portlet {} to {}".format( name, obj.absolute_url())) # aq-wrap it so that complex fields will work assignment = assignment.__of__(site) # set visibility setting visible = portlet_data.get("visible") if visible: settings = IPortletAssignmentSettings(assignment) settings["visible"] = visible # 2. Apply portlet settings portlet_interface = getUtility(IPortletTypeInterface, name=portlet_type) for property_name, value in assignment_data.items(): field = portlet_interface.get(property_name, None) if field is None: continue field = field.bind(assignment) # deserialize data (e.g. for RichText) deserializer = queryMultiAdapter((field, obj, request), IFieldDeserializer) if deserializer is not None: try: value = deserializer(value) except Exception as e: logger.info( u"Could not import portlet data {} for field {} on {}: {}" .format(value, field, obj.absolute_url(), str(e))) continue field.set(assignment, value) results += 1 for blacklist_status in item.get("blacklist_status", []): status = blacklist_status["status"] manager_name = blacklist_status["manager"] category = blacklist_status["category"] manager = getUtility(IPortletManager, manager_name) assignable = queryMultiAdapter((obj, manager), ILocalPortletAssignmentManager) if status.lower() == "block": assignable.setBlacklistStatus(category, True) elif status.lower() == "show": assignable.setBlacklistStatus(category, False) return results