Last active
October 8, 2022 14:47
-
-
Save fredvd/9b2a99d544d8bd95664414a0ff2e7667 to your computer and use it in GitHub Desktop.
TPN10: Change portlet rendering order and restrict editing portlets to a PortletManager Role
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<configure | |
xmlns="http://namespaces.zope.org/zope" | |
xmlns:genericsetup="http://namespaces.zope.org/genericsetup" | |
xmlns:i18n="http://namespaces.zope.org/i18n" | |
xmlns:plone="http://namespaces.plone.org/plone" | |
i18n_domain="test.site"> | |
<i18n:registerTranslations directory="locales" /> | |
<!-- | |
Be careful if you use general includeDependencies, it can have side effects! | |
Better import explicit packages or configurations ;) | |
--> | |
<!--<includeDependencies package="." />--> | |
<include package=".browser" /> | |
<include file="permissions.zcml" /> | |
<genericsetup:registerProfile | |
name="default" | |
title="test.site" | |
directory="profiles/default" | |
description="Installs the test.site add-on." | |
provides="Products.GenericSetup.interfaces.EXTENSION" | |
post_handler=".setuphandlers.post_install" | |
/> | |
<genericsetup:registerProfile | |
name="uninstall" | |
title="test.site (uninstall)" | |
directory="profiles/uninstall" | |
description="Uninstalls the test.site add-on." | |
provides="Products.GenericSetup.interfaces.EXTENSION" | |
post_handler=".setuphandlers.uninstall" | |
/> | |
<utility | |
factory=".setuphandlers.HiddenProfiles" | |
name="test.site-hiddenprofiles" | |
/> | |
<!-- -*- extra stuff goes here -*- --> | |
<adapter factory=".portletretriever.ReversePortletRetriever" /> | |
<!-- Extra local roles managed in the @@sharing view --> | |
<utility | |
name="PortletManager" | |
factory=".roles.PortletManagerRole" | |
/> | |
</configure> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from zope.component import adapter | |
from zope.interface import implementer | |
from plone.portlets.retriever import PortletRetriever | |
from Products.CMFCore.interfaces._content import IContentish | |
from plone.portlets.interfaces import IPortletManager | |
from plone.portlets.interfaces import IPortletRetriever | |
from itertools import groupby | |
@adapter(IContentish, IPortletManager) | |
@implementer(IPortletRetriever) | |
class ReversePortletRetriever(PortletRetriever): | |
"""Custom retriever to reorder context portlets | |
default portlet retriever.""" | |
def getPortlets(self): | |
""" Reshuffle the assignments so that the inherited context portlets | |
are displayed in reverse order, but keep portlet-ordering on each | |
context level intact | |
""" | |
# the assigments are one flat listing, but have a category and a key | |
# the key contains the path on which the assignments are made. | |
# we have to pick out the context category, there reverse all | |
# assignments after we have grouped them first by key, then | |
# reassemble the flat assignment list and lastly add possible group, | |
# user, or contenttype assignments with order unchanged. | |
assignments = super(ReversePortletRetriever,self).getPortlets() | |
if not assignments: | |
return [] | |
# only reverse right column, return otherwise | |
elif self.storage.__name__ != 'plone.rightcolumn': | |
return assignments | |
elif assignments[0]['category'] != 'context': | |
# shortcut if we have no context portlets as first in the list | |
return assignments | |
# get all context portlets | |
on_category = [(cat, list(ass)) for cat, ass in | |
groupby(assignments, lambda a: a['category'])] | |
context_portlets = on_category[0][1] | |
# sort on path_key and reverse each path_key group | |
on_key = [(key, list(ass)) for key, ass in | |
groupby(context_portlets, lambda a: a['key'])] | |
on_key.reverse() | |
new_assignments = [] | |
for key,ass_list in on_key: | |
new_assignments.extend(ass_list) | |
# append other portlet categories (group, user, contenttype) if we had | |
# them at all | |
if len(on_category) > 1: | |
for cat, ass_list in on_category[1:]: | |
new_assignments.extend(ass_list) | |
return new_assignments |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0"?> | |
<rolemap> | |
<roles> | |
<role name="PortletManager"/> | |
</roles> | |
<permissions> | |
<!-- Portlets --> | |
<permission name="Portlets: Manage portlets" | |
acquire="True"> | |
<role name="Manager"/> | |
<role name="PortletManager"/> | |
<role name="Site Administrator"/> | |
</permission> | |
<permission name="Portlets: Manage own portlets" | |
acquire="True"> | |
<role name="Manager"/> | |
<role name="Member"/> | |
<role name="PortletManager"/> | |
<role name="Site Administrator"/> | |
</permission> | |
<permission name="plone.portlet.collection: Add collection portlet" | |
acquire="True"> | |
<role name="Manager"/> | |
<role name="PortletManager"/> | |
<role name="Site Administrator"/> | |
</permission> | |
<permission name="plone.portlet.static: Add static portlet" | |
acquire="True"> | |
<role name="Manager"/> | |
<role name="PortletManager"/> | |
<role name="Site Administrator"/> | |
</permission> | |
</permissions> | |
</rolemap> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""Defines and tests a new PortletManager role. | |
A new PortletManager role is added to plone's default list:: | |
>>> 'PortletManager' in list(self.portal.__ac_roles__) | |
True | |
""" | |
from zope.interface import implementer | |
from plone.app.workflow.interfaces import ISharingPageRole | |
@implementer(ISharingPageRole) | |
class PortletManagerRole(object): | |
title = "Can manage portlets" | |
required_permission = "Manage portal" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment