Navigation portlet with 'drop down', Plone 6 Classic

I think there once was a navigation portlet with drop down/drop right. Does anyone know 'its name' ?

I want to have the navigation menu similar to the (left) toolbar (and put the toolbar 'on top')

Maybe you mean GitHub - collective/collective.sidebar: A sidebar for Plone to consolidate toolbar and navigation as seen here: https://plonetheme.tokyo

I was thinking about another, but this is even better.

This add-on also gets the same error as I have mentioned in some other post recently. Fresh 6.1 site, no other add-ons:

2025-02-20 10:24:33,869 ERROR   [plone.app.viewletmanager:110][waitress-3] Error while rendering viewlet-manager=plone.portalheader, viewlet=sidebar
Traceback (most recent call last):
  File "/home/ubuntu/plone/buildout-cache/eggs/Chameleon-4.4.4-py3.13.egg/chameleon/template.py", line 200, in render
    self._render(
    ~~~~~~~~~~~~^
        stream,
        ^^^^^^^
    ...<2 lines>...
        target_language=target_language
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/home/ubuntu/disk2/Plone6/Plone-6.1/plone601_25feb/var/cache/29719542f3bddf45a14c65348a93ba57.py", line 274, in render
    __value = _static_139785843506128('path', 'view/get_items', econtext=econtext)(_static_139785842179408(econtext, __zt_tmp))
  File "/home/ubuntu/plone/buildout-cache/eggs/zope.tales-6.0-py3.13.egg/zope/tales/expressions.py", line 248, in __call__
    return self._eval(econtext)
          ~~~~~~~~~~^^^^^^^^^^
  File "/home/ubuntu/plone/buildout-cache/eggs/Zope-5.12-py3.13.egg/Products/PageTemplates/Expressions.py", line 225, in _eval
    return render(ob, econtext.vars)
  File "/home/ubuntu/plone/buildout-cache/eggs/Zope-5.12-py3.13.egg/Products/PageTemplates/Expressions.py", line 155, in render
    ob = ob()
  File "/home/ubuntu/disk2/Plone6/Plone-6.1/plone601_25feb/src/collective.sidebar/src/collective/sidebar/browser/sidebar.py", line 377, in get_items
    contents = context.getFolderContents()
              ^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'RequestContainer' object has no attribute 'getFolderContents'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/ubuntu/plone/buildout-cache/eggs/plone.app.viewletmanager-4.0.4-py3.13.egg/plone/app/viewletmanager/manager.py", line 106, in render
    html.append(viewlet.render())
                ~~~~~~~~~~~~~~^^
  File "/home/ubuntu/plone/buildout-cache/eggs/plone.app.layout-5.0.1-py3.13.egg/plone/app/layout/viewlets/common.py", line 70, in render
    return self.index()
          ~~~~~~~~~~^^
  File "/home/ubuntu/plone/buildout-cache/eggs/Zope-5.12-py3.13.egg/Products/Five/browser/pagetemplatefile.py", line 127, in __call__
    return self.__func__(__self__, *args, **kw)
          ~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/ubuntu/plone/buildout-cache/eggs/Zope-5.12-py3.13.egg/Products/Five/browser/pagetemplatefile.py", line 59, in __call__
    s = self.pt_render(
        namespace,
        showtal=getattr(debug_flags, 'showTAL', 0),
        sourceAnnotations=getattr(debug_flags, 'sourceAnnotations', 0),
    )
  File "/home/ubuntu/plone/buildout-cache/eggs/zope.pagetemplate-5.1-py3.13.egg/zope/pagetemplate/pagetemplate.py", line 134, in pt_render
    return self._v_program(
          ~~~~~~~~~~~~~~~^
        context, self._v_macros, tal=not source, showtal=showtal,
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        strictinsert=0, sourceAnnotations=sourceAnnotations
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/home/ubuntu/plone/buildout-cache/eggs/Zope-5.12-py3.13.egg/Products/PageTemplates/engine.py", line 368, in __call__
    return template.render(**kwargs)
          ~~~~~~~~~~~~~~~^^^^^^^^^^
  File "/home/ubuntu/plone/buildout-cache/eggs/z3c.pt-4.4-py3.13.egg/z3c/pt/pagetemplate.py", line 198, in render
    return base_renderer(**context)
  File "/home/ubuntu/plone/buildout-cache/eggs/Chameleon-4.4.4-py3.13.egg/chameleon/zpt/template.py", line 328, in render
    return super().render(**_kw)
          ~~~~~~~~~~~~~~^^^^^^^
  File "/home/ubuntu/plone/buildout-cache/eggs/Chameleon-4.4.4-py3.13.egg/chameleon/template.py", line 229, in render
    raise_with_traceback(exc, tb)
    ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^
  File "/home/ubuntu/plone/buildout-cache/eggs/Chameleon-4.4.4-py3.13.egg/chameleon/utils.py", line 20, in raise_with_traceback
    raise exc
  File "/home/ubuntu/plone/buildout-cache/eggs/Chameleon-4.4.4-py3.13.egg/chameleon/template.py", line 200, in render
    self._render(
    ~~~~~~~~~~~~^
        stream,
        ^^^^^^^
    ...<2 lines>...
        target_language=target_language
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/home/ubuntu/disk2/Plone6/Plone-6.1/plone601_25feb/var/cache/29719542f3bddf45a14c65348a93ba57.py", line 274, in render
    __value = _static_139785843506128('path', 'view/get_items', econtext=econtext)(_static_139785842179408(econtext, __zt_tmp))
  File "/home/ubuntu/plone/buildout-cache/eggs/zope.tales-6.0-py3.13.egg/zope/tales/expressions.py", line 248, in __call__
    return self._eval(econtext)
          ~~~~~~~~~~^^^^^^^^^^
  File "/home/ubuntu/plone/buildout-cache/eggs/Zope-5.12-py3.13.egg/Products/PageTemplates/Expressions.py", line 225, in _eval
    return render(ob, econtext.vars)
  File "/home/ubuntu/plone/buildout-cache/eggs/Zope-5.12-py3.13.egg/Products/PageTemplates/Expressions.py", line 155, in render
    ob = ob()
  File "/home/ubuntu/disk2/Plone6/Plone-6.1/plone601_25feb/src/collective.sidebar/src/collective/sidebar/browser/sidebar.py", line 377, in get_items
    contents = context.getFolderContents()
              ^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'RequestContainer' object has no attribute 'getFolderContents'

- Expression: "view/get_items"
- Filename:   ... ebar/src/collective/sidebar/browser/templates/sidebar.pt
- Location:   (line 11: col 156)
- Source:     ... bel" tal:define="items view/get_items; back view/get_back;" ...
                                          ^^^^^^^^^^^^^^
- Arguments:  template: <Products.Five.browser.pagetemplatefile.ViewPageTemplateFile object at 0x7f226a29a1b0>
              options: {}
              args: ()
              nothing: None
              modules: <Products.PageTemplates.ZRPythonExpr._SecureModuleImporter object at 0x7f2270055fd0>
              request: <WSGIRequest, URL=http://ubuntu.local:8610/Plone/document_view>
              view: <Products.Five.viewlet.metaconfigure.SidebarViewlet object at 0x7f225b63f110>
              context: <PloneSite at /Plone>
              views: <Products.Five.browser.pagetemplatefile.ViewMapper object at 0x7f226ac2b470>
              here: <PloneSite at /Plone>
              container: <PloneSite at /Plone>
              root: <Application at >
              traverse_subpath: []
              user: <PropertiedUser 'admin'>
              default: <DEFAULT>
              repeat: <Products.PageTemplates.engine.RepeatDictWrapper object at 0x7f225b328490>
              loop: {}
              target_language: None
              translate: <function BaseTemplate.render.<locals>.translate at 0x7f226a22ae80>
              attrs: {'class': 'offcanvas offcanvas-${view/get_sidebar_position}', 'tabindex': '-1', 'id': 'portal-sidebar', 'aria-labelledby': 'offcanvasExampleLabel', 'data-sidebar-mouse': '${view/get_mouse_activated}', 'data-sidebar-mouse-area': '${view/get_mouse_area}'}
              portal_url: 'http://ubuntu.local:8610/Plone'
              navigation_root_url: 'http://ubuntu.local:8610/Plone'
              toLocalizedTime: <bound method Plone.toLocalizedTime of <Products.Five.browser.metaconfigure.Plone object at 0x7f225b60cf50>>
              context_url: 'http://ubuntu.local:8610/Plone'
              anonymous: False
              collapsible: True
              collapse: 'collapse'
              role: 'button'
              icons: <Products.Five.browser.metaconfigure.IconsView object at 0x7f226a02fd90>

this is gone in 6.1, use @@contentlisting. Or add back the getFolderContents script: https://github.com/plone/Products.CMFPlone/pull/3960

1 Like

Do you have an example, if I change

# contents = context.getFolderContents()

to

contents = context.restrictedTraverse('@@contentlisting')()

I get:

'FolderListing' object is not iterable

Sounds strange.

I can use:

contents = context.listFolderContents()

But then I get 'real Objects', so I need to change 'item.Title' to 'item.Title()', getURL to absolute_url etc and it is probably slower

By the way: could 'getFolderContents' be (just) api.content.find(context=context) with a depth of 1 ?

There was GitHub - collective/collective.superfish: Suckerfish integration for Plone ... not sure if its Plone 6 compatible

You're calling the browser view with

contents = context.restrictedTraverse('@@contentlisting')()

so it is not possible that this returns the browser view itself ('FolderListing' is a browser view, the return object is a IContentListing.

In a application, I did:

context.getFolderContents() -> context.restrictedTraverse('@@contentlisting')() and brain.review_state -> brain.review_state()

I updated the add on so it works with Plone 6.1

(unfortunately, I accidentialy committed to the main branch 'part of the fix').
can anyone 'approve the fix' ( @santonelli ?? ) or should I do it myself.

PS: My fork is working ok, but I not 100% sure if my approach is the best (fastest)

The PR conflicts with main at the moment. So I'm not 100% sure what to do. Feel free to merge / finish your work.

Since Plone 6.1 is out we're going to create a 2.x (for Plone 6.0.x) anyway.

OK, will do