Question

Is it possible to make elements of a Diazo theme depend on the user role in Plone? For instance: I would like to offer a different header image in the theme for some specific roles, and have these change on the site as soon as the user logs in.

This question may be related, but I would prefer to manage it only through role assignments.

Was it helpful?

Solution

This might be possible by specifying a theme parameter. Untested, but you could define a parameter like this:

roles = python: portal_state.member().getRolesInContext(context)

or something like:

is_manager = python: 'Manager' in portal_state.member().getRolesInContext(context)

Then use that parameter in your rules.xml file. This would switch the theming off for managers:

<notheme if="$is_manager" />

That does nothing with headers, but you should be able to extrapolate from that.

OTHER TIPS

If you know how to handle Python code and create a browser view, you could define a browser view that gives back some css. I used the following code in a client project to insert some css that sets the nearest header.jpg as background, so you can have different backgrounds in different sections.

In configure.zcml:

<browser:page
    for="*"
    permission="zope.Public"
    name="header-image-css"
    class=".utils.HeaderImageCSS"
    />

In an utils.py file:

HEADER_IMAGE_CSS = """
#portal-header {
    background: url("%s") no-repeat scroll right top #FFFFFF;
    position: relative;
    z-index: 2;
}

"""


class HeaderImageCSS(BrowserView):
    """CSS for header image.

    We want the nearest header.jpg in the acquisition context.  For
    caching it is best to look up the image and return its
    absolute_url, instead of simply loading header.jpg in the current
    context.  It will work, but then the same image will be loaded by
    the browser for lots of different pages.

    This is meant to be used in the rules.xml of the Diazo theme, like this:

    <after css:theme="title" css:content="style" href="@@header-image-css" />

    Because we set the Content-Type header to text/css, diazo will put
    a 'style' tag around it.  Nice.
    """

    def __call__(self):
        image = self.context.restrictedTraverse('header.jpg', None)
        if image is None:
            url = ''
        else:
            url = image.absolute_url()
        self.request.RESPONSE.setHeader('Content-Type', 'text/css')
        return HEADER_IMAGE_CSS % url

For your use case you could get the roles like this and then return different css based on that information (code untested):

def __call__(self):
    from zope.component import getMultiAdapter
    pps = getMultiAdapter((self.context, self.request), name='plone_portal_state')
    member = pps.member()
    roles = member.getRolesInContext(self.context)
    css = "#content {background-color: %s}"
    if 'Manager' in roles:
        color = 'red'
    elif 'Reviewer' in roles:
        color = 'blue'
    else:
        color = 'yellow'
    self.request.RESPONSE.setHeader('Content-Type', 'text/css')
    return css % color
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top