[SOLVED] Dropdown menu with (lead) image Plone 6 Classic

Has anyone made something similar to w.dropdownmenus 'show lead image in menu' to Plone 6?

If not, what is the best approach ( use a navigation portlet / override the viewlet / something else)

UPDATE: I made it an add-on, if someone has suggestions (for example: add / change CSS class or 'better code' (maybe get the images using scales-function instead), please let me know and I will make a release.

Hi Espen,

that is a tricky task. Take a look at plone.app.layout.viewlets.common.py

You can override the code and register the navigation viewlet on your browser layer. I have done that in Plone 5 - not in Plone 6.0, but in Plone 6.0 i made a layout tile out of it, because i am using mosaic site layouts for my pages.

There are some 'blue prints' you can alter to make it fit your own markup/theme e.g.

_item_markup_template = (
    '<li class="nav-item nav-item-{id} my-custom-class">'
    '<a href="{url}" class="nav-link {css_class}" {attributes}>{title}</a>'
    "{sub}"
    "</li>"
)

For more cosmetic changes you can also (monkey) patch these helper methods in your own modules, but i didn't use:

def customize_query(self, query):
    """Helper to customize the catalog query."""
    pass

def customize_tab(self, entry, tab):
    """Helper to add custom entry keys/values."""
    pass

def customize_entry(self, entry, brain):
    """Helper to add custom entry keys/values."""
    pass

Another solution may be using diazo rules and js, but i am too pythonic to use that technologies. I do not understand diazo in general i must admit.

Hope that helps a bit,
Roland

zcml:

  <browser:viewlet
    name="plone.global_sections"
    manager="plone.app.layout.viewlets.interfaces.IMainNavigation"
    class=".common.MyGlobalSectionsViewlet"
    layer="myproduct.interfaces.IMyLayer"
    permission="zope2.View"
    />

common.py:

from plone.app.layout.viewlets.common import GlobalSectionsViewlet

class MyGlobalSectionsViewlet(GlobalSectionsViewlet):


    _opener_markup_template = (
        u'custom html'
    )
    _item_markup_template = (
        u'custom html"
    )
    _subtree_markup_wrapper = u'custom html'

But you can also use js to inject the <img> tag (the src attribute could be created from the item url but no idea if no lead image available) and some css to adjust it.

Thanks.

It looks like something similar to this could work:
A bit weird code, I could not find another way to check for image (tal conditions will not work)

# -*- coding: utf-8 -*-

from plone.app.layout.viewlets import ViewletBase
from plone.app.layout.viewlets.common import GlobalSectionsViewlet


class DropDownMenuViewlet(GlobalSectionsViewlet):
    
    def customize_tab(self, entry, tab):
        """Helper to add custom entry keys/values."""
        #Maybe add option for 'top folder too?
        entry['image_thumb'] = ''
        
    def customize_entry(self, entry, brain):
        """Helper to add custom entry keys/values."""
        entry['image_thumb'] = ''
        if brain.getIcon:
            entry['image_thumb'] = '<img  alt="" 
               class="subnmenu_image" 
               src="{url}/@@images/image/{thumb}" /> '.format( url = entry['url'], thumb = 'listing' )
            
    
    _item_markup_template = (
            '<li class="{id}{has_sub_class} nav-item">'
            '<a href="{url}" class="state-{review_state} 
                 nav-link"{aria_haspopup}>{image_thumb}{title}</a>{opener}'   
            "{sub}"  
            "</li>"
        )

UPDATE: It is now on github.