Personal tools
You are here: Home Documentation Tutorials Switching Skins Use Case Two: Skin By Type of User
Support

Get Help

Join our chat rooms or support forums if you have more specific questions.

Plone Training
Learn how to design, build, and deploy a website in Plone through one of the numerous Plone training sessions around the world.
Find Plone training…
 
Document Actions

Use Case Two: Skin By Type of User

Example code for allowing certain users to switch skins.

George Lee

This Tutorial describes how Plone chooses a skin when you open a web page, and then describes the multiple ways that you can intervene to switch the skin. The Tutorial also discusses two common use cases, switching skins based on URL and the type of user (e.g., Anonymous or Authenticated).
Page 6 of 8.

Suppose that you want your site to use different skins depending on whether an anonymous user, member, manager, etc. is viewing the page.

The skin only needs to be determined at one point. So, a longer-lasting switch would work. And in fact, Access Rules are loaded early on while rendering a page, before the page is aware of who is viewing, so an Access Rule will also think that the current user is the Anonymous User. So, running a one-time script makes the most sense for this use case.

The following example sets up a user action that shows in in the personal bar, which allows certain users with a custom permission to perform that action and switch between the standard Plone Default skin, and a custom Public View skin. Our example is for a skin product MySkin, with a permission SWITCH_SKINS_PERMISSION = "MySkin: Switch Skins" defined in Products/MySkin/config.py.

We define a method in MySkin/Extensions/utils.py

from AccessControl import getSecurityManager, Unauthorized
from Acquisition import aq_base

from Products.CMFCore.utils import getToolByName

from Products.MySkin.config import SWITCH_SKINS_PERMISSION

def switchSkin(self, context):
skins_tool = getToolByName(self, 'portal_skins')
mtool = getToolByName(self, 'portal_membership')
if getSecurityManager().checkPermission(SWITCH_SKINS_PERMISSION, self):
member = mtool.getAuthenticatedMember()
if not hasattr(aq_base(member), 'portal_skin'):
member.setProperties(portal_skin = 'My Public View')
portal_skin = member.portal_skin
if portal_skin == 'My Public View':
member.setProperties(portal_skin = 'Plone Default')
else:
member.setProperties(portal_skin = 'My Public View')
skins_tool.updateSkinCookie()
else:
raise Unauthorized

In this case, the method switchSkin uses code that through-the-web (TTW) Python scripts cannot call. So we add it as an external method ext_switchSkin to the Plone site root, and then add a proxy script switchSkin in a skins folder:

## Script (Python) "switchSkin"
##bind container=container
##bind context=context
##bind namespace=
##bind script=script
##bind subpath=traverse_subpath
##parameters=
##title=Switch skin between my public skin and default Plone skin
##
context.portal_url.getPortalObject().ext_switchSkin(context)
context.REQUEST['RESPONSE'].redirect(context.REQUEST['HTTP_REFERER'])

Finally, we use portal_actions to add an action that shows the public view

  • Title: Public View
  • Id: publicskinswitch
  • URL (Expression): string:$portal_url/switchSkin
  • Condition (Expression): python:portal.getCurrentSkinName() != 'My Public View'
  • Permission: MySkin: Switch Skins
  • Category: User
  • Visible: True

and an action that returns to the Plone Default view

  • Title: Plone View
  • Id: ploneskinswitch
  • URL (Expression): string:$portal_url/switchSkin
  • Condition (Expression): python:portal.getCurrentSkinName() == 'My Public View'
  • Permission: MySkin: Switch Skins
  • Category: User
  • Visible: True

Voila! A user with the permission "MySkin: Switch Skins" will now see an option in the personal bar to switch skins. (Notice that one should not manually enter a URL to the switchSkin script, because the script will redirect to itself, resulting in an infinite loop.)

It would also be possible to create a script that fired every time somebody logged in, which switched the skin immediately for them -- although we don't supply the code here.

The Trouble With Cookies!

If we use cookies, then after somebody logs out, the cookie may continue to exist. In this case, an anonymous user will see the same skin as the logged-in user.

To avoid this issue, make sure to:

  • Avoid enabling the option for cookies to exist after the end of a session (by default this is disabled, but it can be changed in the Zope management screen for portal_skins).
  • Design all skins with the knowledge that any user can switch skins with enough technical savvy. Skins are not security!
  • Change the skin back to the default skin upon logging out -- for instance, by including the following code in a customized logout.cpy:
from Products.CMFCore.utils import getToolByName

skins_tool = getToolByName(context, 'portal_skins')
mtool = getToolByName(context, 'portal_membership')
member = mtool.getAuthenticatedMember()
try:
    member.setProperties(portal_skin = 'My Public View')
    skins_tool.updateSkinCookie()
    context.acl_users.logout(context.REQUEST)
except:
    pass
 
by George Lee last modified October 22, 2006 - 05:55 All content is copyright Plone Foundation and the individual contributors.

For any issues with the web site functionality, please file a ticket.

Please consult the policy on plone.org content if you want your content published on this site.

Servers and hosting by