I’m trying to apply a marker interface to requests depending on the current user. The idea is to offer different skins according to user preferences.
So I tried to use Middleware-like hooks. In configure.zcml:
<subscriber
for="Products.CMFCore.interfaces.ISiteRoot
zope.traversing.interfaces.IBeforeTraverseEvent"
handler=".layer.mark_layer"
/>
And in layer.py
def mark_layer(portal, event):
'''Conditional marking of the request according to the user
preferences.'''
request = event.request
portal_state = getMultiAdapter((portal, request), name="plone_portal_state")
anon = portal_state.anonymous()
print anon, portal.portal_membership.isAnonymousUser()
# more code here...
The problem is that plone always reports that the user is anonymous.
So, under those circumstances, how could I apply the marker interface?
Thanks in advance.
The user is not determined until after traversal has taken place. In Plone, the authentication and authorization of a user depends on the context and cannot be determined before traversal is complete.
Thus, you have to hook into the
IPubAfterTraversalinstead; it is passed the request after traversal has completed and a user has been determined.You’ll have to retrieve the portal using the
getSite()function instead:To be explicit: This means you cannot vary the object found during traversal based on the authenticated user, because authentication takes place after traversal is complete. Once rendering starts, then the user has been authenticated.
This means you cannot register a page for your per-user theme, and expect to be able to use that page in a URL path (
/path/to/context/@@user-specific-page). Anything looked up during response rendering is of course fair game, so viewlets, portlets, views looked up by code other than publication traversal, etc. can all be varied using your marker interface.