[Zope3-checkins] CVS: Zope3/src/zope/app/browser/services - menu.py:1.1.2.1 menu.pyc:1.1.2.1 menu.zcml:1.1.2.1 menu_contents.pt:1.1.2.1 menu_overview.pt:1.1.2.1 configure.zcml:1.66.2.1 eventcontrol.pt:1.4.2.1

Stephan Richter srichter at cosmos.phy.tufts.edu
Thu Aug 14 14:58:33 EDT 2003


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

Modified Files:
      Tag: dreamcatcher-ttwschema-branch
	configure.zcml eventcontrol.pt 
Added Files:
      Tag: dreamcatcher-ttwschema-branch
	menu.py menu.pyc menu.zcml menu_contents.pt menu_overview.pt 
Log Message:
Checkpoint check-in for people following the branch:

Got Local Browser Menu Service to work. I used a similar model to the 
interface service, where the service uses registered Browser Menu utilities
to get its menu entries.

There are also a bunch of policy-type decisions that come with local menus.
One is whether a local menu should overwrite or complement existing menus.
Currently I have an 'inherit' flag that can be set. If true, the local menu
will add to the existing entries, otherwise it will overwrite them. Note 
that this does not solve all use cases, such as if you want to take over
just a few entries, but I called YAGNI on it (someone else can do it, if it
is necessary).

I added and extended interfaces for all of this to work. I tried really 
hard to avoid rewriting the getMenu() methof for the local menu service 
version and I think I got it. ;-)

I also have a nice Overview screen for the Local Menu Service, which shows
you all available menus.

To Do:

  - Flesh out the interfaces and implement missing methods.

  - Clean up the code.

  - Fix tests.

  - Write a bunch of new tests.




=== Added File Zope3/src/zope/app/browser/services/menu.py ===
##############################################################################
#
# Copyright (c) 2003 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.
#
##############################################################################
"""Local Menu Service Views

$Id: menu.py,v 1.1.2.1 2003/08/14 17:57:54 srichter Exp $
"""
from zope.app import zapi
from zope.app.browser.container.contents import Contents
from zope.app.browser.form.widget import DisplayWidget, BrowserWidget
from zope.app.component.nextservice import queryNextService
from zope.app.form.widget import CustomWidget
from zope.app.interfaces.dublincore import IZopeDublinCore
from zope.app.interfaces.services.menu import ILocalBrowserMenu
from zope.app.services.servicenames import Utilities
from zope.security.proxy import trustedRemoveSecurityProxy


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 = zapi.queryAdapter(obj, IZopeDublinCore)
        if dc is not None:

            formatter = self.request.locale.getDateTimeFormatter('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)
        matching = utilities.getRegisteredMatching(ILocalBrowserMenu)
        matching = map(lambda m: (m[1], m[2].active().getComponent()),
                       matching)
        for menu_id, menu in matching:
            menus_info.append(self._getInfoFromMenu(menu_id, menu))
        return menus_info


    def getInheritedMenus(self):
        next = queryNextService(self.context, "BrowserMenu")
        menus = []
        while next is not None:
            try:
                menus += next.items()
            except AttributeError:
                # We deal with a global browser menu service
                service = trustedRemoveSecurityProxy(next)
                menus += service._registry.items()
            next = queryNextService(next, "BrowserMenu")
    
        menus_info = []
        for menu_id, menu in menus:
            menus_info.append(self._getInfoFromMenu(menu_id, menu))
        return menus_info
            

    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/browser/services/menu.pyc ===
  <Binary-ish file>

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

<!-- Browser Menu Service -->  
  <menuItem
      for="zope.app.interfaces.container.IAdding"
      menu="add_service"
      action="zope.app.services.MenuService"
      title="Menu Service" />

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

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

<!-- Browser Menu -->

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


  <addform
      label="Add Browser Menu (Registration)"
      for="zope.app.interfaces.services.menu.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" />


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

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

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

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

  <!-- Menu entry for "add component" menu -->
  <menuItem
      for="zope.app.interfaces.container.IAdding"
      menu="add_component"
      action="AddBrowserMenu"
      title="Browser Menu"
      description="A Persistent Browser Menu"
      permission="zope.ManageServices" />

  <!-- Menu entry for "add utility" menu -->
  <menuItem
      for="zope.app.interfaces.container.IAdding"
      menu="add_utility"
      action="AddBrowserMenu"
      title="Browser Menu"
      description="A Persistent Browser Menu"
      permission="zope.ManageServices" />


<!-- Browser Menu Item-->

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

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

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

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

</configure>


=== Added File Zope3/src/zope/app/browser/services/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/browser/services/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>

=== Zope3/src/zope/app/browser/services/configure.zcml 1.66 => 1.66.2.1 ===
--- Zope3/src/zope/app/browser/services/configure.zcml:1.66	Fri Aug  8 17:56:18 2003
+++ Zope3/src/zope/app/browser/services/configure.zcml	Thu Aug 14 13:57:53 2003
@@ -167,6 +167,10 @@
 <!-- Views -->  
   <include file="view.zcml" />
 
+<!-- Menu -->  
+  <include file="menu.zcml" />
+
+
 <!-- ZPT Templates -->
 
   <view


=== Zope3/src/zope/app/browser/services/eventcontrol.pt 1.4 => 1.4.2.1 ===
--- Zope3/src/zope/app/browser/services/eventcontrol.pt:1.4	Thu Aug  7 13:41:03 2003
+++ Zope3/src/zope/app/browser/services/eventcontrol.pt	Thu Aug 14 13:57:54 2003
@@ -6,8 +6,4 @@
 
 </div>
 </body>
-</html>
-
-
-
-
+</html>
\ No newline at end of file




More information about the Zope3-Checkins mailing list