Context-dependent navigation folder icons
In the navigation portlet, I would like to show different folder icons depending on the access rights for Anonymous.
Concretely, if for a given folder, Anonymous does not have the View permission, registered Members should see a red folder icon instead of a yellow one. (of course unregistered visitors will not see the folder at all).
- Adapt portlet_navigation
In (a custom copy of) portal_skins/plone_portlets/portlet_navigation, replace the line:
<img tal:replace="structure python:path('here/%s' % sibling.getIcon(1))"
with:
<img tal:replace="structure python:path(here.portal_url.scripts.folder_icon(sibling))"
- Customise the icon
Create a custom copy of portal_skins/portal_images/folder_icon.gif,
rename it to red_folder_icon.gif, upload a version of the icon with the colours altered.
- Implement the logic in a Script/External Method pair
In your portal_skins/custom folder in the ZMI, or in another skin layer folder, add a "Script (Python)" named "folder_icon" with the following content, and set as Parameter List: 'obj=None':
canMaybeView = context.anonymousHasRight(obj, 'View')
or context.anonymousHasRight(obj, 'Access contents information')
or context.anonymousHasRight(obj, 'Search ZCatalog')
if canMaybeView:
return 'here/' + obj.getIcon(1)
else:
return 'here/red_' + obj.getIcon(1)
The actual rights comparison needs to be done using an External
Method, to avoid rights limitations of non-Manager users. Create a file CheckRights.py on the file system, in the Extensions
directory under Zope's installation directory, with the following content:
def anonymousHasRight(folder, right='View'):
"""
For a given Plone folder, determine whether Anonymous has the right
given by parameter 'right' (String). This recurses to parents if
'Acquire' is checked.
Returns 1 if Anonymous has the right, 0 otherwise.
"""
ps = folder.permission_settings()
for p in ps:
if (p['name'] == right):
acquired = not not p['acquire']
break
if acquired:
# recurse upwardly:
parent = folder.aq_parent
return anonymousHasRight(parent, right)
else:
for p in folder.rolesOfPermission(right):
if p['name'] == "Anonymous":
selected = not not p['selected']
return selected
That's it! Really not elegant, but it seems to work. Suggestions for improvement welcome!
