What is the recommend way to add portlets above content in Plone 5? In the past I have used Products.ContentWellPortlets.
For the specific purpose that I am working on, I only need to provide content managers the portlets to a specific page. Would this now be more of a job for Deco?
For future purposes, I can see needing to add site-wide or section-wide above content portlets.
I have been trying to add a 'Above Content Portlet Manager'.
This works in Plone 4, but in Plone 5, I and up without the possibility to add portlets.
Is there anything special I should know about portlets and Plone 5 ? (Permissions, some hard-coded stuff ?)
Is there something 'outside plone.app.layout' that deals with this?
This worked for me in Plone 5 Put these files in a portlets subpackage of your project and include it (don't forget the init.py)
configure.zcml
<configure
xmlns="http://namespaces.zope.org/zope"
xmlns:browser="http://namespaces.zope.org/browser"
xmlns:zcml="http://namespaces.zope.org/zcml">
<include package="Products.CMFCore" file="permissions.zcml"/>
<!-- this should move to IAboveContentBody -->
<!-- ContentHeader -->
<browser:viewlet
name="plone.headerportlets"
for="*"
manager="plone.app.layout.viewlets.interfaces.IAboveContent"
class=".common.ContentHeaderViewlet"
permission="zope.Public"
/>
common.py
from datetime import date
from plone.app.layout.viewlets.common import ViewletBase
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
from zope.component import getMultiAdapter
class ContentHeaderViewlet(ViewletBase):
index = ViewPageTemplateFile('contentheader.pt')
def update(self):
super(ContentHeaderViewlet, self).update()
self.year = date.today().year
def render_contentheader_portlets(self):
"""
You might ask, why is this necessary. Well, let me tell you a story...
plone.app.portlets, in order to provide @@manage-portlets on a context,
overrides the IPortletRenderer for the IManageContextualPortletsView view.
See plone.portlets and plone.app.portlets
Seems fine right? Well, most of the time it is. Except, here. Previously,
we were just using the syntax like `provider:plone.footerportlets` to
render the footer portlets. Since this tal expression was inside
a viewlet, the view is no longer IManageContextualPortletsView when
visiting @@manage-portlets. Instead, it was IViewlet.
See zope.contentprovider
In to fix this short coming, we render the portlet column by
manually doing the multi adapter lookup and then manually
doing the rendering for the content provider.
See zope.contentprovider
"""
portlet_manager = getMultiAdapter(
(self.context, self.request, self.__parent__), name='plone.headerportlets')
portlet_manager.update()
return portlet_manager.render()
from plone.app.portlets.interfaces import IColumn
class IContentHeader(IColumn):
"""The Content Header
Normally, you will register portlets for IColumn instead.
"""
Don't forget to add a portlets.xml to you profiles folder
Please release the code as an add-on. Or at least guide me how to make a portlet subpackage and include the necesary code to render portlets above the content. like @agitator did.
Great! I've managed to make the portlet subpackage and works fine. Thanks to @agitator
Now i'm having problems to put each one of the portlets in a div of the grid system. Using the aproppiate colum width, based on the number of portlets.
I guess the best way to do it is with diazo rules? or modifying the template (contentheader.pt) ?
Not really, except that I have used portlet managers 'elsewhere' and that Contentwellportlets in some cases 'adds too much' (I dont want them to add portlets 'everywhere' )
Adding a feature to an existing plugin to.disable the unneeded portlet managers might be better than littering the ecosystem with more confusing choices. Just a thought.