Ticket #14127 (new Bug)

Opened 23 months ago

Navigation portlet: "hidden from navigation" items will always move to the bottom.

Reported by: plone@… Owned by:
Priority: minor Milestone: 4.x
Component: Unknown Version: 4.3
Keywords: Cc:

Description

Bug: when an item has "exclude from navigation" and is the current item (or a parent shown by the "show all parents" option), its position in the navigation portlet does not reflect position-in-parent.

Cause: These items are manually added at the end of handling and no info on position is retained at that point.

To reproduce: add two items to a folder, set the first (top) one to "Exclude form navigation". Note that it appears below the second one in the navigation.

Fix: (this is an overridden NavtreeStrategy that seems to work for me)

## skipped standard boiletplate imports

# default navtree strategy first chucks out hidden-in-nav
# items, and at the end puts the current item back in if needed;
# this makes the item always show up at the bottom.
#
# this impl. will simply not filter out things on the way to
# the current item.
# This will probably not fix items that are not shown in navigation
# by default, but that is a very minor case -- most content should
# optionally be shown, with the default for excludeFromNavigation
# being True for things like Files and Images.

from plone.app.portlets.portlets.navigation \
    import NavtreeStrategy as OldNavtreeStrategy

class NavtreeStrategy(OldNavtreeStrategy):

    implements(INavtreeStrategy)
    adapts(Interface, INavigationPortlet)

    def __init__(self, context, portlet):
        #logger.info("New Navtree strategy, context is %s", context)
        self.contextpathslash = '/'.join(context.getPhysicalPath())+'/'
        OldNavtreeStrategy.__init__(self, context, portlet)

    def subtreeFilter(self, node):

        oldDecision = super(NavtreeStrategy, self).subtreeFilter(node)

        if oldDecision == True \
                or not self.showAllParents \
                or not node.get('path', None):

            return oldDecision

        onTrack = self.contextpathslash.startswith(node['path']+'/')
        return onTrack

    def nodeFilter(self, node):

        oldDecision = super(NavtreeStrategy, self).nodeFilter(node)

        if oldDecision == True \
                or not self.showAllParents \
                or not node.get('item', None):

            return oldDecision

        thatpathslash = node['item'].getPath()+'/'
        return self.contextpathslash.startswith(thatpathslash)
Note: See TracTickets for help on using tickets.