def __init__(self): Folder.__init__(self) BaseTool.__init__(self) self._layout_registry = LayoutRegistry() self._viewlet_registry = ViewletRegistry()
class CompositeTool(BaseTool, Folder): """ CompositePack Tool """ implements(ICompositeTool) id = TOOL_ID meta_type = "CompositePack Tool" security = ClassSecurityInfo() _viewlets_by_type = None # PersistentMapping _default_viewlets = ("default_viewlet", "link_viewlet") _default_default = "default_viewlet" _default_layout = "" _manage_composites = PageTemplateFile("composites.pt", zmi_dir) _manage_composables = PageTemplateFile("composables.pt", zmi_dir) _manage_layouts = PageTemplateFile("layouts.pt", zmi_dir) _manage_viewlets = PageTemplateFile("viewlets.pt", zmi_dir) macros_template = PageTemplateFile("macros.pt", zmi_dir) manage_options = insert_zmi_tab_after( "Contents", {"label": "Composites", "action": "manage_composites"}, Folder.manage_options ) manage_options = insert_zmi_tab_after( "Composites", {"label": "Composables", "action": "manage_composables"}, manage_options ) def __init__(self): Folder.__init__(self) BaseTool.__init__(self) self._layout_registry = LayoutRegistry() self._viewlet_registry = ViewletRegistry() def __repr__(self): return "CompositePack Tool" security.declarePublic("moveAndDelete") def moveAndDelete( self, move_source_paths="", move_target_path="", move_target_index="", delete_source_paths="", composite_path="", REQUEST=None, ): """Move and/or delete elements. """ portal = getToolByName(self, "portal_url").getPortalObject() # Try to get translation service for status messages translation_service = getToolByName(self, "translation_service", None) if translation_service: utranslate = translation_service.utranslate # else I won't translate at all try: compo = portal.restrictedTraverse(composite_path) except AttributeError: # We cannot traverse towards the asked composite path, this might # happen when another user deleted the navigation page where we are # dragging an item to a new location. # Or in short: composite_path no longer exists at this place. error = "The page you were working on has been moved or deleted by another user." if translation_service: # Translate if possible message = utranslate("compopack", "navigation_page_deleted_or_moved", {}, self, default=error) else: # We don't have a translation service? Then we will just serve # the default English error message = error status_message = "?portal_status_message=" + message if REQUEST: # Redirect to portal root with a status message, because # current document no longer exists at this place. url = getToolByName(self, "portal_url")() url += status_message REQUEST.RESPONSE.redirect(url) return try: BaseTool.moveAndDelete( self, move_source_paths, move_target_path, move_target_index, delete_source_paths, REQUEST ) except AttributeError: # Item cannot be moved or deleted because the item within this page has # been either deleted or moved to another location. error = "The item you tried to move or delete was already touched by another user." if translation_service: # Translate our error message = utranslate("compopack", "item_touched_by_other_user", {}, self, default=error) status_message = "?portal_status_message=" + message else: # or not... message = error status_message = "?portal_status_message=" + message if REQUEST: # Redirect to same (updated) page with a smart remark url = REQUEST["HTTP_REFERER"].split("?")[0] url += status_message REQUEST.RESPONSE.redirect(url) return if REQUEST: # Change was succesful so remove any standing error messages and # reload the page url = REQUEST["HTTP_REFERER"].split("?")[0] REQUEST.RESPONSE.redirect(url) security.declarePrivate("getMapMetatypesPortalTypes") def getMapMetatypesPortalTypes(self): # compute a map of meta_types and corresponding portal_types tt = getToolByName(self, "portal_types") type_infos = tt.listTypeInfo() meta_portal = {} for ti in type_infos: if meta_portal.has_key(ti.content_meta_type): meta_portal[ti.content_meta_type].append(ti.getId()) else: meta_portal[ti.content_meta_type] = [ti.getId()] return meta_portal security.declarePrivate("getRegisteredCompositePortalTypes") def getRegisteredCompositePortalTypes(self): meta_portal = self.getMapMetatypesPortalTypes() arche_data = listTypes() result = [] for arche_type in arche_data: if hasattr(arche_type["klass"], "cp_view"): result.extend(meta_portal.get(arche_type["meta_type"], [])) return result security.declarePrivate("getRegisteredArchePortalTypes") def getRegisteredArchePortalTypes(self): meta_portal = self.getMapMetatypesPortalTypes() arche_data = listTypes() result = [] for arche_type in arche_data: result.extend(meta_portal.get(arche_type["meta_type"], [])) return result ## Composites ZMI tab security.declareProtected(ManagePortal, "manage_composites") def manage_composites(self, REQUEST, manage_tabs_message=None): """ manage composites """ registered_composites = self.getRegisteredComposites() registered_composites.sort() compositePortalTypes = self.getRegisteredCompositePortalTypes() unregistered_composites = [pt for pt in compositePortalTypes if pt not in registered_composites] unregistered_composites.sort() default_layout = self.queryDefaultLayout() all_layouts = self.getAllLayouts() return self._manage_composites( REQUEST, registered_composites=registered_composites, unregistered_composites=unregistered_composites, default_layout=default_layout, all_layouts=all_layouts, ) security.declareProtected(ManagePortal, "manage_addComposites") def manage_addComposites(self, REQUEST, manage_tabs_message=None, types=None): """ register composites """ if types is None: types = [] for type in types: self.registerAsComposite(type) return self.REQUEST.RESPONSE.redirect("manage_composites") security.declareProtected(ManagePortal, "manage_unregisterComposite") def manage_unregisterComposite(self, REQUEST, type=None): """ unregister composite """ if type is not None: self.unregisterAsComposite(type) return self.REQUEST.RESPONSE.redirect("manage_composites") security.declareProtected(ManagePortal, "manage_setDefaultLayout") def manage_setDefaultLayout(self, REQUEST, layout_id=None): """ set default layout """ if layout_id is not None: self.setDefaultLayout(layout_id) return self.REQUEST.RESPONSE.redirect("manage_composites") ## Manage layouts per composite ZMI view security.declareProtected(ManagePortal, "manage_layouts") def manage_layouts(self, REQUEST, manage_tabs_message=None, type=None): """ manage layouts """ def layout_sort(a, b): return cmp(a.title, b.title) if type is not None: registered_layouts = self.getRegisteredLayoutsForType(type) registered_layouts.sort(layout_sort) allLayouts = self.getAllLayouts() unregistered_layouts = [pt for pt in allLayouts if pt not in registered_layouts] unregistered_layouts.sort(layout_sort) nodefault = self.noDefaultLayoutForType(type) default_layout = self.getLayoutById(self.getDefaultLayout()).title return self._manage_layouts( REQUEST, type=type, registered_layouts=registered_layouts, unregistered_layouts=unregistered_layouts, nodefault=nodefault, default_layout=default_layout, ) security.declareProtected(ManagePortal, "manage_addLayouts") def manage_addLayouts(self, REQUEST, manage_tabs_message=None, type=None, layouts=None): """ register layouts for type """ if type is not None: if layouts is None: layouts = [] for layout_id in layouts: layout = self.getLayoutById(layout_id) if layout: self.registerLayoutForType(layout, type) # return self.manage_layouts(REQUEST, type=type) return self.REQUEST.RESPONSE.redirect("manage_layouts?type=%s" % url_quote(type)) security.declareProtected(ManagePortal, "manage_unregisterLayout") def manage_unregisterLayout(self, REQUEST, manage_tabs_message=None, type=None, layout_id=None): """ unregister layouts for type """ if type is not None: layout = self.getLayoutById(layout_id) if layout: self.unregisterLayoutForType(layout, type) # return self.manage_layouts(REQUEST, type=type) return self.REQUEST.RESPONSE.redirect("manage_layouts?type=%s" % url_quote(type)) security.declareProtected(ManagePortal, "manage_defaultLayout") def manage_defaultLayout(self, REQUEST, manage_tabs_message=None, type=None, default=None): """ set default layout for type """ if type is not None: if default == "nodefault": self.clearDefaultLayoutForType(type) else: layout = self.getLayoutById(default) if layout: self.setDefaultLayoutForType(layout, type) # return self.manage_layouts(REQUEST, type=type) return self.REQUEST.RESPONSE.redirect("manage_layouts?type=%s" % url_quote(type)) ## Composables ZMI tab security.declareProtected(ManagePortal, "manage_composables") def manage_composables(self, REQUEST, manage_tabs_message=None): """ manage composables """ registered_composables = self.getRegisteredComposables() registered_composables.sort() archePortalTypes = self.getRegisteredArchePortalTypes() unregistered_composables = [pt for pt in archePortalTypes if pt not in registered_composables] unregistered_composables.sort() return self._manage_composables( REQUEST, registered_composables=registered_composables, unregistered_composables=unregistered_composables ) security.declareProtected(ManagePortal, "manage_addComposables") def manage_addComposables(self, REQUEST, manage_tabs_message=None, types=None): """ register composables """ if types is None: types = [] for type in types: self.registerAsComposable(type) return self.REQUEST.RESPONSE.redirect("manage_composables") security.declareProtected(ManagePortal, "manage_unregisterComposable") def manage_unregisterComposable(self, REQUEST, type=None): """ unregister composable """ if type is not None: self.unregisterAsComposable(type) return self.REQUEST.RESPONSE.redirect("manage_composables") ## Manage viewlets per composable ZMI view security.declareProtected(ManagePortal, "manage_viewlets") def manage_viewlets(self, REQUEST, manage_tabs_message=None, type=None): """ manage viewlets """ def viewlet_sort(a, b): return cmp(a.title, b.title) if type is not None: registered_viewlets = self.getRegisteredViewletsForType(type) registered_viewlets.sort(viewlet_sort) use_default_viewlets = self.getTypeUseDefaultSetup(type) allViewlets = self.getAllViewlets() if use_default_viewlets: unregistered_viewlets = allViewlets else: unregistered_viewlets = [pt for pt in allViewlets if pt not in registered_viewlets] unregistered_viewlets.sort(viewlet_sort) nodefault = self.noDefaultViewletForType(type) return self._manage_viewlets( REQUEST, type=type, registered_viewlets=registered_viewlets, unregistered_viewlets=unregistered_viewlets, nodefault=nodefault, use_default_viewlets=use_default_viewlets, ) security.declareProtected(ManagePortal, "manage_addViewlets") def manage_addViewlets(self, REQUEST, manage_tabs_message=None, type=None, viewlets=None): """ register viewlets for type """ if type is not None: if viewlets is None: viewlets = [] for viewlet_id in viewlets: viewlet = self.getViewletById(viewlet_id) if viewlet: self.registerViewletForType(viewlet, type) # return self.manage_viewlets(REQUEST, type=type) return self.REQUEST.RESPONSE.redirect("manage_viewlets?type=%s" % url_quote(type)) security.declareProtected(ManagePortal, "manage_unregisterViewlet") def manage_unregisterViewlet(self, REQUEST, manage_tabs_message=None, type=None, viewlet_id=None): """ unregister viewlets for type """ if type is not None: viewlet = self.getViewletById(viewlet_id) if viewlet: self.unregisterViewletForType(viewlet, type) # return self.manage_viewlets(REQUEST, type=type) return self.REQUEST.RESPONSE.redirect("manage_viewlets?type=%s" % url_quote(type)) security.declareProtected(ManagePortal, "manage_defaultViewlet") def manage_defaultViewlet(self, REQUEST, manage_tabs_message=None, type=None, default=None): """ set default viewlet for type """ if type is not None: if default == "nodefault": self.clearDefaultViewletForType(type) else: viewlet = self.getViewletById(default) if viewlet: self.setDefaultViewletForType(viewlet, type) # return self.manage_viewlets(REQUEST, type=type) return self.REQUEST.RESPONSE.redirect("manage_viewlets?type=%s" % url_quote(type)) ## Viewlets management def registerAsComposable(self, items): if type(items) not in (TupleType, ListType): items = (items,) for item in items: self._viewlet_registry.registerContentType(item) self.updateKupuLibraryTool() def unregisterAsComposable(self, items): if type(items) not in (TupleType, ListType): items = (items,) for item in items: self._viewlet_registry.unregisterContentType(item) self.updateKupuLibraryTool() def getRegisteredComposables(self): return self._viewlet_registry.getContentTypes() def isComposable(self, type): return self._viewlet_registry.isContentTypeRegistered(type) def updateKupuLibraryTool(self): try: kt = getToolByName(self, KUPU_TOOL_ID) except AttributeError: return resource_list = [resource for resource in self.getRegisteredComposables() if not resource == DEFAULT] kt.addResourceType(COMPOSABLE, resource_list) def clearViewletRegistry(self): self._viewlet_registry.clear() security.declareProtected(ManagePortal, "registerViewlet") def registerViewlet(self, id, description, skin_method): from Products.CompositePack import viewlet viewlets = getattr(self, VIEWLETS) viewlet.addViewlet(viewlets, id=id) result = getattr(viewlets, id) result.setTitle(description) result.setSkinMethod(skin_method) return result security.declareProtected(ManagePortal, "unregisterViewlet") def unregisterViewlet(self, id): viewlets = getattr(self, VIEWLETS) viewlets.manage_delObjects([id]) def getAllViewlets(self): return self.viewlets.objectValues() def registerViewletForType(self, viewlet, type): self._viewlet_registry.registerForType(viewlet.getId(), type) def unregisterViewletForType(self, viewlet, type, force=False): self._viewlet_registry.unregisterForType(viewlet.getId(), type, force) def getViewletById(self, id): if hasattr(aq_base(self.viewlets), id): return getattr(self.viewlets, id) else: return None def getRegisteredViewletsForType(self, type): result = [self.getViewletById(viewlet_id) for viewlet_id in self._viewlet_registry.getForType(type)] result = [item for item in result if item] return result def setDefaultViewletForType(self, viewlet, type): self._viewlet_registry.setDefaultForType(viewlet.getId(), type) def clearDefaultViewletForType(self, type): self._viewlet_registry.setDefaultForType(None, type) def getDefaultViewletForType(self, type): viewlet_id = self._viewlet_registry.getDefaultForType(type) return self.getViewletById(viewlet_id) def getTypeUseDefaultSetup(self, type): return self._viewlet_registry.getTypeUseDefaultSetup(type) def getTypeUseDefaultFromDefaultSetup(self, type): return self._viewlet_registry.getTypeUseDefaultFromDefaultSetup(type) def noDefaultViewletForType(self, type): result = False try: viewlet_id = self._viewlet_registry.getDefaultForType(type) except CompositePackError: result = True return result ## viewlets for default setup def registerViewletForDefaultSetup(self, viewlet): self._viewlet_registry.registerForType(viewlet.getId(), DEFAULT) def unregisterViewletForDefaultSetup(self, viewlet, force=False): self._viewlet_registry.unregisterForType(viewlet.getId(), DEFAULT, force) def getRegisteredViewletsForDefaultSetup(self): result = [self.getViewletById(viewlet_id) for viewlet_id in self._viewlet_registry.getForType(DEFAULT)] result = [item for item in result if item] return result def setDefaultViewletForDefaultSetup(self, viewlet): self._viewlet_registry.setDefaultForType(viewlet.getId(), DEFAULT) def clearDefaultViewletForDefaultSetup(self): self._viewlet_registry.setDefaultForType(None, DEFAULT) def getDefaultViewletForDefaultSetup(self): viewlet_id = self._viewlet_registry.getDefaultForType(DEFAULT) return self.getViewletById(viewlet_id) def noDefaultViewletForDefaultSetup(self): result = False try: viewlet_id = self._viewlet_registry.getDefaultForType(DEFAULT) except CompositePackError: result = True return result ## Layouts management def registerAsComposite(self, items): if type(items) not in (TupleType, ListType): items = (items,) for item in items: self._layout_registry.registerContentType(item) def unregisterAsComposite(self, items): if type(items) not in (TupleType, ListType): items = (items,) for item in items: self._layout_registry.unregisterContentType(item) def getRegisteredComposites(self): return self._layout_registry.getContentTypes() def isComposite(self, type): return self._layout_registry.isContentTypeRegistered(type) def clearLayoutRegistry(self): self._layout_registry.clear() security.declareProtected(ManagePortal, "registerLayout") def registerLayout(self, id, description, skin_method): from Products.CompositePack import viewlet layouts = getattr(self, LAYOUTS) viewlet.addLayout(layouts, id=id) result = getattr(layouts, id) result.setTitle(description) result.setSkinMethod(skin_method) return result security.declareProtected(ManagePortal, "unregisterLayout") def unregisterLayout(self, id): layouts = getattr(self, LAYOUTS) layouts.manage_delObjects([id]) def registerLayoutForType(self, layout, type): # If the type is not registered yet, implicitly register it. if not self._layout_registry.isContentTypeRegistered(type): self._layout_registry.registerContentType(type) self._layout_registry.registerForType(layout.getId(), type) def unregisterLayoutForType(self, layout, type, force=False): self._layout_registry.unregisterForType(layout.getId(), type, force) def getLayoutById(self, id): if hasattr(aq_base(self.layouts), id): return getattr(self.layouts, id) else: return None def getAllLayouts(self): return self.layouts.objectValues() def getRegisteredLayoutsForType(self, type): layouts = self._layout_registry.getForType(type) if layouts is None: layouts = self.layouts.objectIds() result = [self.getLayoutById(layout_id) for layout_id in layouts] result = [item for item in result if item] return result def setDefaultLayoutForType(self, layout, type): self._layout_registry.setDefaultForType(layout.getId(), type) def clearDefaultLayoutForType(self, type): self._layout_registry.setDefaultForType(None, type) def getDefaultLayoutForType(self, type): layout_id = self._layout_registry.queryDefaultForType(type, default=None) if not layout_id or not self.getLayoutById(layout_id): layout_id = self.getDefaultLayout() return self.getLayoutById(layout_id) def noDefaultLayoutForType(self, type): result = False try: layout_id = self._layout_registry.getDefaultForType(type) except CompositePackError: result = True return result security.declareProtected(ManagePortal, "manage_selectViewlets") def manage_selectViewlets(self, REQUEST, manage_tabs_message=None): """Manage association between types and viewlets. """ vbt = self._viewlets_by_type ti = self._listTypeInfo() types_info = [] # Viewlet IDs. All viewlets are available for # all content types for now, but this may change in the # future. viewlet_info = [{"id": ob.getId(), "title": ob.title_or_id()} for ob in self.viewlets.objectValues()] viewlet_info.sort(lambda x, y: cmp(x["title"], y["title"])) available_viewlets = viewlet_info[:] viewlet_info.insert(0, {"id": DEFAULT, "title": "use Default Setup"}) for t in ti: id = t.getId() title = t.Title() if title == id: title = None if vbt is not None and vbt.has_key(id): viewlets = vbt[id].viewlets default_per_type = vbt[id].default else: viewlets = (DEFAULT,) default_per_type = DEFAULT types_info.append( { "id": id, "title": title, "viewlets": viewlets, "default": default_per_type, "viewlet_info": viewlet_info, } ) return self._manage_selectViewlets( REQUEST, default_viewlets=self._default_viewlets, default_default=self._default_default, types_info=types_info, available_viewlets=available_viewlets, ) _manage_selectViewlets = PageTemplateFile("selectViewlets.pt", zmi_dir) security.declareProtected(ManagePortal, "manage_changeViewlets") def manage_changeViewlets(self, default_viewlets, default_default, props=None, REQUEST=None): """ Changes which viewlets apply to objects of which type. """ if props is None: props = REQUEST # Set up the default viewlets. self.setDefaultViewlets(default_viewlets, default_default) ti = self._listTypeInfo() # Set up the viewlets by type. for t in ti: type = t.getId() field_name = "viewlets_%s" % type viewlet_ids = tuple(props.get(field_name, (DEFAULT,))) field_name = "default_%s" % type default_viewlet = props.get(field_name, DEFAULT).strip() self.setViewletsForType(type, viewlet_ids, default_viewlet) if REQUEST is not None: return self.manage_selectViewlets(REQUEST, manage_tabs_message="Changed.") security.declareProtected(ManagePortal, "setDefaultViewlets") def setViewletsForType(self, type, viewlet_ids, default_viewlet): """ Setup viewlets used by type. """ if viewlet_ids == (DEFAULT,): self._viewlet_registry.setTypeUseDefaultSetup(type) viewlet_ids = self._viewlet_registry.getForType(type) viewlets = [self.getViewletById(viewlet_id) for viewlet_id in viewlet_ids] else: self._viewlet_registry.clearForType(type) viewlets = [self.getViewletById(viewlet_id) for viewlet_id in viewlet_ids] for viewlet in viewlets: self.registerViewletForType(viewlet, type) if default_viewlet == DEFAULT: default_viewlet = self.getDefaultViewletForDefaultSetup() if default_viewlet in viewlets: self._viewlet_registry.setTypeUseDefaultFromDefaultSetup(type) else: raise CompositePackError, "default_viewlet not among viewlet_ids" else: default_viewlet = self.getViewletById(default_viewlet) if default_viewlet in viewlets: self.setDefaultViewletForType(default_viewlet, type) else: raise CompositePackError, "default_viewlet not among viewlet_ids" def old_setViewletsForType(self, type, viewlet_ids, default_viewlet): vbt = self._viewlets_by_type if vbt is None: self._viewlets_by_type = vbt = PersistentMapping() if viewlet_ids == (DEFAULT,) and default_viewlet == DEFAULT: # Remove from vbt. if vbt.has_key(type): del vbt[type] else: viewlet_ids = filter(lambda x: x != DEFAULT, viewlet_ids) ids = [] for viewlet_id in viewlet_ids: if viewlet_id: if not self.getViewletById(viewlet_id): raise ValueError, ('"%s" is not a ' "registered viewlet." % viewlet_id) ids.append(viewlet_id) if default_viewlet == DEFAULT: if self._default_default not in viewlet_ids: raise ValueError, ( "For type %s, the default viewlet (%s) " "is not among viewlets " "(%s)." % (type, self._default_default, viewlet_ids) ) elif not ( (not viewlet_ids and default_viewlet in self._default_viewlets) or default_viewlet in viewlet_ids ): if not viewlet_ids: viewlet_ids = self._default_viewlets raise ValueError, ( "For type %s, the default viewlet " "(%s) is not among viewlets " "(%s)." % (type, default_viewlet, viewlet_ids) ) vft = ViewletsForType() if not ids: ids = (DEFAULT,) vft.viewlets = tuple(ids) vft.default = default_viewlet vbt[type] = vft security.declareProtected(ManagePortal, "setDefaultViewlets") def setDefaultViewlets(self, viewlet_ids, default_viewlet): """ Setup viewlets used by types for which nothing has been setup. """ self._viewlet_registry.clearForType(DEFAULT) viewlets = [self.getViewletById(viewlet_id) for viewlet_id in viewlet_ids] for viewlet in viewlets: self.registerViewletForDefaultSetup(viewlet) default_viewlet = self.getViewletById(default_viewlet) if default_viewlet in viewlets: self.setDefaultViewletForDefaultSetup(default_viewlet) else: raise CompositePackError, "default_viewlet not among viewlet_ids" def old_setDefaultViewlets(self, viewlet_ids, default_viewlet): ids = [] for viewlet_id in viewlet_ids: if viewlet_id: if not self.getViewletById(viewlet_id): raise ValueError, ('Default setup : "%s" is not a registered viewlet.' % viewlet_id) ids.append(viewlet_id) if default_viewlet not in ids: raise ValueError, ( "The default viewlet (%s) of the default " "setup should be among the " "viewlets (%s)." % (default_viewlet, viewlet_ids) ) self._default_viewlets = tuple(ids) self._default_default = default_viewlet security.declarePrivate("_listTypeInfo") def _listTypeInfo(self): """ List the portal types which are available. """ pt = getToolByName(self, "portal_types", None) at = getToolByName(self, "archetype_tool", None) if (pt is None) or (at is None): return () else: meta_types = [ ty["meta_type"] for ty in at.listRegisteredTypes() if IReferenceable.isImplementedByInstancesOf(ty["klass"]) ] tis = [t for t in pt.objectValues() if t.content_meta_type in meta_types] tis.sort(lambda a, b: cmp(a.Title(), b.Title())) return tis def queryDefaultLayout(self, default=None): layout_id = self._default_layout if self.getLayoutById(layout_id) is None: return default return layout_id def getDefaultLayout(self): layout_id = self._default_layout if self.getLayoutById(layout_id) is None: raise CompositePackError, ("Tool default layout %s is no more " "registered" % layout_id) return layout_id def setDefaultLayout(self, layout_id): if self.getLayoutById(layout_id) is None: raise CompositePackError, ("%s is not a registered " "layout" % layout_id) self._default_layout = layout_id def getViewletsFor(self, obj=None): """ Get viewlets for a given object """ type_id = None if obj is not None: type_id = obj.getTypeInfo().getId() return self.getViewletsForType(type_id) def getViewletsForType(self, portal_type=None): """ Get viewlets for a given type Return a dict where: - 'default' value is the default viewlet struct - 'viewlets' value is a list of structs with the other viewlets Each struct is composed of: - Viewlet id - Viewlet title - Viewlet object May return None. """ try: default = self.getDefaultViewletForType(portal_type).getId() except CompositePackError: default = self.getDefaultViewletForDefaultSetup().getId() viewlets = {} registered_viewlets = self.getRegisteredViewletsForType(portal_type) if not registered_viewlets: registered_viewlets = self.getRegisteredViewletsForDefaultSetup() for viewlet in registered_viewlets: id = viewlet.getId() viewlets[id] = {"id": id, "title": viewlet.title_or_id(), "viewlet": viewlet} viewlets_info = viewlets.values() if viewlets.has_key(default): default_viewlet = viewlets[default] del viewlets[default] viewlets_info = viewlets.values() else: default_viewlet = viewlets_info.pop() return {"default": default_viewlet, "viewlets": viewlets_info} def old_getViewletsForType(self, portal_type=None): vbt = self._viewlets_by_type if vbt is not None: info = vbt.get(portal_type) if info is None: # Return default viewlets default = self._default_default viewlets = self._default_viewlets else: default = info.default if default == DEFAULT: default = self._default_default viewlets = info.viewlets if viewlets == (DEFAULT,): viewlets = self._default_viewlets else: # Return default viewlets default = self._default_default viewlets = self._default_viewlets v_names = tuple(viewlets) + (default,) v_names = filter(lambda x: x != DEFAULT, v_names) viewlets = {} for name in v_names: viewlet = self.getViewletById(name) if viewlet is None: continue viewlets[name] = {"id": name, "title": viewlet.title_or_id(), "viewlet": viewlet} if not viewlets: return None viewlets_info = viewlets.values() if viewlets.has_key(default): default_viewlet = viewlets[default] del viewlets[default] viewlets_info = viewlets.values() else: default_viewlet = viewlets_info.pop() return {"default": default_viewlet, "viewlets": viewlets_info} def findSnippets(self, **kwargs): """ Find snippets for use as Composite Element targets Those can include: - Filesystem Composite Snippets - Registered Viewlets In the case where a 'context' keyword argument is passed, the viewlets returned are only those that apply to the context. """ st = getToolByName(self, "portal_skins") ct = getToolByName(self, "portal_catalog") f_params = {"search_sub": 1} c_params = {"portal_type": "CompositePack Viewlet"} mt = kwargs.get("meta_type") if mt is not None: f_params["obj_metatypes"] = mt else: f_params["obj_metatypes"] = ["Filesystem Composite Snippet"] text = kwargs.get("SearchableText") if mt is not None: f_params["obj_searchterm"] = text c_params["SearchableText"] = text f_res = st.ZopeFind(st, **f_params) s_res = ct(**c_params) context = kwargs.get("context") if context is not None: v_info = self.getViewletsFor(context) if v_info is not None: v_info = v_info.get("default", ()) + v_info.get("viewlets", ()) v_ids = [v["id"] for v in v_info] s_res = filter(lambda b: b.id in v_ids, s_res) result = [t for p, t in f_res] templates = [b.getObject().getTemplate() for b in s_res] result.extend(templates) return templates
class CompositeTool(BaseTool, Folder): """ CompositePack Tool """ implements(ICompositeTool) id = TOOL_ID meta_type = 'CompositePack Tool' security = ClassSecurityInfo() _viewlets_by_type = None # PersistentMapping _default_viewlets = ('default_viewlet', 'link_viewlet') _default_default = 'default_viewlet' _default_layout = '' _manage_composites = PageTemplateFile('composites.pt', zmi_dir) _manage_composables = PageTemplateFile('composables.pt', zmi_dir) _manage_layouts = PageTemplateFile('layouts.pt', zmi_dir) _manage_viewlets = PageTemplateFile('viewlets.pt', zmi_dir) macros_template = PageTemplateFile('macros.pt', zmi_dir) manage_options = insert_zmi_tab_after('Contents', { 'label': 'Composites', 'action': 'manage_composites' }, Folder.manage_options) manage_options = insert_zmi_tab_after('Composites', { 'label': 'Composables', 'action': 'manage_composables' }, manage_options) def __init__(self): Folder.__init__(self) BaseTool.__init__(self) self._layout_registry = LayoutRegistry() self._viewlet_registry = ViewletRegistry() def __repr__(self): return "CompositePack Tool" security.declarePublic("moveAndDelete") def moveAndDelete(self, move_source_paths="", move_target_path="", move_target_index="", delete_source_paths="", composite_path="", REQUEST=None): """Move and/or delete elements. """ portal = getToolByName(self, 'portal_url').getPortalObject() # Try to get translation service for status messages translation_service = getToolByName(self, 'translation_service', None) if translation_service: utranslate = translation_service.utranslate # else I won't translate at all try: compo = portal.restrictedTraverse(composite_path) except AttributeError: # We cannot traverse towards the asked composite path, this might # happen when another user deleted the navigation page where we are # dragging an item to a new location. # Or in short: composite_path no longer exists at this place. error = 'The page you were working on has been moved or deleted by another user.' if translation_service: # Translate if possible message = utranslate('compopack', 'navigation_page_deleted_or_moved', {}, self, default=error) else: # We don't have a translation service? Then we will just serve # the default English error message = error status_message = '?portal_status_message=' + message if REQUEST: # Redirect to portal root with a status message, because # current document no longer exists at this place. url = getToolByName(self, 'portal_url')() url += status_message REQUEST.RESPONSE.redirect(url) return try: BaseTool.moveAndDelete(self, move_source_paths, move_target_path, move_target_index, delete_source_paths, REQUEST) except AttributeError: # Item cannot be moved or deleted because the item within this page has # been either deleted or moved to another location. error = 'The item you tried to move or delete was already touched by another user.' if translation_service: # Translate our error message = utranslate('compopack', 'item_touched_by_other_user', {}, self, default=error) status_message = '?portal_status_message=' + message else: # or not... message = error status_message = '?portal_status_message=' + message if REQUEST: # Redirect to same (updated) page with a smart remark url = REQUEST['HTTP_REFERER'].split('?')[0] url += status_message REQUEST.RESPONSE.redirect(url) return if REQUEST: # Change was succesful so remove any standing error messages and # reload the page url = REQUEST['HTTP_REFERER'].split('?')[0] REQUEST.RESPONSE.redirect(url) security.declarePrivate('getMapMetatypesPortalTypes') def getMapMetatypesPortalTypes(self): # compute a map of meta_types and corresponding portal_types tt = getToolByName(self, "portal_types") type_infos = tt.listTypeInfo() meta_portal = {} for ti in type_infos: if meta_portal.has_key(ti.content_meta_type): meta_portal[ti.content_meta_type].append(ti.getId()) else: meta_portal[ti.content_meta_type] = [ti.getId()] return meta_portal security.declarePrivate('getRegisteredCompositePortalTypes') def getRegisteredCompositePortalTypes(self): meta_portal = self.getMapMetatypesPortalTypes() arche_data = listTypes() result = [] for arche_type in arche_data: if hasattr(arche_type['klass'], 'cp_view'): result.extend(meta_portal.get(arche_type['meta_type'], [])) return result security.declarePrivate('getRegisteredArchePortalTypes') def getRegisteredArchePortalTypes(self): meta_portal = self.getMapMetatypesPortalTypes() arche_data = listTypes() result = [] for arche_type in arche_data: result.extend(meta_portal.get(arche_type['meta_type'], [])) return result ## Composites ZMI tab security.declareProtected(ManagePortal, 'manage_composites') def manage_composites(self, REQUEST, manage_tabs_message=None): ''' manage composites ''' registered_composites = self.getRegisteredComposites() registered_composites.sort() compositePortalTypes = self.getRegisteredCompositePortalTypes() unregistered_composites = [ pt for pt in compositePortalTypes if pt not in registered_composites ] unregistered_composites.sort() default_layout = self.queryDefaultLayout() all_layouts = self.getAllLayouts() return self._manage_composites( REQUEST, registered_composites=registered_composites, unregistered_composites=unregistered_composites, default_layout=default_layout, all_layouts=all_layouts) security.declareProtected(ManagePortal, 'manage_addComposites') def manage_addComposites(self, REQUEST, manage_tabs_message=None, types=None): ''' register composites ''' if types is None: types = [] for type in types: self.registerAsComposite(type) return self.REQUEST.RESPONSE.redirect('manage_composites') security.declareProtected(ManagePortal, 'manage_unregisterComposite') def manage_unregisterComposite(self, REQUEST, type=None): ''' unregister composite ''' if type is not None: self.unregisterAsComposite(type) return self.REQUEST.RESPONSE.redirect('manage_composites') security.declareProtected(ManagePortal, 'manage_setDefaultLayout') def manage_setDefaultLayout(self, REQUEST, layout_id=None): ''' set default layout ''' if layout_id is not None: self.setDefaultLayout(layout_id) return self.REQUEST.RESPONSE.redirect('manage_composites') ## Manage layouts per composite ZMI view security.declareProtected(ManagePortal, 'manage_layouts') def manage_layouts(self, REQUEST, manage_tabs_message=None, type=None): ''' manage layouts ''' def layout_sort(a, b): return cmp(a.title, b.title) if type is not None: registered_layouts = self.getRegisteredLayoutsForType(type) registered_layouts.sort(layout_sort) allLayouts = self.getAllLayouts() unregistered_layouts = [ pt for pt in allLayouts if pt not in registered_layouts ] unregistered_layouts.sort(layout_sort) nodefault = self.noDefaultLayoutForType(type) default_layout = self.getLayoutById(self.getDefaultLayout()).title return self._manage_layouts( REQUEST, type=type, registered_layouts=registered_layouts, unregistered_layouts=unregistered_layouts, nodefault=nodefault, default_layout=default_layout) security.declareProtected(ManagePortal, 'manage_addLayouts') def manage_addLayouts(self, REQUEST, manage_tabs_message=None, type=None, layouts=None): ''' register layouts for type ''' if type is not None: if layouts is None: layouts = [] for layout_id in layouts: layout = self.getLayoutById(layout_id) if layout: self.registerLayoutForType(layout, type) #return self.manage_layouts(REQUEST, type=type) return self.REQUEST.RESPONSE.redirect('manage_layouts?type=%s' % url_quote(type)) security.declareProtected(ManagePortal, 'manage_unregisterLayout') def manage_unregisterLayout(self, REQUEST, manage_tabs_message=None, type=None, layout_id=None): ''' unregister layouts for type ''' if type is not None: layout = self.getLayoutById(layout_id) if layout: self.unregisterLayoutForType(layout, type) #return self.manage_layouts(REQUEST, type=type) return self.REQUEST.RESPONSE.redirect('manage_layouts?type=%s' % url_quote(type)) security.declareProtected(ManagePortal, 'manage_defaultLayout') def manage_defaultLayout(self, REQUEST, manage_tabs_message=None, type=None, default=None): ''' set default layout for type ''' if type is not None: if default == 'nodefault': self.clearDefaultLayoutForType(type) else: layout = self.getLayoutById(default) if layout: self.setDefaultLayoutForType(layout, type) #return self.manage_layouts(REQUEST, type=type) return self.REQUEST.RESPONSE.redirect('manage_layouts?type=%s' % url_quote(type)) ## Composables ZMI tab security.declareProtected(ManagePortal, 'manage_composables') def manage_composables(self, REQUEST, manage_tabs_message=None): ''' manage composables ''' registered_composables = self.getRegisteredComposables() registered_composables.sort() archePortalTypes = self.getRegisteredArchePortalTypes() unregistered_composables = [ pt for pt in archePortalTypes if pt not in registered_composables ] unregistered_composables.sort() return self._manage_composables( REQUEST, registered_composables=registered_composables, unregistered_composables=unregistered_composables) security.declareProtected(ManagePortal, 'manage_addComposables') def manage_addComposables(self, REQUEST, manage_tabs_message=None, types=None): ''' register composables ''' if types is None: types = [] for type in types: self.registerAsComposable(type) return self.REQUEST.RESPONSE.redirect('manage_composables') security.declareProtected(ManagePortal, 'manage_unregisterComposable') def manage_unregisterComposable(self, REQUEST, type=None): ''' unregister composable ''' if type is not None: self.unregisterAsComposable(type) return self.REQUEST.RESPONSE.redirect('manage_composables') ## Manage viewlets per composable ZMI view security.declareProtected(ManagePortal, 'manage_viewlets') def manage_viewlets(self, REQUEST, manage_tabs_message=None, type=None): ''' manage viewlets ''' def viewlet_sort(a, b): return cmp(a.title, b.title) if type is not None: registered_viewlets = self.getRegisteredViewletsForType(type) registered_viewlets.sort(viewlet_sort) use_default_viewlets = self.getTypeUseDefaultSetup(type) allViewlets = self.getAllViewlets() if use_default_viewlets: unregistered_viewlets = allViewlets else: unregistered_viewlets = [ pt for pt in allViewlets if pt not in registered_viewlets ] unregistered_viewlets.sort(viewlet_sort) nodefault = self.noDefaultViewletForType(type) return self._manage_viewlets( REQUEST, type=type, registered_viewlets=registered_viewlets, unregistered_viewlets=unregistered_viewlets, nodefault=nodefault, use_default_viewlets=use_default_viewlets) security.declareProtected(ManagePortal, 'manage_addViewlets') def manage_addViewlets(self, REQUEST, manage_tabs_message=None, type=None, viewlets=None): ''' register viewlets for type ''' if type is not None: if viewlets is None: viewlets = [] for viewlet_id in viewlets: viewlet = self.getViewletById(viewlet_id) if viewlet: self.registerViewletForType(viewlet, type) #return self.manage_viewlets(REQUEST, type=type) return self.REQUEST.RESPONSE.redirect('manage_viewlets?type=%s' % url_quote(type)) security.declareProtected(ManagePortal, 'manage_unregisterViewlet') def manage_unregisterViewlet(self, REQUEST, manage_tabs_message=None, type=None, viewlet_id=None): ''' unregister viewlets for type ''' if type is not None: viewlet = self.getViewletById(viewlet_id) if viewlet: self.unregisterViewletForType(viewlet, type) #return self.manage_viewlets(REQUEST, type=type) return self.REQUEST.RESPONSE.redirect('manage_viewlets?type=%s' % url_quote(type)) security.declareProtected(ManagePortal, 'manage_defaultViewlet') def manage_defaultViewlet(self, REQUEST, manage_tabs_message=None, type=None, default=None): ''' set default viewlet for type ''' if type is not None: if default == 'nodefault': self.clearDefaultViewletForType(type) else: viewlet = self.getViewletById(default) if viewlet: self.setDefaultViewletForType(viewlet, type) #return self.manage_viewlets(REQUEST, type=type) return self.REQUEST.RESPONSE.redirect('manage_viewlets?type=%s' % url_quote(type)) ## Viewlets management def registerAsComposable(self, items): if type(items) not in (TupleType, ListType): items = (items, ) for item in items: self._viewlet_registry.registerContentType(item) self.updateKupuLibraryTool() def unregisterAsComposable(self, items): if type(items) not in (TupleType, ListType): items = (items, ) for item in items: self._viewlet_registry.unregisterContentType(item) self.updateKupuLibraryTool() def getRegisteredComposables(self): return self._viewlet_registry.getContentTypes() def isComposable(self, type): return self._viewlet_registry.isContentTypeRegistered(type) def updateKupuLibraryTool(self): try: kt = getToolByName(self, KUPU_TOOL_ID) except AttributeError: return resource_list = [ resource for resource in self.getRegisteredComposables() if not resource == DEFAULT ] kt.addResourceType(COMPOSABLE, resource_list) def clearViewletRegistry(self): self._viewlet_registry.clear() security.declareProtected(ManagePortal, 'registerViewlet') def registerViewlet(self, id, description, skin_method): from Products.CompositePack import viewlet viewlets = getattr(self, VIEWLETS) viewlet.addViewlet(viewlets, id=id) result = getattr(viewlets, id) result.setTitle(description) result.setSkinMethod(skin_method) return result security.declareProtected(ManagePortal, 'unregisterViewlet') def unregisterViewlet(self, id): viewlets = getattr(self, VIEWLETS) viewlets.manage_delObjects([id]) def getAllViewlets(self): return self.viewlets.objectValues() def registerViewletForType(self, viewlet, type): self._viewlet_registry.registerForType(viewlet.getId(), type) def unregisterViewletForType(self, viewlet, type, force=False): self._viewlet_registry.unregisterForType(viewlet.getId(), type, force) def getViewletById(self, id): if hasattr(aq_base(self.viewlets), id): return getattr(self.viewlets, id) else: return None def getRegisteredViewletsForType(self, type): result = [ self.getViewletById(viewlet_id) for viewlet_id in self._viewlet_registry.getForType(type) ] result = [item for item in result if item] return result def setDefaultViewletForType(self, viewlet, type): self._viewlet_registry.setDefaultForType(viewlet.getId(), type) def clearDefaultViewletForType(self, type): self._viewlet_registry.setDefaultForType(None, type) def getDefaultViewletForType(self, type): viewlet_id = self._viewlet_registry.getDefaultForType(type) return self.getViewletById(viewlet_id) def getTypeUseDefaultSetup(self, type): return self._viewlet_registry.getTypeUseDefaultSetup(type) def getTypeUseDefaultFromDefaultSetup(self, type): return self._viewlet_registry.getTypeUseDefaultFromDefaultSetup(type) def noDefaultViewletForType(self, type): result = False try: viewlet_id = self._viewlet_registry.getDefaultForType(type) except CompositePackError: result = True return result ## viewlets for default setup def registerViewletForDefaultSetup(self, viewlet): self._viewlet_registry.registerForType(viewlet.getId(), DEFAULT) def unregisterViewletForDefaultSetup(self, viewlet, force=False): self._viewlet_registry.unregisterForType(viewlet.getId(), DEFAULT, force) def getRegisteredViewletsForDefaultSetup(self): result = [ self.getViewletById(viewlet_id) for viewlet_id in self._viewlet_registry.getForType(DEFAULT) ] result = [item for item in result if item] return result def setDefaultViewletForDefaultSetup(self, viewlet): self._viewlet_registry.setDefaultForType(viewlet.getId(), DEFAULT) def clearDefaultViewletForDefaultSetup(self): self._viewlet_registry.setDefaultForType(None, DEFAULT) def getDefaultViewletForDefaultSetup(self): viewlet_id = self._viewlet_registry.getDefaultForType(DEFAULT) return self.getViewletById(viewlet_id) def noDefaultViewletForDefaultSetup(self): result = False try: viewlet_id = self._viewlet_registry.getDefaultForType(DEFAULT) except CompositePackError: result = True return result ## Layouts management def registerAsComposite(self, items): if type(items) not in (TupleType, ListType): items = (items, ) for item in items: self._layout_registry.registerContentType(item) def unregisterAsComposite(self, items): if type(items) not in (TupleType, ListType): items = (items, ) for item in items: self._layout_registry.unregisterContentType(item) def getRegisteredComposites(self): return self._layout_registry.getContentTypes() def isComposite(self, type): return self._layout_registry.isContentTypeRegistered(type) def clearLayoutRegistry(self): self._layout_registry.clear() security.declareProtected(ManagePortal, 'registerLayout') def registerLayout(self, id, description, skin_method): from Products.CompositePack import viewlet layouts = getattr(self, LAYOUTS) viewlet.addLayout(layouts, id=id) result = getattr(layouts, id) result.setTitle(description) result.setSkinMethod(skin_method) return result security.declareProtected(ManagePortal, 'unregisterLayout') def unregisterLayout(self, id): layouts = getattr(self, LAYOUTS) layouts.manage_delObjects([id]) def registerLayoutForType(self, layout, type): # If the type is not registered yet, implicitly register it. if not self._layout_registry.isContentTypeRegistered(type): self._layout_registry.registerContentType(type) self._layout_registry.registerForType(layout.getId(), type) def unregisterLayoutForType(self, layout, type, force=False): self._layout_registry.unregisterForType(layout.getId(), type, force) def getLayoutById(self, id): if hasattr(aq_base(self.layouts), id): return getattr(self.layouts, id) else: return None def getAllLayouts(self): return self.layouts.objectValues() def getRegisteredLayoutsForType(self, type): layouts = self._layout_registry.getForType(type) if layouts is None: layouts = self.layouts.objectIds() result = [self.getLayoutById(layout_id) for layout_id in layouts] result = [item for item in result if item] return result def setDefaultLayoutForType(self, layout, type): self._layout_registry.setDefaultForType(layout.getId(), type) def clearDefaultLayoutForType(self, type): self._layout_registry.setDefaultForType(None, type) def getDefaultLayoutForType(self, type): layout_id = self._layout_registry.queryDefaultForType(type, default=None) if not layout_id or not self.getLayoutById(layout_id): layout_id = self.getDefaultLayout() return self.getLayoutById(layout_id) def noDefaultLayoutForType(self, type): result = False try: layout_id = self._layout_registry.getDefaultForType(type) except CompositePackError: result = True return result security.declareProtected(ManagePortal, 'manage_selectViewlets') def manage_selectViewlets(self, REQUEST, manage_tabs_message=None): """Manage association between types and viewlets. """ vbt = self._viewlets_by_type ti = self._listTypeInfo() types_info = [] # Viewlet IDs. All viewlets are available for # all content types for now, but this may change in the # future. viewlet_info = [{ 'id': ob.getId(), 'title': ob.title_or_id() } for ob in self.viewlets.objectValues()] viewlet_info.sort(lambda x, y: cmp(x['title'], y['title'])) available_viewlets = viewlet_info[:] viewlet_info.insert(0, {'id': DEFAULT, 'title': 'use Default Setup'}) for t in ti: id = t.getId() title = t.Title() if title == id: title = None if vbt is not None and vbt.has_key(id): viewlets = vbt[id].viewlets default_per_type = vbt[id].default else: viewlets = (DEFAULT, ) default_per_type = DEFAULT types_info.append({ 'id': id, 'title': title, 'viewlets': viewlets, 'default': default_per_type, 'viewlet_info': viewlet_info }) return self._manage_selectViewlets( REQUEST, default_viewlets=self._default_viewlets, default_default=self._default_default, types_info=types_info, available_viewlets=available_viewlets) _manage_selectViewlets = PageTemplateFile('selectViewlets.pt', zmi_dir) security.declareProtected(ManagePortal, 'manage_changeViewlets') def manage_changeViewlets(self, default_viewlets, default_default, \ props=None, REQUEST=None): """ Changes which viewlets apply to objects of which type. """ if props is None: props = REQUEST # Set up the default viewlets. self.setDefaultViewlets(default_viewlets, default_default) ti = self._listTypeInfo() # Set up the viewlets by type. for t in ti: type = t.getId() field_name = 'viewlets_%s' % type viewlet_ids = tuple(props.get(field_name, (DEFAULT, ))) field_name = 'default_%s' % type default_viewlet = props.get(field_name, DEFAULT).strip() self.setViewletsForType(type, viewlet_ids, default_viewlet) if REQUEST is not None: return self.manage_selectViewlets(REQUEST, manage_tabs_message='Changed.') security.declareProtected(ManagePortal, 'setDefaultViewlets') def setViewletsForType(self, type, viewlet_ids, default_viewlet): """ Setup viewlets used by type. """ if viewlet_ids == (DEFAULT, ): self._viewlet_registry.setTypeUseDefaultSetup(type) viewlet_ids = self._viewlet_registry.getForType(type) viewlets = [ self.getViewletById(viewlet_id) for viewlet_id in viewlet_ids ] else: self._viewlet_registry.clearForType(type) viewlets = [ self.getViewletById(viewlet_id) for viewlet_id in viewlet_ids ] for viewlet in viewlets: self.registerViewletForType(viewlet, type) if default_viewlet == DEFAULT: default_viewlet = self.getDefaultViewletForDefaultSetup() if default_viewlet in viewlets: self._viewlet_registry.setTypeUseDefaultFromDefaultSetup(type) else: raise CompositePackError, 'default_viewlet not among viewlet_ids' else: default_viewlet = self.getViewletById(default_viewlet) if default_viewlet in viewlets: self.setDefaultViewletForType(default_viewlet, type) else: raise CompositePackError, 'default_viewlet not among viewlet_ids' def old_setViewletsForType(self, type, viewlet_ids, default_viewlet): vbt = self._viewlets_by_type if vbt is None: self._viewlets_by_type = vbt = PersistentMapping() if viewlet_ids == (DEFAULT, ) and default_viewlet == DEFAULT: # Remove from vbt. if vbt.has_key(type): del vbt[type] else: viewlet_ids = filter(lambda x: x != DEFAULT, viewlet_ids) ids = [] for viewlet_id in viewlet_ids: if viewlet_id: if not self.getViewletById(viewlet_id): raise ValueError, ('"%s" is not a ' 'registered viewlet.' % viewlet_id) ids.append(viewlet_id) if default_viewlet == DEFAULT: if self._default_default not in viewlet_ids: raise ValueError, ( 'For type %s, the default viewlet (%s) ' 'is not among viewlets ' '(%s).' % (type, self._default_default, viewlet_ids)) elif not ( (not viewlet_ids and default_viewlet in self._default_viewlets) or default_viewlet in viewlet_ids): if not viewlet_ids: viewlet_ids = self._default_viewlets raise ValueError, ('For type %s, the default viewlet ' '(%s) is not among viewlets ' '(%s).' % (type, default_viewlet, viewlet_ids)) vft = ViewletsForType() if not ids: ids = (DEFAULT, ) vft.viewlets = tuple(ids) vft.default = default_viewlet vbt[type] = vft security.declareProtected(ManagePortal, 'setDefaultViewlets') def setDefaultViewlets(self, viewlet_ids, default_viewlet): """ Setup viewlets used by types for which nothing has been setup. """ self._viewlet_registry.clearForType(DEFAULT) viewlets = [ self.getViewletById(viewlet_id) for viewlet_id in viewlet_ids ] for viewlet in viewlets: self.registerViewletForDefaultSetup(viewlet) default_viewlet = self.getViewletById(default_viewlet) if default_viewlet in viewlets: self.setDefaultViewletForDefaultSetup(default_viewlet) else: raise CompositePackError, 'default_viewlet not among viewlet_ids' def old_setDefaultViewlets(self, viewlet_ids, default_viewlet): ids = [] for viewlet_id in viewlet_ids: if viewlet_id: if not self.getViewletById(viewlet_id): raise ValueError, ( 'Default setup : "%s" is not a registered viewlet.' % viewlet_id) ids.append(viewlet_id) if default_viewlet not in ids: raise ValueError, ('The default viewlet (%s) of the default ' 'setup should be among the ' 'viewlets (%s).' % (default_viewlet, viewlet_ids)) self._default_viewlets = tuple(ids) self._default_default = default_viewlet security.declarePrivate('_listTypeInfo') def _listTypeInfo(self): """ List the portal types which are available. """ pt = getToolByName(self, 'portal_types', None) at = getToolByName(self, 'archetype_tool', None) if (pt is None) or (at is None): return () else: meta_types = [ ty['meta_type'] for ty in at.listRegisteredTypes() if IReferenceable.isImplementedByInstancesOf(ty['klass']) ] tis = [ t for t in pt.objectValues() if t.content_meta_type in meta_types ] tis.sort(lambda a, b: cmp(a.Title(), b.Title())) return tis def queryDefaultLayout(self, default=None): layout_id = self._default_layout if self.getLayoutById(layout_id) is None: return default return layout_id def getDefaultLayout(self): layout_id = self._default_layout if self.getLayoutById(layout_id) is None: raise CompositePackError, ("Tool default layout %s is no more " "registered" % layout_id) return layout_id def setDefaultLayout(self, layout_id): if self.getLayoutById(layout_id) is None: raise CompositePackError, ("%s is not a registered " "layout" % layout_id) self._default_layout = layout_id def getViewletsFor(self, obj=None): """ Get viewlets for a given object """ type_id = None if obj is not None: type_id = obj.getTypeInfo().getId() return self.getViewletsForType(type_id) def getViewletsForType(self, portal_type=None): """ Get viewlets for a given type Return a dict where: - 'default' value is the default viewlet struct - 'viewlets' value is a list of structs with the other viewlets Each struct is composed of: - Viewlet id - Viewlet title - Viewlet object May return None. """ try: default = self.getDefaultViewletForType(portal_type).getId() except CompositePackError: default = self.getDefaultViewletForDefaultSetup().getId() viewlets = {} registered_viewlets = self.getRegisteredViewletsForType(portal_type) if not registered_viewlets: registered_viewlets = self.getRegisteredViewletsForDefaultSetup() for viewlet in registered_viewlets: id = viewlet.getId() viewlets[id] = { 'id': id, 'title': viewlet.title_or_id(), 'viewlet': viewlet } viewlets_info = viewlets.values() if viewlets.has_key(default): default_viewlet = viewlets[default] del viewlets[default] viewlets_info = viewlets.values() else: default_viewlet = viewlets_info.pop() return {'default': default_viewlet, 'viewlets': viewlets_info} def old_getViewletsForType(self, portal_type=None): vbt = self._viewlets_by_type if vbt is not None: info = vbt.get(portal_type) if info is None: # Return default viewlets default = self._default_default viewlets = self._default_viewlets else: default = info.default if default == DEFAULT: default = self._default_default viewlets = info.viewlets if viewlets == (DEFAULT, ): viewlets = self._default_viewlets else: # Return default viewlets default = self._default_default viewlets = self._default_viewlets v_names = tuple(viewlets) + (default, ) v_names = filter(lambda x: x != DEFAULT, v_names) viewlets = {} for name in v_names: viewlet = self.getViewletById(name) if viewlet is None: continue viewlets[name] = { 'id': name, 'title': viewlet.title_or_id(), 'viewlet': viewlet } if not viewlets: return None viewlets_info = viewlets.values() if viewlets.has_key(default): default_viewlet = viewlets[default] del viewlets[default] viewlets_info = viewlets.values() else: default_viewlet = viewlets_info.pop() return {'default': default_viewlet, 'viewlets': viewlets_info} def findSnippets(self, **kwargs): """ Find snippets for use as Composite Element targets Those can include: - Filesystem Composite Snippets - Registered Viewlets In the case where a 'context' keyword argument is passed, the viewlets returned are only those that apply to the context. """ st = getToolByName(self, 'portal_skins') ct = getToolByName(self, 'portal_catalog') f_params = {'search_sub': 1} c_params = {'portal_type': 'CompositePack Viewlet'} mt = kwargs.get('meta_type') if mt is not None: f_params['obj_metatypes'] = mt else: f_params['obj_metatypes'] = ['Filesystem Composite Snippet'] text = kwargs.get('SearchableText') if mt is not None: f_params['obj_searchterm'] = text c_params['SearchableText'] = text f_res = st.ZopeFind(st, **f_params) s_res = ct(**c_params) context = kwargs.get('context') if context is not None: v_info = self.getViewletsFor(context) if v_info is not None: v_info = v_info.get('default', ()) + v_info.get('viewlets', ()) v_ids = [v['id'] for v in v_info] s_res = filter(lambda b: b.id in v_ids, s_res) result = [t for p, t in f_res] templates = [b.getObject().getTemplate() for b in s_res] result.extend(templates) return templates