[Zope3-checkins] SVN: Zope3/branches/srichter-blow-services/src/zope/app/ Fixed registration views, so that the site management interface becomes

Stephan Richter srichter at cosmos.phy.tufts.edu
Wed Jan 12 11:19:27 EST 2005


Log message for revision 28807:
  Fixed registration views, so that the site management interface becomes 
  useful again.
  
  Reimplemented tools with a compacter UI (which still needs some work).
  
  Fixed bug that prevented us to create absolute urls for views. This was 
  due to the fact that getView has been deprecated. The name and parent of 
  a view are now the responsibility of the factory.
  
  

Changed:
  U   Zope3/branches/srichter-blow-services/src/zope/app/component/browser/__init__.py
  U   Zope3/branches/srichter-blow-services/src/zope/app/component/browser/configure.zcml
  A   Zope3/branches/srichter-blow-services/src/zope/app/component/browser/editregistration.pt
  U   Zope3/branches/srichter-blow-services/src/zope/app/component/browser/metaconfigure.py
  U   Zope3/branches/srichter-blow-services/src/zope/app/component/browser/metadirectives.py
  A   Zope3/branches/srichter-blow-services/src/zope/app/component/browser/registered.pt
  A   Zope3/branches/srichter-blow-services/src/zope/app/component/browser/registration.pt
  U   Zope3/branches/srichter-blow-services/src/zope/app/component/browser/registration.py
  A   Zope3/branches/srichter-blow-services/src/zope/app/component/browser/site.py
  A   Zope3/branches/srichter-blow-services/src/zope/app/component/browser/site_management.pt
  D   Zope3/branches/srichter-blow-services/src/zope/app/component/browser/tool.pt
  D   Zope3/branches/srichter-blow-services/src/zope/app/component/browser/tools.pt
  U   Zope3/branches/srichter-blow-services/src/zope/app/component/browser/tools.py
  A   Zope3/branches/srichter-blow-services/src/zope/app/component/browser/utilreg_details.pt
  D   Zope3/branches/srichter-blow-services/src/zope/app/component/browser/xxx_tests/test_toolbacklink.py
  U   Zope3/branches/srichter-blow-services/src/zope/app/component/configure.zcml
  U   Zope3/branches/srichter-blow-services/src/zope/app/component/interfaces/__init__.py
  U   Zope3/branches/srichter-blow-services/src/zope/app/component/interfaces/registration.py
  U   Zope3/branches/srichter-blow-services/src/zope/app/component/registration.py
  U   Zope3/branches/srichter-blow-services/src/zope/app/container/browser/adding.py
  U   Zope3/branches/srichter-blow-services/src/zope/app/error/browser/configure.zcml
  U   Zope3/branches/srichter-blow-services/src/zope/app/form/browser/add.py
  U   Zope3/branches/srichter-blow-services/src/zope/app/form/browser/addwizard.py
  U   Zope3/branches/srichter-blow-services/src/zope/app/form/browser/editview.py
  U   Zope3/branches/srichter-blow-services/src/zope/app/form/browser/editwizard.py
  U   Zope3/branches/srichter-blow-services/src/zope/app/form/browser/schemadisplay.py
  U   Zope3/branches/srichter-blow-services/src/zope/app/module/manager.py
  U   Zope3/branches/srichter-blow-services/src/zope/app/pagetemplate/simpleviewclass.py
  U   Zope3/branches/srichter-blow-services/src/zope/app/principalannotation/configure.zcml
  U   Zope3/branches/srichter-blow-services/src/zope/app/publisher/browser/viewmeta.py
  U   Zope3/branches/srichter-blow-services/src/zope/app/security/browser/configure.zcml
  U   Zope3/branches/srichter-blow-services/src/zope/app/traversing/browser/absoluteurl.py
  U   Zope3/branches/srichter-blow-services/src/zope/app/traversing/namespace.py

-=-
Modified: Zope3/branches/srichter-blow-services/src/zope/app/component/browser/__init__.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/component/browser/__init__.py	2005-01-12 16:12:39 UTC (rev 28806)
+++ Zope3/branches/srichter-blow-services/src/zope/app/component/browser/__init__.py	2005-01-12 16:19:27 UTC (rev 28807)
@@ -47,11 +47,11 @@
         return self.added_object
 
     def nextURL(self):
-        v = zapi.queryView(
-            self.added_object, "registration.html", self.request)
+        v = zapi.queryMultiAdapter(
+            (self.added_object, self.request), name="registration.html")
         if v is not None:
-            url = str(
-                zapi.getView(self.added_object, 'absolute_url', self.request))
+            url = str(zapi.getMultiAdapter(
+                (self.added_object, self.request), name='absolute_url'))
             return url + "/@@registration.html"
 
         return super(ComponentAdding, self).nextURL()
@@ -116,7 +116,8 @@
             self.added_object, "addRegistration.html", self.request)
         if v is not None:
             url = str(
-                zapi.getView(self.added_object, 'absolute_url', self.request))
+                zapi.getAdapter((self.added_object, self.request),
+                                name='absolute_url'))
             return url + "/addRegistration.html"
 
         return super(UtilityAdding, self).nextURL()
@@ -179,177 +180,3 @@
         self.context.setSiteManager(sm)
         self.request.response.redirect(
             "++etc++site/@@SelectedManagementView.html")
-
-
-class Interfaces(object):
-    """Interface service view
-
-    >>> from zope.interface import Interface
-    >>> from zope.app.content.interfaces import IContentType
-    >>> class DCInterface(Interface):
-    ...     '''DCInterfaceDoc
-    ...
-    ...     This is a multi-line doc string.
-    ...     '''
-    ... 
-    >>> class DummyInterface(object):
-    ...     def items(self):
-    ...         return [('DCInterface', DCInterface)]
-    ...
-    >>> provideInterface('', DCInterface, IContentType)
-    >>> from zope.publisher.browser import TestRequest
-    >>> request = TestRequest()
-    >>> interface_view = Interfaces(DummyInterface(), request)
-    >>> from pprint import PrettyPrinter
-    >>> pprint=PrettyPrinter(width=50).pprint
-    >>> pprint(interface_view.getInterfaces())
-    [{'doc': 'DCInterfaceDoc',
-      'id': 'zope.app.site.browser.DCInterface',
-      'name': 'DCInterface'}]
-        
-
-    """
-
-    def __init__(self, context, request):
-        self.context = context
-        self.request = request
-
-    def getInterfaces(self):
-        L = [(iface.__name__, iface.__module__+'.'+iface.__name__,
-              getattr(iface, '__doc__', '').split('\n')[0].strip()
-              )
-             for iface in searchInterface(self.context)]
-        L.sort()
-        return [{"id": id, "name": name, "doc": doc} for name, id, doc in L]
-
-class Detail(object):
-    """Interface Details
-
-    >>> from zope.schema import TextLine
-    >>> from zope.interface import Interface
-    >>> from zope.app.content.interfaces import IContentType
-    >>> from zope.i18n import MessageIDFactory
-    >>> from zope.interface.interfaces import IInterface
-    >>> _ = MessageIDFactory('zope')
-    >>> class TestInterface(Interface):
-    ...     '''Test Interface'''
-    ...     test_field = TextLine(title = _(u'Test Name'))
-    ...     def testMethod():
-    ...         'Returns test name'
-    ...
-    >>> class TestClass(object):
-    ...     def getInterface(self, id=None):
-    ...         return TestInterface
-    ...
-    >>> IInterface.providedBy(TestInterface)
-    True
-    >>> provideInterface('', TestInterface, IContentType)
-    >>> from zope.publisher.browser import TestRequest
-    >>> request = TestRequest()
-    >>> form = {'id': 'zope.app.site.browser.TestInterface'}
-    >>> request.form = form
-    >>> interface_details = Detail(TestClass(), request)
-    >>> interface_details.setup()
-    >>> interface_details.name
-    'TestInterface'
-    >>> interface_details.doc
-    'Test Interface'
-    >>> interface_details.iface.__name__
-    'TestInterface'
-    >>> [method['method'].__name__ for method in
-    ...     interface_details.methods]
-    ['testMethod']
-    >>> [field.__name__ for field in interface_details.schema]
-    ['test_field']
-    
-    """
-
-    def __init__(self, context, request):
-        self.context = context
-        self.request = request
-    
-    def setup(self):
-        try:
-            id = self.request["id"]
-        except KeyError:
-            raise zapi.UserError("Please click on an interface name to view"
-                  " details.")
-        
-        iface = getInterface(self.context, id)
-
-        from zope.proxy import getProxiedObject
-        self.iface = getProxiedObject(iface)
-        
-        self.name = self.iface.__name__
-        self.doc = getattr(self.iface, '__doc__', '')
-        self.methods = []
-        self.schema = []
-
-        for name in self.iface:
-            defn = self.iface[name]
-            if IMethod.providedBy(defn):
-                title = defn.__doc__.split('\n')[0].strip()
-                self.methods.append({'method': defn, 'title': title})
-            elif IField.providedBy(defn):
-                self.schema.append(defn)
-
-class MethodDetail(object):
-    """Interface Method Details
-
-    >>> from zope.interface import Interface
-    >>> from zope.i18n import MessageIDFactory
-    >>> _ = MessageIDFactory('zope')
-    >>> class TestInterface(Interface):
-    ...     '''Test Interface'''
-    ...     def testMethod():
-    ...         'Returns test name'
-    ...
-    >>> class TestClass(object):
-    ...     def getInterface(self, id=None):
-    ...         return TestInterface
-    ...
-    >>> provideInterface('', TestInterface)
-    >>> from zope.publisher.browser import TestRequest
-    >>> request = TestRequest()
-    >>> form = {
-    ... 'interface_id': 'zope.app.site.browser.TestInterface',
-    ... 'method_id': 'testMethod'}
-    >>> request.form = form
-    >>> imethod_details = MethodDetail(TestClass(), request)
-    >>> imethod_details.setup()
-    >>> imethod_details.name
-    'testMethod'
-    >>> imethod_details.doc
-    'Returns test name'
-    >>> imethod_details.iface.__name__
-    'TestInterface'
-    >>> imethod_details.method.__name__
-    'testMethod'
-
-    """
-
-    def __init__(self, context, request):
-        self.context = context
-        self.request = request
-    
-    def setup(self):
-        try:
-            interface_id = self.request["interface_id"]
-        except KeyError:
-            raise zapi.UserError("Please click on a method name in the Detail"
-                                 " tab to view method details.")
-        try:
-            method_id = self.request["method_id"]
-        except KeyError:
-            raise zapi.UserError("Please click on a method name to view"
-                  " details.")
-        
-        iface = getInterface(self.context, interface_id)
-
-        from zope.proxy import getProxiedObject
-        self.iface = getProxiedObject(iface)
-
-        self.method = self.iface[method_id]
-        self.name = self.method.__name__
-        self.doc = self.method.__doc__
-

Modified: Zope3/branches/srichter-blow-services/src/zope/app/component/browser/configure.zcml
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/component/browser/configure.zcml	2005-01-12 16:12:39 UTC (rev 28806)
+++ Zope3/branches/srichter-blow-services/src/zope/app/component/browser/configure.zcml	2005-01-12 16:19:27 UTC (rev 28807)
@@ -2,8 +2,91 @@
    xmlns:zope="http://namespaces.zope.org/zope"
    xmlns="http://namespaces.zope.org/browser">
 
-<!-- SiteManagementFolder -->
+<!-- Registration Managemenet -->
 
+  <!-- BBB: Backward-compatibility: 12/07/2004 -->
+  <!-- XXX: temp. deactivated
+  <zope:view
+      for="zope.app.component.interfaces.registration.IComponentPath"
+      type="zope.publisher.interfaces.browser.IBrowserRequest"
+      provides="zope.app.form.interfaces.IInputWidget"
+      factory=".registration.ComponentPathWidget"
+      permission="zope.Public"
+      />
+
+  <zope:view
+      for="zope.app.component.interfaces.registration.IComponentPath"
+      type="zope.publisher.interfaces.browser.IBrowserRequest"
+      provides="zope.app.form.interfaces.IDisplayWidget"
+      factory=".registration.ComponentPathWidget"
+      permission="zope.Public"
+      />
+   -->
+  <!-- BBB: End of backward-compatibility block -->
+
+  <zope:view
+      for="zope.app.component.interfaces.registration.IComponent"
+      type="zope.publisher.interfaces.browser.IBrowserRequest"
+      provides="zope.app.form.interfaces.IInputWidget"
+      factory=".registration.ComponentWidget"
+      permission="zope.Public"
+      />
+
+  <zope:view
+      for="zope.app.component.interfaces.registration.IComponent"
+      type="zope.publisher.interfaces.browser.IBrowserRequest"
+      provides="zope.app.form.interfaces.IDisplayWidget"
+      factory=".registration.ComponentWidget"
+      permission="zope.Public"
+      />
+
+  <page
+      name="index.html" 
+      for="zope.app.component.interfaces.registration.IRegistrationManager"
+      menu="zmi_views" title="Registration"
+      permission="zope.ManageSite"
+      class=".registration.EditRegistration"
+      template="editregistration.pt" />
+
+  <!-- For now, we'll allow CMs to be added, but we won't include them
+       in the add_component menu. -->
+
+  <view
+      for="zope.app.component.interfaces.registration.IRegistrationManager"
+      name="+"
+      menu="zmi_actions" title="Add"
+      permission="zope.ManageSite"
+      class=".registration.RegistrationAdding"
+      >
+    <page name="index.html"  attribute="index"  />
+    <page name="action.html" attribute="action" />
+  </view>
+
+  <!-- Generic page for objects that keep track of their registrations.
+       Objects that need to override one of these may need to override
+       both.  The "registrations.html" page is only used for objects
+       that have more than one registration. -->
+
+  <page
+      for="zope.app.component.interfaces.registration.IRegisterable"
+      name="registrations.html"
+      template="registered.pt"
+      class=".registration.Registered"
+      permission="zope.ManageSite"
+      />
+
+  <page
+      for="zope.app.component.interfaces.registration.IRegisterable"
+      name="registration.html"
+      template="registration.pt"
+      class=".registration.RegistrationView"
+      permission="zope.ManageSite"
+      menu="zmi_views" title="Registration"
+      />
+
+
+<!-- Site Management Folder -->
+
   <addMenuItem
       class="zope.app.component.site.SiteManagementFolder"
       permission="zope.ManageSite"
@@ -66,38 +149,6 @@
 
 <!-- SiteManager -->
 
-  <!--XXX: page
-     for="zope.app.component.interfaces.ILocalSiteManager"
-     name="tasks.html"
-     menu="zmi_views" title="Tasks"
-     template="tasks.pt"
-     permission="zope.ManageSite" /-->
-
-  <!-- XXX: page
-      for="zope.app.component.interfaces.ILocalSiteManager"
-      name="interfacebrowse.html"
-      template="interfacebrowse.pt"
-      class=".Interfaces"
-      permission="zope.ManageServices"
-      menu="zmi_views" title="Interface Browse" 
-      /-->
-  
-  <!-- XXX: page
-      for="zope.app.component.interfaces.ILocalSiteManager"
-      name="interfacedetail.html"
-      template="interfacedetail.pt"
-      class=".Detail"
-      permission="zope.ManageServices"
-      /-->
-
-  <!-- page
-      for="zope.app.component.interfaces.ILocalSiteManager"
-      name="interfacemethoddetail.html"
-      template="interfacemethoddetail.pt"
-      class=".MethodDetail"
-      permission="zope.ManageServices"
-      /-->
-
   <menuItems
       menu="zmi_actions"
       for="zope.app.component.interfaces.ILocalSiteManager">
@@ -136,46 +187,100 @@
     <page name="index.html" attribute="index" />
   </pages>
 
-<!-- Adapter Registration -->
+  <view
+      name="SiteManagement"
+      for="zope.app.component.interfaces.ILocalSiteManager"
+      menu="zmi_views" title="Site Management"
+      class=".tools.SiteManagementView"
+      permission="zope.ManageSite"
+      >
+    <page name="index.html" template="site_management.pt" />
+  </view>
 
+<!-- Site Management Folder -->
+
+  <menuItem
+      menu="zmi_actions"
+      for="zope.app.component.interfaces.ISiteManagementFolder"
+      title="Registrations"
+      action="++registrations++/@@SelectedManagementView.html"
+      permission="zope.ManageSite"
+      />
+
+
+<!-- Utility Registration -->
+
+  <!-- When creating a new utility object, you are taken to this
+       form to configure it.  The form lets you choose a name,
+       an interface, a permission, and a registration status
+       (Inactive or Active). -->
+  <addform
+      label="New Utility Registration"
+      for="zope.app.component.interfaces.ILocalUtility"
+      name="addRegistration.html"
+      schema="zope.app.component.interfaces.IUtilityRegistration"
+      class=".registration.AddComponentRegistration"
+      permission="zope.ManageSite"
+      content_factory="zope.app.component.site.UtilityRegistration"
+      arguments="name provided component"
+      fields="name provided component status permission"
+      >
+    <widget 
+        field="name" 
+        class="zope.app.form.browser.TextWidget"
+        required="False"
+        convert_missing_value="False"
+        />
+  </addform>
+
+  <!-- When editing the registration of an existing utility object,
+       you are taken to this form.  It is similar to the above add
+       form, but doesn't let you change the name, interface or path.
+       (Thus leaving only permission and registration status.) -->
   <editform
-    schema="..interfaces.IAdapterRegistration"
-    name="index.html"
-    menu="zmi_views"
-    label="Change adapter"
-    permission="zope.ManageSite"
-    />
+      menu="zmi_views" title="Edit"
+      label="Edit Utility Registration"
+      name="index.html"
+      schema="zope.app.component.interfaces.IUtilityRegistration"
+      permission="zope.ManageSite"
+      fields="name provided component status permission" />
 
-  <!-- XXX: addform
-      schema="..interfaces.IAdapterRegistration"
-      name="AdapterRegistration"
-      content_factory="..site.AdapterRegistration"
+  <page
+      for="..interfaces.IUtilityRegistration"
+      name="details"
+      template="utilreg_details.pt"
+      class=".site.UtilityRegistrationDetails"
+      permission="zope.Public"
+      />
+
+
+<!-- Adapter Registration -->
+
+  <!--XXX: addform
+      label="New Adapter Registration"
+      schema="zope.app.component.interfaces.IAdapterRegistration"
+      name="addRegistration.html"
+      content_factory="zope.app.component.site.AdapterRegistration"
       arguments="required provided factoryName"
       keyword_arguments="name permission"
-      label="Register an adapter"
       permission="zope.ManageServices"
       fields="required provided name permission factoryName" 
       menu="add_registration" title="Adapter Registration"
       /-->
 
-<!-- Tools Views -->
+  <!-- XXX: addMenuItem
+      view="addAdapterRegistration.html"
+      class="zope.app.component.site.AdapterRegistration"
+      permission="zope.ManageSite"
+      title="Adapter Registration"
+      /-->
 
-  <page
-     name="tools.html"
-     for="zope.app.component.interfaces.ILocalSiteManager"
-     permission="zope.ManageSite"
-     template="tools.pt"
-     menu="zmi_views" title="Tools"
-     class=".tools.ToolsOverview"
-     />
+  <editform
+    schema="..interfaces.IAdapterRegistration"
+    name="index.html"
+    menu="zmi_views"
+    label="Change adapter"
+    permission="zope.ManageSite"
+    />
 
-  <page
-     name="tools.html"
-     for="zope.app.component.interfaces.ILocalUtility"
-     permission="zope.ManageSite"
-     class=".tools.ToolsBacklink"
-     attribute="getLink"
-     menu="zmi_actions" title="Tools"
-     />
-
 </zope:configure>

Copied: Zope3/branches/srichter-blow-services/src/zope/app/component/browser/editregistration.pt (from rev 28777, Zope3/branches/srichter-blow-services/src/zope/app/component/bbb/registration/browser/editregistration.pt)
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/component/bbb/registration/browser/editregistration.pt	2005-01-10 22:29:04 UTC (rev 28777)
+++ Zope3/branches/srichter-blow-services/src/zope/app/component/browser/editregistration.pt	2005-01-12 16:19:27 UTC (rev 28807)
@@ -0,0 +1,56 @@
+<html metal:use-macro="context/@@standard_macros/view">
+<head>
+  <title metal:fill-slot="title" i18n:translate="">
+    Registration Manager
+  </title>
+</head>
+<body>
+<div metal:fill-slot="body">
+
+  <h2 i18n:translate="">Registration Manager</h2>
+
+  <form action="." method="POST"
+        tal:define="message view/update"
+        tal:attributes="action request/URL">
+
+    <p tal:condition="message" tal:content="message" />
+
+    <table>
+      <thead>
+        <tr>
+          <th></th>
+          <th align="left" i18n:translate="">Summary</th>
+        </tr>
+      </thead>
+      <tbody>
+        <tr tal:repeat="reg view/registrationInfo">
+          <td valign="top">
+            <input type="checkbox" name="keys:list" value="1"
+                   tal:attributes="value reg/name" />
+          </td>
+          <td>
+            <a href="." tal:attributes="href reg/name">
+              Config item <span tal:content="reg/name" />
+            </a>
+            <span tal:condition="not:reg/active"
+                i18n:translate="">(disabled)</span>
+            <br />
+            <span tal:content="structure reg/details">
+              Registration Details
+            </span>
+          </td>
+        </tr>
+      </tbody>
+    </table>
+
+    <div class="row">
+      <input type="submit" name="refresh_submit" value="Refresh" 
+             i18n:attributes="value refresh-button" />
+      <input type="submit" name="remove_submit" value="Remove" 
+             i18n:attributes="value remove-button" />
+    </div>
+  </form>
+
+</div>
+</body>
+</html>

Modified: Zope3/branches/srichter-blow-services/src/zope/app/component/browser/metaconfigure.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/component/browser/metaconfigure.py	2005-01-12 16:12:39 UTC (rev 28806)
+++ Zope3/branches/srichter-blow-services/src/zope/app/component/browser/metaconfigure.py	2005-01-12 16:19:27 UTC (rev 28807)
@@ -11,48 +11,21 @@
 # FOR A PARTICULAR PURPOSE.
 #
 ##############################################################################
-"""Configuration handlers for 'tools' directive.
+"""Configuration handlers for 'tool' directive.
 
 $Id$
 """
-from zope.publisher.interfaces.browser import IBrowserRequest, IBrowserPublisher
-from zope.app.component.metaconfigure import view, interface as ifaceDirective
-from zope.app.publisher.browser.viewmeta import view as complexView
+from zope.app.component.metaconfigure import utility
+from zope.app.component.metaconfigure import interface as ifaceDirective
+from tools import IToolType, IToolConfiguration, ToolConfiguration
 
-from zope.component.interfaces import ISiteManager
-from tools import IToolView, IUtilityToolView, IToolType
-from tools import UtilityToolAdding, UtilityToolView
 
-
-def tool(_context, interface, folder="tools", title=None, description=None):
-    name = "manage" + interface.getName() + "Tool.html"
-    addName = "Add" + interface.getName() + "Tool"
-    
+def tool(_context, interface, title, description=None,
+         folder="tools", unique=False):
+    name = interface.getName()
     permission = 'zope.ManageContent'
+    tool = ToolConfiguration(interface, title, description, unique)
 
     ifaceDirective(_context, interface, IToolType)
-
-    class_ = type("UtilityToolView for %s" % interface.getName(),
-                  (UtilityToolView,),
-                  {'interface':interface,
-                   'folder':folder,
-                   'title':title,
-                   'description':description})
-    
-    view(_context, [class_], IBrowserRequest, name, [ISiteManager],
-         permission=permission,
-         allowed_interface=[IUtilityToolView, IBrowserPublisher],
-         allowed_attributes=['__call__', '__getitem__'])
-
-    class_ = type("UtilityToolAdding for %s" % interface.getName(),
-                  (UtilityToolAdding,),
-                  {'_addFilterInterface': interface,
-                   'folder':folder,
-                   'title':'Add %s Tool' % interface.getName()} )
-
-    addView = complexView(_context, ISiteManager, permission, addName,
-                          class_=class_)
-    addView.page(_context, 'index.html', 'index')
-    addView.page(_context, 'action.html', 'action')
-
-    addView()
+    utility(_context, IToolConfiguration, tool,
+            permission=permission, name=name)

Modified: Zope3/branches/srichter-blow-services/src/zope/app/component/browser/metadirectives.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/component/browser/metadirectives.py	2005-01-12 16:12:39 UTC (rev 28806)
+++ Zope3/branches/srichter-blow-services/src/zope/app/component/browser/metadirectives.py	2005-01-12 16:19:27 UTC (rev 28807)
@@ -21,6 +21,7 @@
     
 class IUtilityToolDirective(Interface):
     """Directive for creating new utility-based tools."""
+
     folder = zope.configuration.fields.PythonIdentifier(
         title=u"Destination Folder",
         description=u"""Destination Folder in which the tool instances are
@@ -45,3 +46,9 @@
         description=u"Interface used to filter out the available entries in a \
                       tool",
         required=True)
+
+    unique = zope.configuration.fields.Bool(
+        title=u"Unique",
+        description=u"Specifies whether the tool is unique to a site manager.",
+        required=False,
+        default=False)

Copied: Zope3/branches/srichter-blow-services/src/zope/app/component/browser/registered.pt (from rev 28777, Zope3/branches/srichter-blow-services/src/zope/app/component/bbb/registration/browser/registered.pt)
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/component/bbb/registration/browser/registered.pt	2005-01-10 22:29:04 UTC (rev 28777)
+++ Zope3/branches/srichter-blow-services/src/zope/app/component/browser/registered.pt	2005-01-12 16:19:27 UTC (rev 28807)
@@ -0,0 +1,24 @@
+<html metal:use-macro="context/@@standard_macros/view">
+<body>
+<div metal:fill-slot="body">
+
+  <p i18n:translate="">Registrations for this object:</p>
+
+  <ul>
+    <li tal:repeat="reg view/registrations">
+
+      <a href=""
+         tal:attributes="href reg/url"
+         tal:content="reg/name">Name</a>
+      (<span tal:replace="reg/status">Active</span>)
+      <span tal:replace="structure reg/details" />
+    </li>
+  </ul>
+
+  <p><a href="addRegistration.html" i18n:translate="">
+    Add a registration for this object
+  </a></p>
+
+</div>
+</body>
+</html>

Copied: Zope3/branches/srichter-blow-services/src/zope/app/component/browser/registration.pt (from rev 28777, Zope3/branches/srichter-blow-services/src/zope/app/component/bbb/registration/browser/registration.pt)
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/component/bbb/registration/browser/registration.pt	2005-01-10 22:29:04 UTC (rev 28777)
+++ Zope3/branches/srichter-blow-services/src/zope/app/component/browser/registration.pt	2005-01-12 16:19:27 UTC (rev 28807)
@@ -0,0 +1,57 @@
+<html metal:use-macro="context/@@standard_macros/view">
+<body>
+<div metal:fill-slot="body">
+
+<form tal:attributes="action request/URL" method="POST"
+      tal:define="ignored view/update">
+
+  <div tal:condition="view/registered">
+    <div tal:define="registration view/registration">
+      <p i18n:translate="">This object is registered as:</p>
+
+      <div class="registrationSummary">
+        <div tal:content="structure registration/details">
+          Details
+        </div>
+        <div class="modificationLink">
+          <a tal:attributes="href registration/url"
+             i18n:translate="">(modify)</a>
+        </div>
+      </div>
+
+      <tal:block condition="view/active">
+        <p i18n:translate="">This object is currently active.</p>
+        <input type="submit" i18n:attributes="value deactivate-button"
+          value="Deactivate" name="deactivate" />
+      </tal:block>
+      <tal:block condition="not:view/active">
+        <p i18n:translate="">This object is currently inactive.</p>
+        <input type="submit" i18n:attributes="value activate-button"
+          value="Activate" name="activate" />
+      </tal:block>
+    </div>
+
+    <hr />
+    <a href="registrations.html" i18n:translate="">
+      Advanced Options
+    </a>
+
+  </div>
+
+  <div tal:condition="not:view/registered">
+    <p i18n:translate="">This object is not currently active.</p>
+
+    <p i18n:translate="">
+      This object won't actually be used unless it is registered to
+      perform a specific function and is activated.
+    </p>
+
+    <input type="submit" value="Register" name="activate"
+      i18n:attributes="value register-button" />
+  </div>
+
+</form>
+
+</div>
+</body>
+</html>

Modified: Zope3/branches/srichter-blow-services/src/zope/app/component/browser/registration.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/component/browser/registration.py	2005-01-12 16:12:39 UTC (rev 28806)
+++ Zope3/branches/srichter-blow-services/src/zope/app/component/browser/registration.py	2005-01-12 16:19:27 UTC (rev 28807)
@@ -27,21 +27,19 @@
 from zope.app.i18n import ZopeMessageIDFactory as _
 from zope.app.pagetemplate.viewpagetemplatefile import ViewPageTemplateFile
 from zope.app.publisher.browser import BrowserView
+from zope.app.component import interfaces
 from zope.app.component.interfaces.registration import ActiveStatus
-from zope.app.component.interfaces.registration import IRegistered
-from zope.app.component.interfaces.registration import IRegistration
+from zope.app.component.interfaces.registration import InactiveStatus
 
 class RegistrationView(BrowserView):
     """View for registerable objects that have at most one registration.
 
     If the object has more than one registration, this performs a
     redirection to the 'registrations.html' view.
-
     """
-
     def __init__(self, context, request):
         super(RegistrationView, self).__init__(context, request)
-        useconfig = IRegistered(self.context)
+        useconfig = interfaces.registration.IRegistered(self.context)
         self.registrations = useconfig.registrations()
 
     def update(self):
@@ -50,7 +48,7 @@
             self.request.response.redirect("registrations.html")
             return
         if "deactivate" in self.request:
-            self.registrations[0].status = RegisteredStatus
+            self.registrations[0].status = InactiveStatus
         elif "activate" in self.request:
             if not self.registrations:
                 # create a registration:
@@ -69,32 +67,26 @@
 
         If there are no registrations, raises an error.
         """
-        return self.registrations[0]
+        return {'url': zapi.absoluteURL(self.registrations[0], self.request),
+                'details': zapi.queryMultiAdapter(
+                    (self.registrations[0], self.request), name='details')
+                }
 
 
 class Registered(object):
-    """View for registerable objects that more than one registration."""
+    """View for registerable objects with more than one registration."""
 
-    def __init__(self, context, request):
-        self.context = context
-        self.request = request
+    def registrations(self):
+        registered = interfaces.registration.IRegistered(self.context)
+        return [
+            {'name': zapi.name(reg),
+             'url': zapi.absoluteURL(reg, self.request),
+             'status': reg.status,
+             'details': zapi.queryMultiAdapter((reg, self.request),
+                                               name='details')}
+            for reg in registered.registrations()]
 
-    def uses(self):
-        component = self.context
-        useconfig = IRegistered(component)
-        result = []
-        for path in useconfig.usages():
-            config = zapi.traverse(component, path)
-            description = config.usageSummary()
-            url = zapi.getView(config, 'absolute_url', self.request)
-            result.append({'path': path,
-                           'url': url(),
-                           'status': config.status,
-                           'description': description,
-                           })
-        return result
 
-
 class ChangeRegistrations(BrowserView):
 
     _prefix = 'registrations'
@@ -126,11 +118,9 @@
         return message
 
     def update(self):
-
         message = self.applyUpdates()
 
-        self.configBase = str(zapi.getView(zapi.getServices(), 'absolute_url',
-                                           self.request))
+        self.configBase = zapi.absoluteURL(zapi.getSiteManager(), self.request)
 
         registrations = self.context.info()
 
@@ -185,7 +175,7 @@
         # Render as a link to the component
         field = self.context
         context = field.context
-        if IRegistration.providedBy(context):
+        if interfaces.registration.IRegistration.providedBy(context):
             # It's a registration object. Just get the corresponding attr
             path = getattr(context, field.__name__)
             # The path may be relative; then interpret relative to ../..
@@ -198,7 +188,7 @@
             # Always use a relative path (just the component name)
             path = zapi.name(context)
 
-        url = zapi.getView(component, 'absolute_url', self.request)
+        url = zapi.absoluteURL(component, self.request)
 
         return ('<a href="%s/@@SelectedManagementView.html">%s</a>'
                 % (url, path))
@@ -215,7 +205,7 @@
         """See zope.app.form.interfaces.IWidget"""
         field = self.context
         context = field.context
-        if IRegistration.providedBy(context):
+        if interfaces.registration.IRegistration.providedBy(context):
             # It's a registration object. Just get the corresponding attr
             path = getattr(context, field.getName())
         else:
@@ -242,7 +232,7 @@
         # Render as a link to the component
         field = self.context
         context = field.context
-        if IRegistration.providedBy(context):
+        if interfaces.registration.IRegistration.providedBy(context):
             # It's a registration object. Just get the corresponding attr
             component = getattr(context, field.__name__)
             path = zapi.getPath(component)
@@ -252,7 +242,7 @@
             # Always use a relative path (just the component name)
             path = zapi.name(context)
 
-        url = zapi.getView(component, 'absolute_url', self.request)
+        url = zapi.absoluteURL(component, self.request)
 
         return ('<a href="%s/@@SelectedManagementView.html">%s</a>'
                 % (url, path))
@@ -269,7 +259,7 @@
         """See zope.app.form.interfaces.IWidget"""
         field = self.context
         context = field.context
-        if IRegistration.providedBy(context):
+        if interfaces.registration.IRegistration.providedBy(context):
             # It's a registration object. Just get the corresponding attr
             return getattr(context, field.getName())
 
@@ -298,9 +288,10 @@
 
         component = self.context
 
+        # XXX: Fix to use addRegistration()
         # Get the registration manager for this folder
         folder = component.__parent__
-        rm = folder.getRegistrationManager()
+        rm = folder.registrationManager
 
         name = INameChooser(rm).chooseName('', registration)
         rm[name] = registration
@@ -312,20 +303,15 @@
 
 class RegistrationAdding(Adding):
     """Adding subclass for adding registrations."""
-
     menu_id = "add_registration"
 
     def nextURL(self):
-        return str(zapi.getView(self.context, "absolute_url", self.request))
+        return zapi.absoluteURL(self.context, self.request)
 
 
 class EditRegistration(BrowserView):
     """A view on a registration manager, used by registrations.pt."""
 
-    def __init__(self, context, request):
-        self.request = request
-        self.context = context
-
     def update(self):
         """Perform actions depending on user input."""
 
@@ -339,18 +325,6 @@
         if 'remove_submit' in self.request:
             if not k: return msg
             self.remove_objects(k)
-        elif 'top_submit' in self.request:
-            if not k: return msg
-            self.context.moveTop(k)
-        elif 'bottom_submit' in self.request:
-            if not k: return msg
-            self.context.moveBottom(k)
-        elif 'up_submit' in self.request:
-            if not k: return msg
-            self.context.moveUp(k)
-        elif 'down_submit' in self.request:
-            if not k: return msg
-            self.context.moveDown(k)
         elif 'refresh_submit' in self.request:
             pass # Nothing to do
 
@@ -362,18 +336,12 @@
         for name in key_list:
             del container[name]
 
-    def configInfo(self):
+    def registrationInfo(self):
         """Render View for each directives."""
-        result = []
-        for name, configobj in self.context.items():
-            url = str(zapi.getView(configobj, 'absolute_url', self.request))
-            active = configobj.status == ActiveStatus
-            summary1 = getattr(configobj, "usageSummary", None)
-            summary2 = getattr(configobj, "implementationSummary", None)
-            item = {'name': name, 'url': url, 'active': active}
-            if summary1:
-                item['line1'] = summary1()
-            if summary2:
-                item['line2'] = summary2()
-            result.append(item)
-        return result
+        return [
+            {'name': name,
+             'url': zapi.absoluteURL(reg, self.request),
+             'active': reg.status == ActiveStatus,
+             'details': zapi.queryMultiAdapter((reg, self.request),
+                                               name='details')}
+            for name, reg in self.context.items()]

Added: Zope3/branches/srichter-blow-services/src/zope/app/component/browser/site.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/component/browser/site.py	2005-01-12 16:12:39 UTC (rev 28806)
+++ Zope3/branches/srichter-blow-services/src/zope/app/component/browser/site.py	2005-01-12 16:19:27 UTC (rev 28807)
@@ -0,0 +1,35 @@
+##############################################################################
+#
+# Copyright (c) 2005 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (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.
+#
+##############################################################################
+"""Site Management view code
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+from zope.app import zapi
+
+class UtilityRegistrationDetails(object):
+    """Utility Registration Details"""
+
+    def provided(self):
+        provided = self.context.provided
+        return provided.__module__ + '.' + provided.__name__
+
+    def name(self):
+        return self.context.name or '<no name>'
+
+    def component(self):
+        url = zapi.getMultiAdapter(
+            (self.context.component, self.request), name='absolute_url')
+        name = zapi.name(self.context.component)
+        return {'url': url, 'name': name}

Added: Zope3/branches/srichter-blow-services/src/zope/app/component/browser/site_management.pt
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/component/browser/site_management.pt	2005-01-12 16:12:39 UTC (rev 28806)
+++ Zope3/branches/srichter-blow-services/src/zope/app/component/browser/site_management.pt	2005-01-12 16:19:27 UTC (rev 28807)
@@ -0,0 +1,121 @@
+<html metal:use-macro="context/@@standard_macros/page">
+<body>
+<div metal:fill-slot="body">
+
+  <h1 i18n:translate="">
+    <b>Site Management</b>
+  </h1>
+
+  <div class="message"
+       tal:define="message view/update"
+       tal:condition="message"
+       tal:content="message">
+    Status Message
+  </div>
+
+  <h2>
+    <b>Unique Utilities</b>
+  </h2>
+  <div>
+    Unique utilities can only exist once per site manager and have no name.
+  </div>
+  <br/>
+  <form action="." method="post">
+    <div tal:repeat="tool view/getUniqueTools">
+      <input type="checkbox" name="selected:list" value="" 
+             tal:attributes="value tool/name" />
+      <span 
+          tal:content="tool/title"
+          tal:condition="not:tool/exists">
+        Authentication
+      </span>
+      <a href="" style="color: green" 
+          tal:content="tool/title"
+          tal:condition="tool/exists">
+        Authentication
+      </a>
+    </div>
+    <br/>
+    <input type="submit" name="INSTALL-SUBMIT" value="Install">&nbsp;
+    <input type="submit" name="UNINSTALL-SUBMIT" value="Uninstall">
+  </form>
+
+  <form action="." method="post" tal:repeat="tool view/getTools">
+    <input type="hidden" name="activeTool" value=""
+           tal:attributes="value tool/name" />
+    <h3>
+      <b tal:content="tool/title">Caches</b>
+    </h3>
+    <div tal:content="tool/description">
+      Description of the tool
+    </div>
+    <br/>
+    <div tal:define="instances tool/instances">
+      <div tal:repeat="instance instances"
+           tal:condition="instances">
+        <input type="checkbox" name="selected:list" value="" 
+               tal:attributes="value instance/name" />
+
+        <span tal:condition="not:instance/rename">
+          <span tal:condition="instance/active">
+            <a href="" style="color: green"
+               tal:attributes="href instance/url"
+               tal:content="instance/name">
+              sql-queries
+            </a>
+            (Active)
+          </span>
+          <span tal:condition="not:instance/active">
+            <a href="" style="color: red"
+               tal:attributes="href instance/url"
+               tal:content="instance/name">
+              sql-queries
+            </a>
+            (Inactive)
+          </span>
+        </span>
+        <span tal:condition="instance/rename">
+          <input type="hidden" name="old_names:list" value=""
+                 tal:attributes="value instance/name" />
+          <input type="text" size="20" name="new_names:list" value=""
+                 tal:attributes="value instance/name" />
+        </span>
+
+      </div>
+      <div tal:condition="not:instances">
+        <i>No instances of this utility are available yet.</i>
+      </div>
+    </div>
+    <div tal:condition="tool/add"
+         tal:define="info view/addingInfo">
+      <input type="text" width="20" name="id" value="">
+      <select name="type_name">
+        <option tal:repeat="entry info"
+                tal:attributes="value entry/action"
+                tal:content="entry/title">RAM Cache</option>
+      </select>
+      &nbsp;
+      <input type="submit" name="ADD-TOOL-SUBMIT" value="Add">
+      <input type="submit" name="CANCEL-ADD-TOOL-SUBMIT" value="Cancel">
+    </div>
+    <br/>
+    <div>
+      <input type="submit" name="ACTIVATE-SUBMIT" value="Activate"
+             tal:condition="not:tool/rename">&nbsp;
+      <input type="submit" name="DEACTIVATE-SUBMIT" value="Deactivate"
+             tal:condition="not:tool/rename">
+      &nbsp;&nbsp;
+      <input type="submit" name="ADD-SUBMIT" value="Add"
+             tal:condition="not:tool/rename">&nbsp;
+      <input type="submit" name="DELETE-SUBMIT" value="Delete"
+             tal:condition="not:tool/rename">&nbsp;
+      <input type="submit" name="RENAME-SUBMIT" value="Rename">&nbsp;
+      <input type="submit" name="RENAME-CANCEL-SUBMIT" value="Cancel"
+             tal:condition="tool/rename">&nbsp;
+    </div>
+    <br/>
+  </form>
+
+</div>
+</body>
+</html>

Deleted: Zope3/branches/srichter-blow-services/src/zope/app/component/browser/tool.pt
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/component/browser/tool.pt	2005-01-12 16:12:39 UTC (rev 28806)
+++ Zope3/branches/srichter-blow-services/src/zope/app/component/browser/tool.pt	2005-01-12 16:19:27 UTC (rev 28807)
@@ -1,123 +0,0 @@
-<html metal:use-macro="context/@@standard_macros/page">
-<body>
-<div metal:fill-slot="body">
-
-  <h2 tal:content="view/title" i18n:translate="">
-    IInterface Tools
-  </h2>
-
-  <p tal:content="view/description" i18n:translate="">
-    Some description here.
-  </p>
-
-  <div tal:define="message view/update;
-                   registries view/getComponents;
-                   rename_list view/renameList">
-
-
-    <div class="message" tal:condition="message">
-       <span tal:replace="message">view/update message here</span>
-       <br /><br />
-       <i><a href="" i18n:translate="">(click to clear message)</a></i>
-    </div>
-
-    <p tal:condition="not:registries" i18n:translate="">
-      No tools are registered.
-    </p>
-
-    <div>
-      <p i18n:translate="">
-         Unless a tool is disabled the tool name links to the
-         active tool. ...
-      </p>
-
-      <form method="POST">
-
-        <table width="100%" tal:condition="registries">
-          <tr>
-            <th width="5%"> </th>
-            <th i18n:translate="" width="35%">Name</th>
-            <th i18n:translate="" width="20%">Registration</th>
-            <th i18n:translate="" width="40%">Parent</th>
-          </tr>
-          <tr tal:repeat="reg registries">
-            <td>
-              <input type="checkbox"
-                  name="selected:list" tal:attributes="value reg/name" />
-            </td>
-            <td>
-             <a href=""
-                tal:attributes="
-                    href string:${reg/url}/@@SelectedManagementView.html"
-                tal:content="reg/name"
-                tal:condition="python: not reg['name'] in rename_list">
-               Foobar (the tool)
-             </a>
-             <input type="hidden" name="old_names:list" value=""
-                tal:attributes="value reg/name"
-                tal:condition="python:reg['name'] in rename_list" />
-             <input type="text" name ="new_names:list" value=""
-                tal:attributes="value reg/name"
-                tal:condition="python:reg['name'] in rename_list" />
-
-            </td>
-            <td>
-             <tal:block>
-              <a href="" 
-                 tal:attributes="href string:${reg/url}/@@registration.html"
-                 tal:condition="reg/active" i18n:translate="">
-                active
-              </a>
-              <a href="" 
-                 tal:attributes="href string:${reg/url}/@@registration.html"
-                 tal:condition="not: reg/active" i18n:translate="">
-                disabled
-              </a>
-             </tal:block>
-            </td>
-            <td>
-             <a href=""
-                tal:condition="reg/parent_url"
-                tal:attributes= "href reg/parent_url"
-                tal:content="reg/parent_name">
-               Foobar (the tool)
-             </a>
-            </td>
-          </tr>
-        </table>
-
-        <div tal:condition="not: rename_list">
-          <input type="submit" name="ACTIVATE" value="Activate" 
-                 i18n:attributes="value activate-button"/>
-          <input type="submit" name="DEACTIVATE" value="Deactivate"
-                 i18n:attributes="value deactivate-button"/>
-          &nbsp;
-          <input type="submit" name="ADD" value="Add"
-                 i18n:attributes="value add-button"/>
-          &nbsp;
-          <input type="submit" name="DELETE" value="Delete"
-                 i18n:attributes="value delete-button"/>
-          &nbsp;
-          <input type="submit" name="RENAME" value="Rename"
-                 i18n:attributes="value rename-button"
-                 tal:condition="view/can_rename" />
-          &nbsp;
-          <input type="submit" name="REFRESH" value="Refresh"
-                 i18n:attributes="value refresh-button"/>
-        </div>
-        <div tal:condition="rename_list">
-          <input type="submit" name="APPLY_RENAME" value="Apply"
-                 i18n:attributes="value apply-button"/>
-          &nbsp;
-          <input type="submit" name="CANCEL_RENAME" value="Cancel"
-                 i18n:attributes="value cancel-button"/>
-        </div>
-
-      </form>
-
-    </div>
-  </div>
-
-</div>
-</body>
-</html>

Deleted: Zope3/branches/srichter-blow-services/src/zope/app/component/browser/tools.pt
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/component/browser/tools.pt	2005-01-12 16:12:39 UTC (rev 28806)
+++ Zope3/branches/srichter-blow-services/src/zope/app/component/browser/tools.pt	2005-01-12 16:19:27 UTC (rev 28807)
@@ -1,26 +0,0 @@
-<html metal:use-macro="context/@@standard_macros/view">
-<body>
-<div metal:fill-slot="body">
-
-  <h2 i18n:translate="">
-    Available Tools
-  </h2>
-  <br/>
-
-  <tal:block repeat="tool view/getTools">
-    <h4>
-      <a href="" 
-          tal:attributes="href tool/action"
-          tal:content="tool/title"
-          i18n:translate="">
-        Menu Title
-      </a>
-     </h4>
-     <p tal:content="tool/description">
-       Tool Description
-     </p>
-  </tal:block>
-
-</div>
-</body>
-</html>

Modified: Zope3/branches/srichter-blow-services/src/zope/app/component/browser/tools.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/component/browser/tools.py	2005-01-12 16:12:39 UTC (rev 28806)
+++ Zope3/branches/srichter-blow-services/src/zope/app/component/browser/tools.py	2005-01-12 16:19:27 UTC (rev 28807)
@@ -15,231 +15,227 @@
 
 $Id$
 """
-from zope.interface import implements, Attribute
-from zope.interface.interfaces import IInterface
-from zope.app.pagetemplate.simpleviewclass import simple as SimpleView
-from zope.app.publisher.interfaces.browser import IBrowserView
+import zope.interface
+import zope.event
+from zope.component.interfaces import IFactory
+
 from zope.app import zapi
-from zope.app.copypastemove import rename
-from zope.app.pagetemplate.viewpagetemplatefile import ViewPageTemplateFile
-#from zope.app.component.browser import AddRegistration
-from zope.app.component.browser import ComponentAdding
-from zope.app.component.site import UtilityRegistration
-from zope.app.component.site import SiteManagementFolder
-from zope.app.component.interfaces.registration import ActiveStatus
-from zope.app.component.interfaces.registration import InactiveStatus
+from zope.app.component import site, interfaces
+from zope.app.container.browser import adding
+from zope.app.event import objectevent
 
-from zope.app.i18n import ZopeMessageIDFactory as _
-
-
-class IToolType(IInterface):
+class IToolType(zope.interface.interfaces.IInterface):
     """Interfaces implementing the tool type are considered tools."""
 
-class IToolView(IBrowserView):
 
-    title = Attribute("Title for the view.")
-    description = Attribute("Description for the view.")
+class IToolConfiguration(zope.interface.Interface):
+    """This is an object that represents a tool configuration"""
 
-    def update(self):
-        """Update the data."""
+    #title
+    #
+    #description
+    #
+    #interface
+    #
+    #unique
 
-    def getComponents(self):
-        """Return a list of components."""
 
+class ToolConfiguration(object):
+    """ """
+    zope.interface.implements(IToolConfiguration)
 
-class IUtilityToolView(IToolView):
+    def __init__(self, interface, title, description=None, unique=False,
+                 folder='tools'):
+        self.interface = interface
+        self.title = title
+        self.description = description
+        self.unique = unique
+        self.folder = folder
 
-    interface = Attribute("Interface the utility provides.")
 
+class SiteManagementView(adding.Adding):
+    """A Site Management via Tools"""
 
-class ToolsOverview(object):
-    def getTools(self):
-        tools = []
-        for n, iface in zapi.getUtilitiesFor(IToolType):
-            name = iface.getName()
-            view = zapi.getView(self.context, 'manage%sTool.html' % name,
-                                self.request)
-            tools.append({'title':view.title,
-                          'description':view.description,
-                          'action':'./@@manage%sTool.html' % name })
-        tools.sort(lambda x, y: cmp(x['title'], y['title']))
-        return tools
+    activeTool = None
+    addTool = False
+    renameList = []
 
-class ToolsBacklink(object):
-    def getLink(self):
-        sm = zapi.getSiteManager()
-        iface = zapi.queryType(self.context, IToolType)
-        url = '%s/manage%sTool.html' %(zapi.getPath(sm), iface.getName())
+    def __init__(self, context, request):
+        super(SiteManagementView, self).__init__(context, request)
+        if 'activeTool' in request:
+            self.activeTool = zapi.getUtility(IToolConfiguration,
+                                              request['activeTool'])
 
-        return self.request.response.redirect(url)
-
-class AbstractToolView(SimpleView):
-    """Abstract tools view."""
-
-    index = ViewPageTemplateFile('tool.pt')
-
-    title = None
-    description = None
-
-    can_rename = False
-
     def update(self):
-        status = ''
-        self.renameList = []
-
-        has_key = self.request.form.has_key
-        selected = self.request.form.get('selected', [])
-        doAdd = has_key('ADD')
-        doDelete = has_key('DELETE')
-        doRename = has_key('RENAME')
-        applyRename = has_key('APPLY_RENAME')
-        doActivate = has_key('ACTIVATE')
-        doDeactivate = has_key('DEACTIVATE')
-
-        if doAdd:
-            self.add()
-        elif not selected:
-            if (doDelete or doRename or applyRename
-                or doActivate or doDeactivate):
-                status = _('Please select at least one checkbox')
-        elif doDelete:
+        """ """
+        msg = u''
+        if "INSTALL-SUBMIT" in self.request:
+            self.install()
+            msg = u'Tools successufully installed.'
+        if "UNINSTALL-SUBMIT" in self.request:
+            self.uninstall()
+            msg = u'Tools successufully uninstalled.'
+        if "ADD-TOOL-SUBMIT" in self.request:
+            self.action(self.request['type_name'], self.request['id'])
+        elif "CANCEL-ADD-TOOL-SUBMIT" in self.request:
+            self.activeTool = None
+        elif "ACTIVATE-SUBMIT" in self.request:
+            self.changeStatus(interfaces.registration.ActiveStatus)
+            msg = u'Tools successfully activated.'
+        elif "DEACTIVATE-SUBMIT" in self.request:
+            self.changeStatus(interfaces.registration.InactiveStatus)
+            msg = u'Tools successfully deactivated.'
+        elif "ADD-SUBMIT" in self.request:
+            self.addTool = True
+        elif "DELETE-SUBMIT" in self.request:
             self.delete()
-            status = _('Deleted selected tools.')
-        elif doRename:
-            self.renameList = selected
-        elif applyRename:
-            self.rename()
-            status = _('Renamed selected tools.')
-        elif doActivate:
-            self.activate()
-            status = _('Activated registrations.')
-        elif doDeactivate:
-            self.deactivate()
-            status = _('Deactivated registrations.')
+        elif "RENAME-SUBMIT" in self.request:
+            if 'selected' in self.request:
+                self.renameList = self.request['selected']
+            if 'new_names' in self.request:
+                self.rename()
+                msg = u'Tools successullfy renamed.'
+        elif "RENAME-CANCEL-SUBMIT" in self.request:
+            self.activeTool = None
+        return msg
 
-        return status
+    def getSiteManagementFolder(self, tool):
+        """Get the site management folder for this tool."""
+        sm = zapi.getSiteManager()
+        if not tool.folder in sm:
+            folder = site.SiteManagementFolder()
+            zope.event.notify(objectevent.ObjectCreatedEvent(folder))
+            sm[tool.folder] = folder            
+        return sm[tool.folder]
 
+    def toolExists(self, interface, name=''):
+        """Check whether a tool already exists in this site"""
+        sm = zapi.getSiteManager()
+        for reg in sm.registrations():
+            if isinstance(reg, site.UtilityRegistration):
+                if reg.name == name and reg.provided == interface:
+                    return True
+        return False
 
-class UtilityToolView(AbstractToolView):
-    """Tools view for utilities."""
+    def getUniqueTools(self):
+        """Get unique tools info for display."""
+        results = [{'name': tool.interface.getName(),
+                    'title': tool.title,
+                    'description': tool.description,
+                    'exists': self.toolExists(tool.interface)
+                    }
+                   for name, tool in zapi.getUtilitiesFor(IToolConfiguration)
+                   if tool.unique]
+        results.sort(lambda x, y: cmp(x['title'], y['title']))
+        return results
 
-    implements(IUtilityToolView)
+    def getToolInstances(self, tool):
+        """Find every registered utility for a given tool configuration."""
+        regManager = self.context[tool.folder].registrationManager
+        return [
+            {'name': reg.name,
+             'url': zapi.absoluteURL(reg.component, self.request),
+             'rename': tool is self.activeTool and reg.name in self.renameList,
+             'active': reg.status == u'Active'
+            }
+            for reg in regManager.values()
+            if (zapi.isinstance(reg, site.UtilityRegistration) and
+                reg.provided.isOrExtends(tool.interface))]
 
-    can_rename = True
+    def getTools(self):
+        """Return a list of all tools"""
+        results = [{'name': tool.interface.getName(),
+                    'title': tool.title,
+                    'description': tool.description,
+                    'instances': self.getToolInstances(tool),
+                    'add': tool is self.activeTool and self.addTool,
+                    'rename': tool is self.activeTool and self.renameList
+                    }
+                   for name, tool in zapi.getUtilitiesFor(IToolConfiguration)
+                   if not tool.unique]
+        results.sort(lambda x, y: cmp(x['title'], y['title']))
+        return results
 
-    def delete(self):
-        for name in self.request.form['selected']:
-            utils = zapi.getService(Utilities)
-            reg = utils.queryRegistrations(name, self.interface)
+    def install(self):
+        tool_names = self.request['selected']
+        for tool_name in tool_names:
+            self.activeTool = zapi.getUtility(IToolConfiguration, tool_name)
+            type_name = list(self.addingInfo())[0]['extra']['factory']
+            self.action(type_name)
+        self.activeTool = None
 
-            del_objs = []
+    def uninstall(self):
+        type_names = self.request['selected']
+        self.request.form['selected'] = [u'']
+        for name, tool in zapi.getUtilitiesFor(IToolConfiguration):
+            if name in type_names:
+                self.activeTool = tool
+                self.delete()
+        self.activeTool = None
 
-            # Delete registrations
-            for info in reg.info():
-                conf = info['registration']
-                obj = conf.component
-                conf.status = UnregisteredStatus
-                reg_folder = zapi.getParent(conf)
-                name = zapi.name(conf)
-                del reg_folder[name]
-                if obj not in [c.component
-                               for c in reg_folder.values()]:
-                    del_objs.append(obj)
+    def changeStatus(self, status):
+        tool = self.activeTool
+        regManager = self.context[tool.folder].registrationManager
+        names = self.request.form['selected']
+        print names
+        for reg in regManager.values():
+            if reg.provided.isOrExtends(tool.interface) and reg.name in names:
+                print reg.name
+                reg.status = status
 
-            # Delete object, if no other registration is available.
-            for obj in del_objs:
-                parent = zapi.getParent(obj)
-                name = zapi.name(obj)
-                del parent[name]
+    def delete(self):
+        tool = self.activeTool
+        regManager = self.context[tool.folder].registrationManager
+        names = self.request.form['selected']
+        for reg in regManager.values():
+            if reg.provided.isOrExtends(tool.interface) and reg.name in names:
+                component = reg.component
+                reg.status = interfaces.registration.InactiveStatus
+                del regManager[zapi.name(reg)]
+                del zapi.getParent(component)[zapi.name(component)]
 
     def rename(self):
-        for name in self.request.form['old_names']:
-            newname = self.request.form['new_names'][
-                self.request.form['old_names'].index(name)]
+        tool = self.activeTool
+        regManager = self.context[tool.folder].registrationManager
+        new_names = self.request['new_names']
+        old_names = self.request['old_names']
+        for reg in regManager.values():
+            if reg.provided.isOrExtends(tool.interface) and \
+                   reg.name in old_names:
+                orig_status = reg.status
+                reg.status = interfaces.registration.InactiveStatus
+                reg.name = new_names[old_names.index(reg.name)]
+                reg.status = orig_status
 
-            utils = zapi.getService('Utilities')
-            reg = utils.queryRegistrations(name, self.interface)
-
-            # Rename registrations
-            for info in reg.info():
-                conf = info['registration']
-                orig_status = conf.status
-                conf.status = UnregisteredStatus
-                conf.name = newname
-                conf.status = orig_status
-
-    def activate(self):
-        for name in self.request.form['selected']:
-            utils = zapi.getService('Utilities')
-            reg = utils.queryRegistrations(name, self.interface)
-
-            # Activate registrations
-            for info in reg.info():
-                conf = info['registration']
-                conf.status = ActiveStatus
-
-    def deactivate(self):
-        for name in self.request.form['selected']:
-            utils = zapi.getService('Utilities')
-            reg = utils.queryRegistrations(name, self.interface)
-
-            # Deactivate registrations
-            for info in reg.info():
-                conf = info['registration']
-                conf.status = RegisteredStatus
-
-    def add(self):
-        self.request.response.redirect('./Add%sTool' %
-                                       self.interface.getName())
-
-    def getComponents(self):
-        utils = zapi.getService(Utilities)
-        items = []
-        for registration in [reg for reg in utils.registrations(localOnly=True)
-                             if reg.provided == self.interface]:
-
-            stack = utils.queryRegistrationsFor(registration)
-            parent = zapi.getParent(registration.component)
-            items.append({
-                'name': registration.name,
-                'url': zapi.getPath(registration.component),
-                'parent_url': zapi.getPath(parent),
-                'parent_name': zapi.name(parent),
-                'active': stack.active()})
-
-        return items
-
-
-class UtilityToolAdding(ComponentAdding):
-    """Adding subclass used for adding utilities."""
-
-    menu_id = None
-    title = "Add Tool"
-    folder = "tools"
-    _addFilterInterface = None
-
-
-    def addingInfo(self):
-        if self.folder not in self.context:
-            self.context[self.folder] = SiteManagementFolder()
-        self.context = self.context[self.folder]
-        return super(UtilityToolAdding, self).addingInfo()
-
     def add(self, content):
-        if not self._addFilterInterface.providedBy(content):
-            raise TypeError("%s is not a %s" %(
-                content, self._addFilterInterface.getName()))
-        self.context = self.context[self.folder]
-        util = super(UtilityToolAdding, self).add(content)
+        """See zope.app.container.interfaces.IAdding"""
+        sm = self.context
+        self.context = self.getSiteManagementFolder(self.activeTool)
 
+        util = super(SiteManagementView, self).add(content)
+
         # Add registration
-        registration = UtilityRegistration(self.contentName,
-                                           self._addFilterInterface,
-                                           util)
-        reg_view = AddRegistration(util, self.request)
-        reg_view.add(registration)
+        name = not self.activeTool.unique and self.contentName or u''
+        registration = site.UtilityRegistration(
+            name, self.activeTool.interface, util)
+        self.context.registrationManager.addRegistration(registration)
+        registration.status = interfaces.registration.ActiveStatus
 
+        self.context = sm
         return util
-
+        
     def nextURL(self):
-        return '../@@manage%sTool.html' %self._addFilterInterface.getName()
+        """See zope.app.container.interfaces.IAdding"""
+        return (zapi.absoluteURL(self.context, self.request)
+                + '/@@SiteManagement')
+
+    def addingInfo(self):
+        """See zope.app.container.interfaces.IAdding"""
+        sm = self.context
+        self.context = self.getSiteManagementFolder(self.activeTool)
+        results = super(SiteManagementView, self).addingInfo()
+        self.context = sm
+        for result in results:
+            factory = zapi.getUtility(IFactory, result['extra']['factory'])
+            if self.activeTool.interface in factory.getInterfaces():
+                yield result

Added: Zope3/branches/srichter-blow-services/src/zope/app/component/browser/utilreg_details.pt
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/component/browser/utilreg_details.pt	2005-01-12 16:12:39 UTC (rev 28806)
+++ Zope3/branches/srichter-blow-services/src/zope/app/component/browser/utilreg_details.pt	2005-01-12 16:19:27 UTC (rev 28807)
@@ -0,0 +1,17 @@
+<ul style="margin-top: 0; margin-bottom: 0">
+  <li>
+    <i i18n:translate="">provided:</i>
+    <span tal:content="view/provided">zope.app.interfaces.IMyUtility</span>
+  </li>
+  <li>
+    <i i18n:translate="">name:</i>
+    <span tal:content="view/name">myutility</span>
+  </li>
+  <li tal:define="component view/component">
+    <i i18n:translate="">component:</i>
+    <a href="" 
+       tal:attributes="href 
+         string:${component/url}/@@SelectedManagementView.html"
+       tal:content="component/name">myutility</a>
+  </li>
+</ul>
\ No newline at end of file

Deleted: Zope3/branches/srichter-blow-services/src/zope/app/component/browser/xxx_tests/test_toolbacklink.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/component/browser/xxx_tests/test_toolbacklink.py	2005-01-12 16:12:39 UTC (rev 28806)
+++ Zope3/branches/srichter-blow-services/src/zope/app/component/browser/xxx_tests/test_toolbacklink.py	2005-01-12 16:19:27 UTC (rev 28807)
@@ -1,70 +0,0 @@
-# -*- coding: latin-1 -*-
-##############################################################################
-#
-# 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.1 (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.
-#
-##############################################################################
-"""Tool backlink generation tests
-
-$Id$
-"""
-
-import unittest
-
-from zope.interface import implements, Interface
-from zope.app.utility.interfaces import ILocalUtility
-from zope.publisher.browser import TestRequest
-from zope.app.component.interface import provideInterface
-from zope.app.tests.placelesssetup import PlacelessSetup
-from zope.app.site.browser.tools import IToolType, ToolsBacklink
-from zope.component.interfaces import IServiceService
-from zope.app.traversing.interfaces import IPhysicallyLocatable
-from zope.app.tests import ztapi
-
-class IDummyUtility(Interface):
-    pass
-
-class DummyUtility(object):
-    implements(IDummyUtility, ILocalUtility)
-
-class Locatable(object):
-    def __init__(self, context):
-        pass
-    
-    def getPath(self):
-        return '/++etc++site'
-    
-class TestBackLink(PlacelessSetup, unittest.TestCase):
-    def setUp(self):
-        super(TestBackLink, self).setUp()
-        provideInterface(None, IDummyUtility, IToolType)
-        ztapi.provideAdapter(IServiceService, IPhysicallyLocatable, Locatable)
-        
-    def testLink(self):
-        view = ToolsBacklink()
-        view.request = TestRequest()
-        view.context = DummyUtility()
-
-        location = view.getLink()
-
-        # inspect the response
-        self.assertEqual(location, '/++etc++site/manageIDummyUtilityTool.html')
-
-
-def test_suite():
-    suite = unittest.TestSuite()
-    suite.addTest(unittest.makeSuite(TestBackLink))
-    return suite
-
-
-if __name__ == '__main__':
-    unittest.main()
-

Modified: Zope3/branches/srichter-blow-services/src/zope/app/component/configure.zcml
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/component/configure.zcml	2005-01-12 16:12:39 UTC (rev 28806)
+++ Zope3/branches/srichter-blow-services/src/zope/app/component/configure.zcml	2005-01-12 16:19:27 UTC (rev 28807)
@@ -22,6 +22,20 @@
         />
   </content>
 
+  <!-- ++registrations++ namespace registrations -->
+  <view
+      name="registrations" type="*"
+      for=".interfaces.registration.IRegisterableContainer"
+      provides="zope.app.traversing.interfaces.ITraversable"
+      factory=".registration.RegistrationManagerNamespace"
+      />
+  <adapter
+      name="registrations"
+      for=".interfaces.registration.IRegisterableContainer"
+      provides="zope.app.traversing.interfaces.ITraversable"
+      factory=".registration.RegistrationManagerNamespace"
+      />
+
   <class class=".registration.Registered">
     <allow attributes="registrations" />
   </class>

Modified: Zope3/branches/srichter-blow-services/src/zope/app/component/interfaces/__init__.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/component/interfaces/__init__.py	2005-01-12 16:12:39 UTC (rev 28806)
+++ Zope3/branches/srichter-blow-services/src/zope/app/component/interfaces/__init__.py	2005-01-12 16:19:27 UTC (rev 28807)
@@ -136,8 +136,9 @@
 
     name = zope.schema.TextLine(
         title=_(u"Name"),
-        readonly=True,
-        required=False,
+        readonly=False,
+        required=True,
+        default=u''
         )
 
     permission = zope.schema.Choice(
@@ -167,8 +168,9 @@
     name = zope.schema.TextLine(
         title=_("Register As"),
         description=_("The name under which the utility will be known."),
-        readonly=True,
+        readonly=False,
         required=True,
+        default=u''
         )
 
     provided = zope.schema.Choice(

Modified: Zope3/branches/srichter-blow-services/src/zope/app/component/interfaces/registration.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/component/interfaces/registration.py	2005-01-12 16:12:39 UTC (rev 28806)
+++ Zope3/branches/srichter-blow-services/src/zope/app/component/interfaces/registration.py	2005-01-12 16:19:27 UTC (rev 28807)
@@ -178,6 +178,7 @@
 
 class IRegistrationManager(IContainerNamesContainer):
     """Manage Registrations"""
+    contains(IRegistration)
 
     def addRegistration(registration):
         """Add a registration to the manager.
@@ -188,6 +189,12 @@
         """
 
 
+class IRegistrationManagerContained(IContained):
+    """Objects that can be contained by the registration manager should
+    implement this interface."""
+    containers(IRegistrationManager)
+
+
 class IRegisterableContainer(IContainer):
     """Containers with registration managers
 

Modified: Zope3/branches/srichter-blow-services/src/zope/app/component/registration.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/component/registration.py	2005-01-12 16:12:39 UTC (rev 28806)
+++ Zope3/branches/srichter-blow-services/src/zope/app/component/registration.py	2005-01-12 16:19:27 UTC (rev 28807)
@@ -23,14 +23,14 @@
 from zope.security.proxy import Proxy, removeSecurityProxy
 
 from zope.app import zapi
+from zope.app.component.interfaces import registration as interfaces
 from zope.app.container.btree import BTreeContainer
 from zope.app.container.contained import Contained
 from zope.app.dependable.interfaces import IDependable, DependencyError
 from zope.app.event import objectevent
 from zope.app.location import inside
-from zope.app.component.interfaces import registration as interfaces
+from zope.app.traversing.interfaces import TraversalError
 
-
 class RegistrationEvent(objectevent.ObjectEvent):
     """An event that is created when a registration-related activity occured."""
     implements(interfaces.IRegistrationEvent)
@@ -78,7 +78,8 @@
 
 class SimpleRegistration(Persistent, Contained):
     """Registration objects that just contain registration data"""
-    implements(interfaces.IRegistration)
+    implements(interfaces.IRegistration,
+               interfaces.IRegistrationManagerContained)
 
     # See interfaces.IRegistration
     status = RegistrationStatusProperty()
@@ -226,6 +227,21 @@
         # See interfaces.IRegisterableContainer
         self.registrationManager = RegistrationManager()
         self.registrationManager.__parent__ = self
-        self.registrationManager.__name__ = 'RegistrationManager'
+        self.registrationManager.__name__ = '++registrations++'
         zope.event.notify(
             objectevent.ObjectCreatedEvent(self.registrationManager))
+
+# XXX: Needs tests
+class RegistrationManagerNamespace(object):
+    """Used to traverse to a Registration Manager from a
+       Registerable Container."""
+    __used_for__ = interfaces.IRegisterableContainer
+
+    def __init__(self, ob, request=None):
+        self.context = ob.registrationManager
+        
+    def traverse(self, name, ignore):
+        if name == '':
+            return self.context
+        raise TraversalError(self.context, name)
+        

Modified: Zope3/branches/srichter-blow-services/src/zope/app/container/browser/adding.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/container/browser/adding.py	2005-01-12 16:12:39 UTC (rev 28806)
+++ Zope3/branches/srichter-blow-services/src/zope/app/container/browser/adding.py	2005-01-12 16:19:27 UTC (rev 28807)
@@ -129,8 +129,7 @@
         if zapi.queryMultiAdapter((self, self.request),
                                   name=view_name) is not None:
             url = "%s/%s=%s" % (
-                zapi.getMultiAdapter((self, self.request), name="absolute_url"),
-                type_name, id)
+                zapi.absoluteURL(self, self.request), type_name, id)
             self.request.response.redirect(url)
             return
 

Modified: Zope3/branches/srichter-blow-services/src/zope/app/error/browser/configure.zcml
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/error/browser/configure.zcml	2005-01-12 16:12:39 UTC (rev 28806)
+++ Zope3/branches/srichter-blow-services/src/zope/app/error/browser/configure.zcml	2005-01-12 16:19:27 UTC (rev 28807)
@@ -38,6 +38,13 @@
      description="Error Reporting Utility for Logging Errors"
      permission="zope.ManageServices" />
 
+  <tool
+      interface="..interfaces.IErrorReportingUtility"
+      title="Error Reporting"
+      description="Component to record all uncaught errors and exceptions."
+      unique="true"
+      />
+
   <icon name="zmi_icon"
       for="zope.app.error.interfaces.IErrorReportingUtility"
       file="error.gif" />

Modified: Zope3/branches/srichter-blow-services/src/zope/app/form/browser/add.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/form/browser/add.py	2005-01-12 16:12:39 UTC (rev 28806)
+++ Zope3/branches/srichter-blow-services/src/zope/app/form/browser/add.py	2005-01-12 16:19:27 UTC (rev 28807)
@@ -141,10 +141,9 @@
                    keyword_arguments, set_before_add, set_after_add,
                    menu=u''):
 
+    # XXX: Needs to be tested
     class_  = SimpleViewClass(
-        template,
-        used_for = schema, bases = bases
-        )
+        template, used_for=schema, bases=bases, name=name)
 
     class_.schema = schema
     class_.label = label

Modified: Zope3/branches/srichter-blow-services/src/zope/app/form/browser/addwizard.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/form/browser/addwizard.py	2005-01-12 16:12:39 UTC (rev 28806)
+++ Zope3/branches/srichter-blow-services/src/zope/app/form/browser/addwizard.py	2005-01-12 16:19:27 UTC (rev 28807)
@@ -108,13 +108,15 @@
         self.request.response.redirect(self.context.nextURL())
         return False
 
-
+# XXX: Needs unittest
 def AddWizardViewFactory(
     name, schema, permission, layer, panes, fields,
     template, default_template, bases, for_, content_factory, arguments,
     keyword_arguments, set_before_add, set_after_add, use_session=True):
 
-    class_  = SimpleViewClass(template, used_for = schema, bases = bases)
+    # XXX: name=name Needs to be tested
+    class_  = SimpleViewClass(template, used_for=schema, bases=bases,
+                              name=name)
 
     class_.schema = schema
     class_.panes = panes
@@ -137,5 +139,5 @@
     if layer is None:
         layer = IDefaultBrowserLayer
 
-    s = zapi.getGlobalService(zapi.servicenames.Adapter)
-    s.register((for_, layer), Interface, name, class_)
+    sm = zapi.getGlobalSiteManager()
+    sm.provideAdapter((for_, layer), Interface, name, class_)

Modified: Zope3/branches/srichter-blow-services/src/zope/app/form/browser/editview.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/form/browser/editview.py	2005-01-12 16:12:39 UTC (rev 28806)
+++ Zope3/branches/srichter-blow-services/src/zope/app/form/browser/editview.py	2005-01-12 16:19:27 UTC (rev 28807)
@@ -129,7 +129,8 @@
 def EditViewFactory(name, schema, label, permission, layer,
                     template, default_template, bases, for_, fields,
                     fulledit_path=None, fulledit_label=None, menu=u''):
-    class_ = SimpleViewClass(template, used_for=schema, bases=bases)
+    # XXX: Need to test name=name
+    class_ = SimpleViewClass(template, used_for=schema, bases=bases, name=name)
     class_.schema = schema
     class_.label = label
     class_.fieldNames = fields

Modified: Zope3/branches/srichter-blow-services/src/zope/app/form/browser/editwizard.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/form/browser/editwizard.py	2005-01-12 16:12:39 UTC (rev 28806)
+++ Zope3/branches/srichter-blow-services/src/zope/app/form/browser/editwizard.py	2005-01-12 16:19:27 UTC (rev 28807)
@@ -224,6 +224,8 @@
     class_.use_session = use_session
 
     class_.generated_form = ViewPageTemplateFile(default_template)
+    # XXX: needs to be tested
+    class_.__name__ = name
 
     defineChecker(
         class_,

Modified: Zope3/branches/srichter-blow-services/src/zope/app/form/browser/schemadisplay.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/form/browser/schemadisplay.py	2005-01-12 16:12:39 UTC (rev 28806)
+++ Zope3/branches/srichter-blow-services/src/zope/app/form/browser/schemadisplay.py	2005-01-12 16:19:27 UTC (rev 28807)
@@ -73,7 +73,9 @@
                        fulledit_path=None, fulledit_label=None, menu=u'',
                        usage=u''):
     # XXX What about the __implements__ of the bases?
-    class_ = SimpleViewClass(template, used_for=schema, bases=bases)
+    # XXX: Needs to test name=name
+    class_ = SimpleViewClass(template, used_for=schema, bases=bases,
+                             name=name)
     class_.schema = schema
     class_.label = label
     class_.fieldNames = fields
@@ -82,6 +84,7 @@
         fulledit_label = "Full display"
     class_.fulledit_label = fulledit_label
     class_.generated_form = ViewPageTemplateFile(default_template)
+    # XXX: Cannot work!
     class_.usage = usage or (
         menu and globalBrowserMenuService.getMenuUsage(menu)
         )

Modified: Zope3/branches/srichter-blow-services/src/zope/app/module/manager.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/module/manager.py	2005-01-12 16:12:39 UTC (rev 28806)
+++ Zope3/branches/srichter-blow-services/src/zope/app/module/manager.py	2005-01-12 16:19:27 UTC (rev 28807)
@@ -23,8 +23,8 @@
 from zope.app.container.contained import Contained
 from zope.app.filerepresentation.interfaces import IFileFactory
 from zope.app.module.interfaces import IModuleManager
+from zope.app.module import ZopeModuleRegistry
 
-
 class ModuleManager(persistent.Persistent, Contained):
 
     zope.interface.implements(IModuleManager)

Modified: Zope3/branches/srichter-blow-services/src/zope/app/pagetemplate/simpleviewclass.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/pagetemplate/simpleviewclass.py	2005-01-12 16:12:39 UTC (rev 28806)
+++ Zope3/branches/srichter-blow-services/src/zope/app/pagetemplate/simpleviewclass.py	2005-01-12 16:19:27 UTC (rev 28807)
@@ -44,14 +44,16 @@
     def __call__(self, *args, **kw):
         return self.index(*args, **kw)
 
-def SimpleViewClass(src, offering=None, used_for=None, bases=()):
+# XXX: Test new name argument
+def SimpleViewClass(src, offering=None, used_for=None, bases=(), name=u''):
     if offering is None:
         offering = sys._getframe(1).f_globals
 
     bases += (simple, )
 
     class_ = type("SimpleViewClass from %s" % src, bases,
-                  {'index': ViewPageTemplateFile(src, offering)})
+                  {'index': ViewPageTemplateFile(src, offering),
+                   '__name__': name})
 
     if used_for is not None:
         class_.__used_for__ = used_for

Modified: Zope3/branches/srichter-blow-services/src/zope/app/principalannotation/configure.zcml
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/principalannotation/configure.zcml	2005-01-12 16:12:39 UTC (rev 28806)
+++ Zope3/branches/srichter-blow-services/src/zope/app/principalannotation/configure.zcml	2005-01-12 16:19:27 UTC (rev 28807)
@@ -21,6 +21,13 @@
      title="Principal Annotation Utility"
      description="Stores Annotations for Principals" />
 
+  <browser:tool
+      interface=".interfaces.IPrincipalAnnotationUtility"
+      title="Principal Annotations"
+      description="Stores annotations for any principal."
+      unique="true"
+      />
+
   <subscriber
       for="zope.app.appsetup.IDatabaseOpenedEvent"
       factory=".bootstrap.bootStrapSubscriber"

Modified: Zope3/branches/srichter-blow-services/src/zope/app/publisher/browser/viewmeta.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/publisher/browser/viewmeta.py	2005-01-12 16:12:39 UTC (rev 28806)
+++ Zope3/branches/srichter-blow-services/src/zope/app/publisher/browser/viewmeta.py	2005-01-12 16:19:27 UTC (rev 28807)
@@ -117,6 +117,7 @@
             raise ConfigurationError("No such file", template)
         required['__getitem__'] = permission
 
+    # XXX: new __name__ attribute must be tested
     if class_:
         if attribute != '__call__':
             if not hasattr(class_, attribute):
@@ -125,8 +126,7 @@
                     )
         if template:
             # class and template
-            new_class = SimpleViewClass(
-                template, bases=(class_, ))
+            new_class = SimpleViewClass(template, bases=(class_, ), name=name)
         else:
             if not hasattr(class_, 'browserDefault'):
                 cdict = {
@@ -136,17 +136,16 @@
             else:
                 cdict = {}
 
+            cdict['__name__'] = name
             cdict['__page_attribute__'] = attribute
-            new_class = type(class_.__name__,
-                             (class_, simple,),
-                             cdict)
+            new_class = type(class_.__name__, (class_, simple,), cdict)
 
         if hasattr(class_, '__implements__'):
             classImplements(new_class, IBrowserPublisher)
 
     else:
         # template
-        new_class = SimpleViewClass(template)
+        new_class = SimpleViewClass(template, name=name)
 
     for n in (attribute, 'browserDefault', '__call__', 'publishTraverse'):
         required[n] = permission
@@ -316,6 +315,7 @@
         except:
             cname = "GeneratedClass"
 
+        cdict['__name__'] = name
         newclass = type(cname, bases, cdict)
 
         for n in ('publishTraverse', 'browserDefault', '__call__'):

Modified: Zope3/branches/srichter-blow-services/src/zope/app/security/browser/configure.zcml
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/security/browser/configure.zcml	2005-01-12 16:12:39 UTC (rev 28806)
+++ Zope3/branches/srichter-blow-services/src/zope/app/security/browser/configure.zcml	2005-01-12 16:19:27 UTC (rev 28807)
@@ -2,6 +2,7 @@
    xmlns="http://namespaces.zope.org/zope"
    xmlns:browser="http://namespaces.zope.org/browser">
 
+
   <adapter
       for="zope.app.security.interfaces.IAuthenticationUtility
            zope.publisher.interfaces.browser.IBrowserRequest"
@@ -16,6 +17,13 @@
       factory="zope.app.security.browser.principalterms.PrincipalTerms" 
       />
 
+  <browser:tool
+      interface="..interfaces.IAuthenticationUtility"
+      title="Authentication"
+      description="Authenticates Principals."
+      unique="true"
+      />
+
   <browser:page
       name="login.html"
       for="*"

Modified: Zope3/branches/srichter-blow-services/src/zope/app/traversing/browser/absoluteurl.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/traversing/browser/absoluteurl.py	2005-01-12 16:12:39 UTC (rev 28806)
+++ Zope3/branches/srichter-blow-services/src/zope/app/traversing/browser/absoluteurl.py	2005-01-12 16:19:27 UTC (rev 28807)
@@ -32,7 +32,7 @@
 _safe = '@+' # Characters that we don't want to have quoted
 
 def absoluteURL(ob, request):
-    return str(capi.getMultiAdapter((ob, request), IAbsoluteURL))
+    return capi.getMultiAdapter((ob, request), IAbsoluteURL)()
 
 class AbsoluteURL(BrowserView):
     implements(IAbsoluteURL)

Modified: Zope3/branches/srichter-blow-services/src/zope/app/traversing/namespace.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/traversing/namespace.py	2005-01-12 16:12:39 UTC (rev 28806)
+++ Zope3/branches/srichter-blow-services/src/zope/app/traversing/namespace.py	2005-01-12 16:19:27 UTC (rev 28807)
@@ -314,7 +314,7 @@
 
     def traverse(self, name, ignored):
         # TODO:
-        # This is here now to allow us to get service managers from a
+        # This is here now to allow us to get site managers from a
         # separate namespace from the content. We add and etc
         # namespace to allow us to handle misc objects.  We'll apply
         # YAGNI for now and hard code this. We'll want something more
@@ -330,7 +330,7 @@
             and IContainmentRoot.providedBy(ob)):
             return applicationController
 
-        if name not in ('site', 'Services'):
+        if name not in ('site',):
             raise TraversalError(ob, name)
 
         method_name = "getSiteManager"



More information about the Zope3-Checkins mailing list