def testSelectedSkinHasProperCSSClass(self): st = getToolByName(self.folder, "portal_skins") skins = st.getSkinSelections() actions = self.menu.getMenuItems(self.folder, self.request) action = [a for a in actions if a["title"] == skins[0]][0] self.assertEqual("actionMenu", action["extra"]["class"]) set_selected_default_skin(self.folder, skins[0]) self.assertEqual(skins[0], get_selected_default_skin(self.folder)) actions = self.menu.getMenuItems(self.folder, self.request) action = [a for a in actions if a["title"] == skins[0]][0] self.assertEqual("actionMenuSelected", action["extra"]["class"])
def update(self): """Set selected skin as the default for the current folder.""" context = aq_inner(self.context) utils = getToolByName(context, "plone_utils") # Which skin is requested? skin_name = self.request.form.get("skin_name", None) if skin_name is not None: skins_tool = getToolByName(context, 'portal_skins') if skin_name not in skins_tool.getSkinSelections(): skin_name = None # Which skin is currently used as default skin, if any? current_skin = get_selected_default_skin(context) # Determine what needs to be done, and create or remove a # local site hook when needed. if skin_name is None and current_skin is None: utils.addPortalMessage(_(u"Nothing changed.")) elif skin_name == current_skin: utils.addPortalMessage(_(u"Nothing changed.")) elif skin_name is None and current_skin is not None: # Need to remove the hook. utils.addPortalMessage(_(u"No default skin selected anymore.")) remove_hook(context) else: # The normal case: a change to the default skin. utils.addPortalMessage(_(u"Skin changed.")) add_hook(context) # Finally set the default skin. Note that this is safe to # call when skin_name is None as well, as this cleans up a # possible earlier setting. set_selected_default_skin(context, skin_name) return self.request.RESPONSE.redirect(context.absolute_url())
def available(self): if self.context_state.is_portal_root(): # Just use the portal_skins tool, Luke! return False # This menu is also used to set the navigation root, when # allowed. if self._allowSetNavigationRoot(): return True if not self._manageSkinSettings(): return False # Only allow this menu on folders. if not (self.context_state.is_structural_folder() or self.context_state.is_default_page()): return False # Check if our property sheet is available. When not, then # this might be a second Plone site in the same Zope instance. # If we are not installed in this Plone Site, we do not want # to offer this menu item. if not self.tools.properties().get('editskin_switcher'): return False if get_selected_default_skin(self.folder): # We have previously selected a default skin, so we should # show the menu to make this clear (and possibly unset # it). return True skins_tool = getToolByName(self.context, 'portal_skins') if len(skins_tool.getSkinSelections()) < 2: # Nothing to choose. return False return True
def switch_skin(object, event): """Switch to the Sunburst Theme skin when we are editing. Note: when we bail out before the changeSkin call, then we show the normal theme, which presumably is a custom theme for this website. If we do the changeSkin call, this means we switch to the edit skin, which normally is the Sunburst Theme skin. """ request = event.request context = get_real_context(object) current_skin = context.getCurrentSkinName() skin_name = get_selected_default_skin(context) if skin_name is not None and not request.get('editskinswitched'): # We've specified a skin and are not in the edit skin. portal_skins = getToolByName(context, 'portal_skins', None) if (portal_skins is not None and skin_name not in portal_skins.getSkinSelections()): logger.warn("Non-existing skin %s set on %s", skin_name, context.absolute_url()) else: context.changeSkin(skin_name, request) set_theme_specific_layers(request, context, skin_name, current_skin) portal_props = getToolByName(context, 'portal_properties', None) if portal_props is None: return None editskin_props = portal_props.get('editskin_switcher') if editskin_props is None: return None # Okay, we have a property sheet we can use. edit_skin = editskin_props.getProperty('edit_skin', '') if force_login(request, editskin_props): # We have a header that forces us to be logged in; so add a # hook at the end of the traversal to check that we really are # logged in. request.post_traverse(check_auth, (request, )) # Check if we need authentication first, possibly in addition to # one of the other tests if need_authentication(request, editskin_props) and anonymous(request): logger.debug("need auth, but am anonymous: staying at normal skin.") return None # Try to find a reason for switching to the edit skin. When one # of the selected actions returns True, we switch the skin. switches = editskin_props.getProperty('switch_skin_action', ()) if not isinstance(switches, tuple): # Old data using a selection instead of multiple selection, # which returns a string instead of a tuple of strings. switches = (switches, ) found = False for switch in switches: method = methods.get(switch) if not method: continue if method(request, editskin_props): found = True break if not found: # No switching logger.debug("no switching, staying at normal skin") return None logger.debug("will switch to edit skin") # Use to preview default skin in edit skin mode if request.get('mutate_skin', '') == 'default': return None # Assume that if you get here you are switching to the edit skin # ... flag this for the purposes of caching / kss loading etc. request.set('editskinswitched', 1) # If the edit_skin does not exist, the next call is # intelligent enough to use the default skin instead. context.changeSkin(edit_skin, request) set_theme_specific_layers(request, context, edit_skin, current_skin) return None
def getMenuItems(self, context, request): """Return menu item entries in a TAL-friendly form.""" results = [] context_state = getMultiAdapter((context, request), name='plone_context_state') folder = context if not context_state.is_structural_folder(): folder = utils.parent(context) url = folder.absolute_url() current_skin = get_selected_default_skin(folder) skins_tool = getToolByName(context, "portal_skins") skin_selections = skins_tool.getSkinSelections() # Only add menu items for skins when we have a choice or when # we have previously selected a default skin. It could be # that this default skin has been removed and then we need a # way to unset it. tools = getMultiAdapter((context, request), name='plone_tools') if tools.membership().checkPermission(SetDefaultSkin, folder) and ( len(skin_selections) > 1 or current_skin): if current_skin and current_skin not in skin_selections: # Skin has been removed. skin = current_skin skin_title = utils.safe_unicode(skin) skin_id = utils.normalizeString(skin, folder, "utf-8") results.append( {"title": _(u"Warning: ${skin}", mapping={'skin': skin_title}), "description": _( u"Skin '${skin}' no longer exists. Selecting this " u"again will result in using the site default.", mapping=dict(skin=skin_title)), "action": "%s/@@switchDefaultSkin?skin_name=%s" % ( url, skin), "selected": True, "extra": { "is_skin_option": True, "id": "collective.editskinswitcher-skin-%s" % skin_id, "separator": False, "class": 'actionMenuSelected'}, "submenu": None, "icon": None, }) for skin in skin_selections: skin_id = utils.normalizeString(skin, folder, "utf-8") skin_title = utils.safe_unicode(skin) selected = skin == current_skin cssClass = selected and "actionMenuSelected" or "actionMenu" results.append( {"title": skin, "description": _(u"Use '${skin}' skin for this folder", mapping=dict(skin=skin_title)), "action": "%s/@@switchDefaultSkin?skin_name=%s" % ( url, skin), "selected": selected, "extra": { "is_skin_option": True, "id": "collective.editskinswitcher-skin-%s" % skin_id, "separator": False, "class": cssClass}, "submenu": None, "icon": None, }) # Add option to reset the default. if current_skin: # Use a fake id that is unlikely to be the id of an actual skin. skin_id = 'collective_set_default_editor_use_site_default' results.append( {"title": _(u"Use site default"), "description": u"", "action": "%s/@@switchDefaultSkin?skin_name=%s" % ( url, skin_id), "selected": False, "extra": { "is_skin_option": True, "id": "collective.editskinswitcher-skin-%s" % skin_id, "separator": 'actionSeparator', "class": 'actionMenu'}, "submenu": None, "icon": None, }) if tools.membership().checkPermission(SetNavigationRoot, folder): # Now add an option to set/unset the navigation root. menu_item = { "title": _(u"Navigation root"), "extra": { "is_skin_option": False, "id": "collective.editskinswitcher-set-navigation-root", "separator": 'actionSeparator', }, "submenu": None, "icon": None, } if INavigationRoot.providedBy(folder): menu_item["selected"] = True menu_item["cssClass"] = "actionMenuSelected" menu_item["description"] = _( u"No longer use this folder as a navigation root.") menu_item["action"] = "%s/@@unset-navigation-root" % (url) else: menu_item["selected"] = False menu_item["cssClass"] = "actionMenu" menu_item["description"] = _( u"Start using this folder as a navigation root.") menu_item["action"] = "%s/@@set-navigation-root" % (url) results.append(menu_item) return results