Ticket #14 (feature request)

Opened 3 years ago

Last modified 2 years ago

Suggestions for qPloneDropDownMenu - autogenerated sublevels

Status: new

Reported by: carn Assigned to: piv
Priority: major Component: qPloneDropDownMenu
Keywords: Cc:

(qPloneDropDownMenu version 0.1.6 tested with Plone 2.1.2 / Zope 2.8.5)

Wouldn't it be nice to have a drop down menu that autogenerated sublevels? A client of mine thought it would, so I have made some changes in the original qPloneDropDownMenu product.

I'm no Python shark, so don't expect any rocket science here. But it works for me, and maybe it will work for you as well. And perhaps the ideas behind my approach can inspire the further development of the product.

The main changes in the product are:

- you get the menu structure from the sitemap

- you check that the level 1 URL's match URL's in the tab directory

- you can change and save a new menu depth (level) from the control panel (but you have to regenerate after that - this can obviously be better)

- The homepage title is translated, using the msgid 'Home'

To reach my goals I have made some changes in Extensions/Install.py and in skins/qPloneDropDownMenu/prefs_dropdownmenu_edit_form.cpt (see below).

Hope some of this is of any use.

Regards, Casper


Install.py has got a new function (createMenuString), and the function updateMenu is changed:

def createMenuString(children, level=1, maxlevel=0, urls=None):
    """Iterates through dictionary of objects n levels down in site structure.
    Creates a HTML list to be used in drop down menu.

    Returns string.
    """
    
    retval = ''

    for child in children:
        # Test if the toplevel URL is supposed to be a tab
        if level == 1 and urls and not child['getURL'] in urls:
            continue
        if not child['no_display'] and not child['portal_type'] == 'Plone Site':
            retval += '<li id="portaltab-%s" class="plain"><a href="%s" accesskey="t">' % \
                      (child['path'], child['getURL']) + child['Title'] + '</a>'
            subchildren = child['children']
            if level <= maxlevel and len(subchildren) > 0:
                retval += '<ul>'
                retval += createMenuString(subchildren, level+1, maxlevel)
                retval += '</ul>'
            retval += '</li>\n'
    return retval

def updateMenu(self):
    out = ''

    # We work with the property sheet now - so we can keep existing dropdownmenu_level
    portal_props = getToolByName(self, 'portal_properties')
    if not hasattr(portal_props, PROPERTY_SHEET):
        portal_props.addPropertySheet(PROPERTY_SHEET, 'DropDown Menu Properties')
    ap = getattr(portal_props, PROPERTY_SHEET)

    dropdownmenu_level = 1
    if ap.hasProperty('dropdownmenu_level'):
        dropdownmenu_level = ap.getProperty('dropdownmenu_level')

    pu = getToolByName(self, 'plone_utils')

    # Uses createNavTree to autogenerate deeper menu structure
    if hasattr(pu, 'createNavTree'):
        
        #Translation service - used to translate homepage title
        homepage_title = 'Home'
        if hasattr(pu, 'translation_service'):
            translation_service = getToolByName(self, 'translation_service', None)
            if translation_service is not None:
                homepage_title = translation_service.utranslate( \
                    domain='plone', msgid='Home', \
                    context=self, \
                    default='Home')
                homepage_title = translation_service.encode(homepage_title, errors='replace')

        #Generates a list of toplevel URL's to test against in createMenuString()
        tl_urls = []
        if hasattr(pu, 'createTopLevelTabs'):
            pactions = getToolByName(self, 'portal_actions').listFilteredActionsFor(self)
            tl_tabs = pu.createTopLevelTabs(pactions)
            for url in tl_tabs:
                tl_urls.append(url['url'])

        # We are ready to get the navigation tree and generate an output string
        tl_nav = pu.createNavTree(self, sitemap=dropdownmenu_level)

        out += '<li id="portaltab-%s" class="plain"><a href="%s" accesskey="t">' % \
               (tl_nav['path'], tl_nav['getURL']) + homepage_title + '</a></li>\n'
        children = tl_nav.get('children', [])
        out += createMenuString(children, maxlevel=dropdownmenu_level, urls=tl_urls)
        
    else:
        portal = getToolByName(self, 'portal_url').getPortalObject()

        portal_act = getToolByName(self, 'portal_actions')
        actions=portal_act._cloneActions()

        for act in actions:
            if act.category == 'portal_tabs':
                out += '<li id="portaltab-%s" class="plain"><a href="%s" accesskey="t">%s</a></li>\n' % \
                    (act.id, \
                     Expression(act.getActionExpression())(createExprContext(portal, portal, portal)), \
                     act.title)

    safeEditProperty(ap, 'menu', out, 'text')
    safeEditProperty(ap, 'dropdownmenu_level', dropdownmenu_level, 'int')

prefs_dropdownmenu_edit_form.cpt has got an extra field to adjust the number of sublevels:

<html xmlns="http://www.w3.org/1999/xhtml"" xml:lang="en-US"
      xmlns:metal="http://xml.zope.org/namespaces/metal"
      xmlns:tal="http://xml.zope.org/namespaces/tal"
      lang="en-US"
      metal:use-macro="here/prefs_main_template/macros/master"
      i18n:domain="qPloneDropDownMenu"> 

  <metal:block fill-slot="top_slot"
             tal:define="dummy python:request.set('disable_border',1)" />

<body>
  <div metal:fill-slot="prefs_configlet_main"
       tal:define="errors python:request.get('errors', {})">
  
    <h1 i18n:translate="heading_plonedropdownmenu">Plone Drop Down Menu</h1>
    <a href=""
       class="link-parent"
       tal:attributes="href string: $portal_url/plone_control_panel"
       i18n:translate="label_up_to_plone_setup">
    Up to Plone Setup
    </a>
    
    <div class="documentDescription"
         i18n:translate="description_plonedropdownmenu">
    Plone Drop Down Menu ... 
    </div>

    <h2>Post-install instructions</h2>

    <p>Congratulations, you've installed Plone Drop Down Menu product from 
    Quintagroup.</p>

    <p>In case you have some problems following editing DropDown Menu you
    can only click <a href="dropdownmenu_update">regenerate menu</a>, and
    you'll get the initial portal menu.</p>
 
    <form name="menu_edit_form"
          action="." 
          method="post" 
          tal:attributes="action string:${here/getId}/${template/getId}" >
 
     <div class="field">
         <label for="menu" i18n:translate="label_dropdownlevel">Menu depth</label>
                    
         <div class="formHelp" i18n:translate="help_dropdownlevel_edit">
         Here you can set the depth of the drop down menu's structure. 
         </div>
     
         <input type="text" 
                   value=""
                   tabindex=""
                   name="dropdownmenu_level"
                   id="dropdownmenu_level"
                   tal:attributes="value portal/portal_properties/dropdownmenu_properties/dropdownmenu_level;
					tabindex tabindex/next;"
                   />
     </div>

     <div class="field">
         <label for="menu" i18n:translate="label_portaltabs">Portal tabs</label>
                    
         <div class="formHelp" i18n:translate="help_portaltabs_edit">
         Here you can change your portal tabs. 
         </div>
     
         <textarea cols="80" 
                   rows="20"
                   tabindex=""
                   name="menu"
                   id="menu"
                   tal:content="portal/portal_properties/dropdownmenu_properties/menu"
                   tal:attributes="tabindex tabindex/next;"
                   >Portal Tabs</textarea>
     </div>

     <div class="formControls"
             tal:define="process_creation request/process_creation|nothing;">
         <input class="context"
                tabindex=""
                type="submit"
                value="Regenerate Menu"
                name="form.button.Regenerate"
                i18n:attributes="value"
                tal:attributes="tabindex tabindex/next"
                />
          
     </div>

     <div class="formControls"
             tal:define="process_creation request/process_creation|nothing;">
         <input class="context"
                tabindex=""
                type="submit"
                value="Save"
                name="form.button.Save"
                i18n:attributes="value"
                tal:attributes="tabindex tabindex/next"
                />
          
     </div>

     <input type="hidden" name="form.submitted" value="1" />
    </form>

            
  </div>
</body>
</html>

Attachments

Install.py (7.7 kB) - added by carn on 02/28/06 03:37:52.
prefs_dropdownmenu_edit_form.cpt (3.5 kB) - added by carn on 02/28/06 03:38:27.

Change History

02/28/06 03:37:52: Modified by carn

  • attachment Install.py added.

02/28/06 03:38:27: Modified by carn

  • attachment prefs_dropdownmenu_edit_form.cpt added.