[Zope3-checkins] CVS: Zope3/src/zope/app/menu/browser - __init__.py:1.1 configure.zcml:1.1 interfaces.py:1.1 managementviewselector.py:1.1 menu_contents.pt:1.1 menu_overview.pt:1.1 tests.py:1.1

Stephan Richter srichter at cosmos.phy.tufts.edu
Wed Mar 10 18:10:46 EST 2004


Update of /cvs-repository/Zope3/src/zope/app/menu/browser
In directory cvs.zope.org:/tmp/cvs-serv7817/src/zope/app/menu/browser

Added Files:
	__init__.py configure.zcml interfaces.py 
	managementviewselector.py menu_contents.pt menu_overview.pt 
	tests.py 
Log Message:


Moved local browser menu implementation to zope.app.menu.




=== Added File Zope3/src/zope/app/menu/browser/__init__.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Menu Access and Local Menu Service Views

$Id: __init__.py,v 1.1 2004/03/10 23:10:44 srichter Exp $
"""
from zope.interface import implements
from zope.publisher.browser import BrowserView
from zope.app import zapi
from zope.app.browser.container.contents import Contents
from zope.app.component.nextservice import queryNextService
from zope.app.dublincore.interfaces import IZopeDublinCore
from zope.app.menu.interfaces import ILocalBrowserMenu
from zope.app.services.servicenames import Utilities, BrowserMenu
from interfaces import IMenuAccessView

class MenuAccessView(BrowserView):

    implements(IMenuAccessView)

    def __getitem__(self, menu_id):
        browser_menu_service = zapi.getService(self.context, 'BrowserMenu')
        return browser_menu_service.getMenu(menu_id,
                                            self.context,
                                            self.request)


class MenuContents(Contents):

    def _extractContentInfo(self, item):
        id, obj = item
        info = {}
        info['cb_id'] = info['id'] = id
        info['object'] = obj

        info['url'] = id
        info['title'] = obj.title
        info['action'] = obj.action

        dc = IZopeDublinCore(obj, None)
        if dc is not None:

            formatter = self.request.locale.dates.getFormatter(
                'dateTime', 'short')
            created = dc.created
            if created is not None:
                info['created'] = formatter.format(created)

            modified = dc.modified
            if modified is not None:
                info['modified'] = formatter.format(modified)

        return info


class BrowserMenuServiceOverview:

    def getLocalMenus(self):
        menus_info = []
        utilities = zapi.getService(self.context, Utilities)
        for menu_id, menu in utilities.getLocalUtilitiesFor(ILocalBrowserMenu):
            menus_info.append(self._getInfoFromMenu(menu_id, menu))
        return menus_info


    def getInheritedMenus(self):
        menus = []
        utilities = queryNextService(self.context, Utilities)
        for id, menu in utilities.getUtilitiesFor(ILocalBrowserMenu):
            menus.append(self._getInfoFromMenu(id, menu))
        # Global Browser Menus
        service = zapi.getService(None, BrowserMenu)
        for id, menu in service._registry.items():
            menus.append(self._getInfoFromMenu(id, menu))
        return menus


    def _getInfoFromMenu(self, menu_id, menu):
        info = {}
        info['id'] = menu_id
        info['title'] = menu.title
        info['local_items'] = self._getItemsInfo(menu)
        info['inherit'] = False
        if getattr(menu, 'inherit', False):
            info['inherit'] = True
            next = queryNextService(menu, BrowserMenu)
            if next is not None:
                try:
                    inherit_menu = next.queryLocalMenu(menu_id)
                except AttributeError:
                    # We deal with a global broqwser menu service
                    inherit_menu = next._registry.get(menu_id, None)

                if not inherit_menu:
                    info['inherited_items'] = []
                else:
                    info['inherited_items'] = self._getItemsInfo(inherit_menu)
        else:
            info['inherited_items'] = None
        return info


    def _getItemsInfo(self, menu):
        menu_items = []

        for items in menu.getMenuItems():
            action, title, description, filter, permission = items

            menu_items.append({'title': title,
                               'action': action})
        return menu_items


=== Added File Zope3/src/zope/app/menu/browser/configure.zcml ===
<zope:configure 
   xmlns:zope="http://namespaces.zope.org/zope"
   xmlns="http://namespaces.zope.org/browser">

<!-- Browser Menu Service -->

   <addMenuItem
     title="Browser Menu Service"
     description="A Service For Persistent Browser Menus"
     class="zope.app.menu.LocalBrowserMenuService"
     permission="zope.ManageServices"
   />

  <page
       name="overview.html"
       menu="zmi_views" title="Overview"
       for="zope.app.publisher.interfaces.browser.IBrowserMenuService"
       permission="zope.ManageServices"
       class=".BrowserMenuServiceOverview"
       template="menu_overview.pt" />

  <defaultView
      for="zope.app.publisher.interfaces.browser.IBrowserMenuService"
      name="overview.html" />

<!-- Browser Menu -->

  <view
      name="+"
      for="zope.app.menu.interfaces.ILocalBrowserMenu"
      permission="zope.ManageContent"
      class="zope.app.browser.container.adding.Adding" />


  <addform
      label="Add Browser Menu (Registration)"
      for="zope.app.menu.interfaces.ILocalBrowserMenu"
      name="addRegistration.html"
      schema="zope.app.interfaces.services.utility.IUtilityRegistration"
      class="zope.app.browser.services.utility.AddRegistration"
      permission="zope.ManageServices"
      content_factory="zope.app.services.utility.UtilityRegistration"
      arguments="name interface componentPath"
      set_after_add="status"
      fields="name interface componentPath permission status" 
      usage="addingdialog" />


  <addform
      name="AddBrowserMenu"
      schema="zope.app.menu.interfaces.ILocalBrowserMenu"
      label="Add Browser Menu"
      content_factory="zope.app.menu.LocalBrowserMenu"
      fields="title description inherit"
      permission="zope.ManageContent"
      usage="addingdialog" />

  <page
      name="contents.html"
      menu="zmi_views" title="Contents"
      for="zope.app.menu.interfaces.ILocalBrowserMenu"
      permission="zope.ManageServices"
      class=".MenuContents"
      template="menu_contents.pt" />

  <editform
      name="edit.html"
      for="zope.app.menu.interfaces.ILocalBrowserMenu"
      schema="zope.app.menu.interfaces.ILocalBrowserMenu"
      label="Edit Browser Menu"
      fields="title description inherit"
      permission="zope.ManageContent"
      menu="zmi_views" title="Edit"/>

  <defaultView
      for="zope.app.menu.interfaces.ILocalBrowserMenu"
      name="contents.html" />

  <addMenuItem
      title="Browser Menu"
      description="A Persistent Browser Menu"
      class="zope.app.menu.LocalBrowserMenu"
      permission="zope.ManageServices"
      />


<!-- Browser Menu Item-->

  <menuItem
      menu="zmi_actions" title="Add Menu Item"
      for="zope.app.menu.interfaces.ILocalBrowserMenu"
      action="+/AddLocalBrowserMenuItemForm=name" />

  <addform
      schema="zope.app.publisher.interfaces.browser.IBrowserMenuItem"
      label="Add Browser Menu Item"
      content_factory="zope.app.menu.LocalBrowserMenuItem"
      name="AddLocalBrowserMenuItemForm"
      permission="zope.ManageContent" />

  <editform
      name="edit.html"
      for="zope.app.publisher.interfaces.browser.IBrowserMenuItem"
      schema="zope.app.publisher.interfaces.browser.IBrowserMenuItem"
      label="Edit Browser Menu Item"
      permission="zope.ManageContent"
      menu="zmi_views" title="Edit"/>

  <defaultView
      for="zope.app.publisher.interfaces.browser.IBrowserMenuItem"
      name="edit.html" />


  <!-- Management view selector -->
  <!-- Get first accessable item from zmi_views menu -->
  <page
      for="*"
      name="SelectedManagementView.html"
      permission="zope.Public"
      class=".managementviewselector.ManagementViewSelector"
      allowed_interface="zope.publisher.interfaces.browser.IBrowserPublisher" />

  <!-- Make manage an alias for same -->
  <page
      for="*"
      name="manage"
      permission="zope.ManageContent"
      class=".managementviewselector.ManagementViewSelector"
      allowed_interface="zope.publisher.interfaces.browser.IBrowserPublisher" />

  <!-- Menu access -->
  <page
      for="*"
      name="view_get_menu"
      permission="zope.Public"
      class=".MenuAccessView"
      allowed_interface=".interfaces.IMenuAccessView"
      />

</zope:configure>


=== Added File Zope3/src/zope/app/menu/browser/interfaces.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""
$Id: interfaces.py,v 1.1 2004/03/10 23:10:44 srichter Exp $
"""
from zope.interface import Interface

class IMenuAccessView(Interface):
    """View that provides access to menus"""

    def __getitem__(menu_id):
        """Get menu information

        Return a sequence of dictionaries with labels and
        actions, where actions are relative URLs.
        """


=== Added File Zope3/src/zope/app/menu/browser/managementviewselector.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Selecting first available and allowed management view

$Id: managementviewselector.py,v 1.1 2004/03/10 23:10:44 srichter Exp $
"""
from zope.interface import implements
from zope.publisher.browser import BrowserView
from zope.publisher.interfaces.browser import IBrowserPublisher
from zope.app import zapi
from zope.app.services.servicenames import BrowserMenu

class ManagementViewSelector(BrowserView):
    """View that selects the first available management view."""
    implements(IBrowserPublisher)

    def browserDefault(self, request):
        return self, ()

    def __call__(self):
        browser_menu_service = zapi.getService(self.context, BrowserMenu)
        item = browser_menu_service.getFirstMenuItem(
            'zmi_views', self.context, self.request)

        if item:
            self.request.response.redirect(item['action'])
            return u''

        self.request.response.redirect('.') # Redirect to content/
        return u''


=== Added File Zope3/src/zope/app/menu/browser/menu_contents.pt ===
<html metal:use-macro="views/standard_macros/page">
<body>
<div metal:fill-slot="body">

  <form name="containerContentsForm" method="POST" action="."
        tal:attributes="action request/URL"
        tal:define="container_contents view/listContentInfo">

    <input type="hidden" name="type_name" value=""
           tal:attributes="value request/type_name"
           tal:condition="request/type_name|nothing"
           />
    <input type="hidden" name="retitle_id" value=""
           tal:attributes="value request/retitle_id"
           tal:condition="request/retitle_id|nothing"
           />

    <div class="page_error"
         tal:condition="view/error"
         tal:content="view/error"
         i18n:translate="">
      Error message
    </div>

    <table id="sortable" class="listing" summary="Content listing"
           i18n:attributes="summary">

      <thead>
        <tr>
          <th>&nbsp;</th>
          <th i18n:translate="">Title</th>
          <th i18n:translate="">Action</th>
          <th i18n:translate="">Created</th>
          <th i18n:translate="">Modified</th>
        </tr>
      </thead>

      <tbody>

      <metal:block tal:repeat="item container_contents">
        <tr tal:define="oddrow repeat/item/odd; url item/url"
            tal:attributes="class python:oddrow and 'even' or 'odd'" >
          <td>
            <input type="checkbox" class="noborder" name="ids:list" id="#"
                   value="#"
                   tal:attributes="value item/id;
                                   id item/cb_id;
                                   checked request/ids_checked|nothing;"/>
          </td>
          <td><span>
                <a href="#"
                   tal:attributes="href
                               string:${url}/@@SelectedManagementView.html"
                   tal:content="item/title"
                   >foo</a
              ></span
             ></td>
          <td><span>
                <a href="#"
                   tal:attributes="href
                               string:${url}/@@SelectedManagementView.html"
                   tal:content="item/action"
                   >foo</a
              ></span
             ></td>

          <td><span tal:define="created item/created|default"
                    tal:content="created">&nbsp;</span></td>
          <td><span tal:define="modified item/modified|default"
                    tal:content="modified">&nbsp;</span></td>
        </tr>
      </metal:block>

      </tbody>
    </table>

    <div tal:condition="view/normalButtons">
      <input type="submit" name="container_delete_button" value="Delete"
             i18n:attributes="value container-delete-button"
             i18n:domain="zope"
             />
    </div>

  </form>

  <script ><!--
      prettydump('focus', LG_INFO);
      document.containerContentsForm.new_value.focus();
      //-->
  </script>

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


=== Added File Zope3/src/zope/app/menu/browser/menu_overview.pt ===
<html metal:use-macro="views/standard_macros/page">
<head>
  <title metal:fill-slot="title" i18n:translate="">Menu Service</title>
</head>
<body>
<div metal:fill-slot="body">

  <h1>Local Menus</h1>
  <ul>
    <li tal:repeat="menu view/getLocalMenus">
      <b tal:content="menu/id" /> (<span tal:replace="menu/title"/>)
      <br />
      <em>Local Items</em> 
      <ul>
        <li tal:repeat="item menu/local_items">
          <em tal:replace="item/title"/>
           (<span tal:replace="item/action"/>)
        </li>          
      </ul>
      <div tal:condition="menu/inherit">
        <em>Inherited Items</em>
        <ul>
          <li tal:repeat="item menu/inherited_items">
            <em tal:replace="item/title"/>
             (<span tal:replace="item/action"/>)
          </li>          
        </ul>
      </div>
    </li>
  </ul>

  <h2>Inherited Menus</h2>
  <ul>
    <li tal:repeat="menu view/getInheritedMenus">
      <b tal:content="menu/id" /> (<span tal:replace="menu/title"/>)
      <a href="" tal:attributes="href string:?expand=${menu/id}">Expand</a>
      <ul tal:condition="python: menu['id'] == view.request.get('expand')">
        <li tal:repeat="item menu/local_items">
          <em tal:replace="item/title"/>
           (<span tal:replace="item/action"/>)
        </li>
      </ul>
    </li>
  </ul>


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

=== Added File Zope3/src/zope/app/menu/browser/tests.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Browser Menu Browser Tests

$Id: tests.py,v 1.1 2004/03/10 23:10:44 srichter Exp $
"""
import unittest

from zope.app.tests import ztapi
from zope.interface import Interface, implements

from zope.component import getServiceManager
from zope.app.services.tests.placefulsetup import PlacefulSetup

from zope.app.menu.browser import MenuAccessView
from zope.publisher.browser import TestRequest
from zope.publisher.interfaces.browser import IBrowserView
from zope.app.publisher.interfaces.browser import IBrowserMenuService
from zope.app.publication.traversers import TestTraverser
from zope.security.management import newSecurityManager
from zope.security.checker import defineChecker, NamesChecker, CheckerPublic
from zope.security.proxy import ProxyFactory
from zope.app.interfaces.services.service import ISimpleService

def d(title, action):
    return {'action': action, 'title': title, 'description': ''}

class Service:
    implements(IBrowserMenuService, ISimpleService)

    def getMenu(self, name, ob, req):
        return [d('l1', 'a1'),
                d('l2', 'a2/a3'),
                d('l3', '@@a3'),]

class I(Interface): pass
class C:
    implements(I)

    def __call__(self):
        pass

ob = C()
ob.a1 = C()
ob.a2 = C()
ob.a2.a3 = C()
ob.abad = C()
ob.abad.bad = 1

class V:
    implements(IBrowserView)

    def __init__(self, context, request):
        self.context = context
        self.request = request

    def __call__(self):
        pass


class Test(PlacefulSetup, unittest.TestCase):

    def setUp(self):
        PlacefulSetup.setUp(self)
        defineService = getServiceManager(None).defineService
        provideService = getServiceManager(None).provideService


        defineService('BrowserMenu', IBrowserMenuService)
        provideService('BrowserMenu', Service())
        ztapi.browserView(I, 'a3', [V])
        ztapi.browserView(None, '_traverse', [TestTraverser])
        defineChecker(C, NamesChecker(['a1', 'a2', 'a3', '__call__'],
                                      CheckerPublic,
                                      abad='waaa'))

    def test(self):
        newSecurityManager('who')
        v = MenuAccessView(ProxyFactory(ob), TestRequest())
        self.assertEqual(v['zmi_views'],
                         [{'description': '', 'title':'l1', 'action':'a1'},
                          {'description': '', 'title':'l2', 'action':'a2/a3'},
                          {'description': '', 'title':'l3', 'action':'@@a3'}
                          ])


def test_suite():
    loader = unittest.TestLoader()
    return loader.loadTestsFromTestCase(Test)

if __name__=='__main__':
    unittest.TextTestRunner().run(test_suite())




More information about the Zope3-Checkins mailing list