Above content portlets in Plone 5

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'd still use Products.ContentWellPortlets - although this addon probably needs some update to be Plone 5 compliant...

We're discussion about replacing portlets with Mosaic in the future. But I wouldn't count on that at the moment...

I prefer collective.panels over ContentWellPortlets, but I don't know if it will work in Plone 5.

You could consider using the footerportlets and move them in the theme.
(or maybe register another manager ( copy code from https://github.com/plone/plone.app.layout/blob/master/plone/app/layout/viewlets/configure.zcml#L122 ?)

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()

contentheader.pt

<div class="container">
    <div class="row">
        <div class="col-xs-12" id="content-header">
            <div tal:on-error="nothing" tal:replace="structure view/render_contentheader_portlets" />
        </div>
    </div>
</div>

interfaces.py

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

<configure
    xmlns="http://namespaces.zope.org/zope"
    xmlns:browser="http://namespaces.zope.org/browser"
    xmlns:zcml="http://namespaces.zope.org/zcml">

 <portletmanager
   name="plone.headerportlets"
   type="your.package.path.to.portlets.interfaces.IContentHeader"
   />

</configure>
2 Likes

Got it working now.

If anyone has a need for this I can release the codes as an add on on Pypi.

1 Like

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.

Thanks

The easiest way to create an addon package of your own is to use http://docs.plone.org/develop/addons/bobtemplates.plone/README.html
A sub package is basically a folder within your package that you include in the configuration.
Look at the browser folder in here http://docs.plone.org/adapt-and-extend/theming/theme_product.html

I am extremely busy at the moment, but will see if I can get this released.

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) ?

In some projects I added a Javascript snippet that calculated the number of portlets/columns and adds the according bootstrap grid classes.

you could maybe use CSS:

display:flex

Very quickly put together, so no tests, etc, but works:

Despite the name, it also adds a 'below content portlet manager as well'

If anyone things I should, I can release it on Pypi.

Note to those putting the code in their own product: do not (re)name the content manager 'plone.above', it will not work

Any reason for not using this? https://pypi.python.org/pypi/Products.ContentWellPortlets

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.

1 Like

True
(but it was actually made before ContentWellPortlets worked on Plone 5)