[Zope3-checkins] CVS: Zope3/src/zope/app/site/browser - __init__.py:1.1 add_svc_config.pt:1.1 configure.zcml:1.1 interfacebrowse.pt:1.1 interfacedetail.pt:1.1 interfacemethoddetail.pt:1.1 service.gif:1.1 service_manager.gif:1.1 service_manager.png:1.1 serviceactivation.pt:1.1 services.pt:1.1 tasks.pt:1.1

Stephan Richter srichter at cosmos.phy.tufts.edu
Sat Mar 13 10:22:00 EST 2004


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

Added Files:
	__init__.py add_svc_config.pt configure.zcml 
	interfacebrowse.pt interfacedetail.pt interfacemethoddetail.pt 
	service.gif service_manager.gif service_manager.png 
	serviceactivation.pt services.pt tasks.pt 
Log Message:


Move Local Service Manager and site code to zope.app.site.


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

$Id: __init__.py,v 1.1 2004/03/13 15:21:52 srichter Exp $
"""
from zope.proxy import removeAllProxies
from zope.app import zapi
from zope.app.browser.container.adding import Adding
from zope.app.i18n import ZopeMessageIDFactory as _
from zope.app.container.interfaces import INameChooser
from zope.app.interfaces.services.registration import UnregisteredStatus
from zope.app.interfaces.services.registration import RegisteredStatus
from zope.app.interfaces.services.registration import ActiveStatus
from zope.app.site.interfaces import ILocalService
from zope.app.utility.interfaces import ILocalUtility
from zope.app.site.service import ServiceRegistration
from zope.publisher.browser import BrowserView
from zope.app.site.interfaces import ISite, ISiteManager
from zope.app.site.service import SiteManager
from zope.app.component.nextservice import getNextServiceManager
from zope.component.service import IGlobalServiceManager
from zope.interface.interfaces import IMethod
from zope.schema.interfaces import IField
from zope.app.interface.interfaces import IInterfaceBasedRegistry
from zope.app.component.interface import searchInterface
from zope.app.component.interface import getInterface
from zope.app.component.interface import provideInterface

class ComponentAdding(Adding):
    """Adding subclass used for registerable components."""

    menu_id = "add_component"

    def add(self, content):
        # Override so as to save a reference to the added object
        self.added_object = super(ComponentAdding, self).add(content)
        return self.added_object

    def nextURL(self):
        v = zapi.queryView(
            self.added_object, "registration.html", self.request)
        if v is not None:
            url = str(
                zapi.getView(self.added_object, 'absolute_url', self.request))
            return url + "/@@registration.html"

        return super(ComponentAdding, self).nextURL()

    def action(self, type_name, id=''):
        # For special case of that we want to redirect to another adding view
        # (usually another menu such as AddService)
        if type_name.startswith("../"):
            # Special case
            url = type_name
            if id:
                url += "?id=" + id
            self.request.response.redirect(url)
            return

        # Call the superclass action() method.
        # As a side effect, self.added_object is set by add() above.
        super(ComponentAdding, self).action(type_name, id)

    _addFilterInterface = None
    def addingInfo(self):
        # A site management folder can have many things. We only want 
        # things that implement a particular interface
        info = super(ComponentAdding, self).addingInfo()
        if self._addFilterInterface is None:
            return info
        out = []
        for item in info:
            extra = item.get('extra')
            if extra:
                factoryname = extra.get('factory')
                if factoryname:
                    factory = zapi.getFactory(self.context, factoryname)
                    intf = factory.getInterfaces()
                    if not intf.extends(self._addFilterInterface):
                        # We only skip new addMenuItem style objects
                        # that don't implement our wanted interface.
                        continue

            out.append(item)

        return out


class ServiceAdding(ComponentAdding):
    """Adding subclass used for adding services."""

    menu_id = None
    title = _("Add Service")

    _addFilterInterface = ILocalService

    def add(self, content):
        # Override so as to check the type of the new object.
        # XXX This wants to be generalized!
        if not ILocalService.providedBy(content):
            raise TypeError("%s is not a local service" % content)

        content = super(ServiceAdding, self).add(content)

        # figure out the interfaces that this service implements
        sm = zapi.getServiceManager(self.context)
        implements = []
        for type_name, interface in sm.getServiceDefinitions():
            if interface.providedBy(content):
                implements.append(type_name)

        path = zapi.name(content)
        rm = content.__parent__.getRegistrationManager()
        chooser = INameChooser(rm)
        
        # register an activated service registration
        for type_name in implements:
            sc = ServiceRegistration(type_name, path, content)
            name = chooser.chooseName(type_name, sc)
            rm[name] = sc
            sc.status = ActiveStatus

        return content


class UtilityAdding(ComponentAdding):
    """Adding subclass used for adding utilities."""

    menu_id = None
    title = _("Add Utility")

    _addFilterInterface = ILocalUtility

    def add(self, content):
        # Override so as to check the type of the new object.
        # XXX This wants to be generalized!
        if not ILocalUtility.providedBy(content):
            raise TypeError("%s is not a local utility" % content)
        return super(UtilityAdding, self).add(content)

    def nextURL(self):
        v = zapi.queryView(
            self.added_object, "addRegistration.html", self.request)
        if v is not None:
            url = str(
                zapi.getView(self.added_object, 'absolute_url', self.request))
            return url + "/addRegistration.html"

        return super(UtilityAdding, self).nextURL()


class AddServiceRegistration(BrowserView):
    """A view on a service implementation, used by add_svc_config.pt."""

    def listServiceTypes(self):

        # Collect all defined services interfaces that it implements.
        sm = zapi.getServiceManager(self.context)
        lst = []
        for servicename, interface in sm.getServiceDefinitions():
            if interface.providedBy(self.context):
                registry = sm.queryRegistrations(servicename)
                checked = True
                if registry and registry.active():
                    checked = False
                d = {'name': servicename, 'checked': checked}
                lst.append(d)
        return lst

    def action(self, name=[], active=[]):
        path = zapi.name(self.context)
        rm = self.context.__parent__.getRegistrationManager()
        chooser = INameChooser(rm)

        for nm in name:
            sc = ServiceRegistration(nm, path, self.context)
            name = chooser.chooseName(nm, sc)
            rm[name] = sc
            if nm in active:
                sc.status = ActiveStatus
            else:
                sc.status = RegisteredStatus

        self.request.response.redirect("@@SelectedManagementView.html")


class ServiceSummary(BrowserView):
    """A view on the service manager, used by services.pt."""

    def update(self):
        """Possibly delete one or more services.

        In that case, issue a message.
        """
        todo = self.request.get("selected")
        doActivate = self.request.get("Activate")
        doDeactivate = self.request.get("Deactivate")
        doDelete = self.request.get("Delete")
        if not todo:
            if doDeactivate or doDelete:
                return "Please select at least one checkbox"
            return None
        if doActivate:
            return self._activate(todo)
        if doDeactivate:
            return self._deactivate(todo)
        if doDelete:
            return self._delete(todo)

    def _activate(self, todo):
        done = []
        for name in todo:
            registry = self.context.queryRegistrations(name)
            obj = registry.active()
            if obj is None:
                # Activate the first registered registration
                obj = registry.info()[0]['registration']
                obj.status = ActiveStatus
                done.append(name)
        if done:
            s = _("Activated: ${activated_services}")
            s.mapping = {'activated_services': ", ".join(done)}
            return s
        else:
            return _("All of the checked services were already active")

    def _deactivate(self, todo):
        done = []
        for name in todo:
            registry = self.context.queryRegistrations(name)
            obj = registry.active()
            if obj is not None:
                obj.status = RegisteredStatus
                done.append(name)
        if done:
            s = _("Deactivated: ${deactivated_services}")
            s.mapping = {'deactivated_services': ", ".join(done)}
            return s
        else:
            return _("None of the checked services were active")

    def _delete(self, todo):
        errors = []
        for name in todo:
            registry = self.context.queryRegistrations(name)
            assert registry
            if registry.active() is not None:
                errors.append(name)
                continue
        if errors:
            s = _("Can't delete active service(s): ${service_names}; "
                  "use the Deactivate button to deactivate")
            s.mapping = {'service_names': ", ".join(errors)}
            return s

        # 1) Delete the registrations
        services = {}
        for name in todo:
            registry = self.context.queryRegistrations(name)
            assert registry
            assert registry.active() is None # Phase error
            for info in registry.info():
                conf = info['registration']
                obj = conf.getComponent()
                path = zapi.getPath(obj)
                services[path] = obj
                conf.status = UnregisteredStatus
                parent = zapi.getParent(conf)
                name = zapi.name(conf)
                del parent[name]

        # 2) Delete the service objects
        # XXX Jim doesn't like this very much; he thinks it's too much
        #     magic behind the user's back.  OTOH, Guido believes that
        #     we're providing an abstraction here that hides the
        #     existence of the folder and its registration manager as
        #     much as possible, so it's appropriate to clean up when
        #     deleting a service; if you don't want that, you can
        #     manipulate the folder explicitly.
        for path, obj in services.items():
            parent = zapi.getParent(obj)
            name = zapi.name(obj)
            del parent[name]

        s = _("Deleted: ${service_names}")
        s.mapping = {'service_names': ", ".join(todo)}
        return s

    def listConfiguredServices(self):
        return gatherConfiguredServices(self.context, self.request)

def gatherConfiguredServices(sm, request, items=None):
    """Find all s/service/site managers up to the root and gather info
    about their services.
    """
    if items is None:
        items = {}
        # make sure no-one tries to use this starting at the global service
        # manager
        assert ISiteManager.providedBy(sm)
        manageable = True
    else:
        # don't want the "change registration" link for parent services
        manageable = False

    if IGlobalServiceManager.providedBy(sm):
        # global service manager
        names = []
        for type_name, interface in sm.getServiceDefinitions():
            if items.has_key(type_name):
                # a child has already supplied one of these
                continue
            if sm.queryService(type_name) is not None:
                names.append(type_name)
                items[type_name] = {'name': type_name, 'url': '',
                    'parent': 'global', 'disabled': False, 'manageable': False}
        return

    for name in sm.listRegistrationNames():
        if items.has_key(name):
            # a child has already supplied one of these
            continue

        registry = sm.queryRegistrations(name)
        assert registry
        infos = [info for info in registry.info() if info['active']]
        if infos:
            configobj = infos[0]['registration']
            component = configobj.getComponent()
            url = str(
                zapi.getView(component, 'absolute_url', request))
        else:
            url = ""
        items[name] = {'name': name, 'url': url, 'parent': 'parent',
            'disabled': not url, 'manageable': manageable}

    # look for more
    gatherConfiguredServices(getNextServiceManager(sm), request, items)

    # make it a list and sort by name
    items = items.values()
    items.sort(lambda a,b:cmp(a['name'], b['name']))
    return items

class ServiceActivation(BrowserView):
    """A view on the service manager, used by serviceactivation.pt.

    This really wants to be a view on a registration registry
    containing service registrations, but registries don't have names,
    so we make it a view on the service manager; the request parameter
    'type' determines which service is to be configured."""

    def isDisabled(self):
        sm = zapi.getServiceManager(self.context)
        registry = sm.queryRegistrations(self.request.get('type'))
        return not (registry and registry.active())

    def listRegistry(self):
        sm = zapi.getServiceManager(self.context)
        registry = sm.queryRegistrations(self.request.get('type'))
        if not registry:
            return []

        # XXX this code path is not being tested
        result = []
        dummy = {'id': 'None',
                 'active': False,
                 'registration': None,
                 'name': '',
                 'url': '',
                 'config': '',
                }
        for info in registry.info(True):
            configobj = info['registration']
            if configobj is None:
                info = dummy
                dummy = None
                if not result:
                    info['active'] = True
            else:
                component = configobj.getComponent()
                path = zapi.getPath(component)
                path = path.split("/")
                info['name'] = "/".join(path[-2:])
                info['url'] = str(
                    zapi.getView(component, 'absolute_url', self.request))
                info['config'] = str(zapi.getView(configobj, 'absolute_url',
                                             self.request))
            result.append(info)
        if dummy:
            result.append(dummy)
        return result

    def update(self):
        active = self.request.get("active")
        if not active:
            return ""

        sm = zapi.getServiceManager(self.context)
        registry = sm.queryRegistrations(self.request.get('type'))
        if not registry:
            return _("Invalid service type specified")
        old_active = registry.active()
        if active == "None":
            new_active = None
        else:
            new_active = zapi.traverse(sm, active)
        if old_active == new_active:
            return _("No change")

        if new_active is None:
            registry.activate(None)
            return _("Service deactivated")
        else:
            new_active.status = ActiveStatus
            s = _("${active_services} activated")
            s.mapping = {'active_services': active}
            return s

class MakeSite(BrowserView):
    """View for convering a possible site to a site
    """

    def addSiteManager(self):
        """Convert a possible site to a site

        XXX we should also initialize some user-selected services.

        >>> from zope.app.interfaces.traversing import IContainmentRoot
        >>> from zope.interface import implements

        >>> class PossibleSite:
        ...     implements(IContainmentRoot)
        ...     def setSiteManager(self, sm):
        ...         from zope.interface import directlyProvides
        ...         directlyProvides(self, ISite)


        >>> folder = PossibleSite()

        >>> from zope.publisher.browser import TestRequest
        >>> request = TestRequest()
        
        Now we'll make our folder a site:

        >>> MakeSite(folder, request).addSiteManager()

        Now verify that we have a site:

        >>> ISite.providedBy(folder)
        1

        Note that we've also redirected the request:

        >>> request.response.getStatus()
        302

        >>> request.response.getHeader('location')
        '++etc++site/@@SelectedManagementView.html'

        If we try to do it again, we'll fail:

        >>> MakeSite(folder, request).addSiteManager()
        Traceback (most recent call last):
        ...
        UserError: This is already a site


        """
        if ISite.providedBy(self.context):
            raise zapi.UserError('This is already a site')

        # we don't want to store security proxies (we can't,
        # actually), so we have to remove proxies here before passing
        # the context to the SiteManager.
        bare = removeAllProxies(self.context)
        sm = SiteManager(bare)
        self.context.setSiteManager(sm)
        self.request.response.redirect(
            "++etc++site/@@SelectedManagementView.html")


class Interfaces:
    """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:
    ...     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:
    """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:
    ...     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__
        # XXX the doc string needs some formatting for presentation
        # XXX self.doc = self.iface.__doc__
        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)

    def getServices(self):
        """Return an iterable of service dicts

        where the service dicts contains keys "name" and "registrations."
        registrations is a list of IRegistrations.
        """
        sm = zapi.getServiceManager(self.context)
        for name, iface in sm.getServiceDefinitions():
            service = sm.queryService(name)
            if service is None:
                continue
            registry = IInterfaceBasedRegistry(service, None)
            if registry is None:
                continue
            regs = list(registry.getRegistrationsForInterface(self.iface))
            if regs:
                yield {"name": name, "registrations": regs}
            

class MethodDetail:
    """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:
    ...     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__



=== Added File Zope3/src/zope/app/site/browser/add_svc_config.pt ===
<html metal:use-macro="context/@@standard_macros/dialog">
<body>
<div metal:fill-slot="body">

  <form action="add_svc_config.html" method="post">

    <p i18n:translate="">
      Register this object to provide the following service(s):
    </p>

    <table>
      <thead>
        <tr>
          <th i18n:translate="register-button">Register</th>
          <th i18n:translate="">Service name</th>
          <th i18n:translate="activate-button">Activate</th>
        </tr>
      </thead>
      <tbody>
        <tr tal:repeat="item view/listServiceTypes">
          <td>
            <input type="checkbox" name="name:list" value="value"
                   checked="checked" tal:attributes="value item/name" />
          </td>
          <td tal:content="item/name">Events</td>
          <td>
            <input type="checkbox" name="active:list" value="value"
                   tal:attributes="value item/name;
                                   checked item/checked" />
          </td>
        </tr>
      </tbody>
    </table>

    <input type="reset" value="Reset form"
           i18n:attributes="value reset-button" />
    <input type="submit" value="Submit"
           i18n:attributes="value submit-button" />

  </form>

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


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

<!-- SiteManagementFolder -->

  <addMenuItem
      class="zope.app.site.folder.SiteManagementFolder"
      permission="zope.ManageServices"
      title="Site-Management Folder"
      />

  <page
    for="zope.app.site.interfaces.ISiteManagementFolder"
    permission="zope.ManageServices" 
    class="zope.app.browser.container.contents.JustContents"
    name="index.html" attribute="index" />

  <page
     name="contents.html"
     for="zope.app.site.interfaces.ISiteManagementFolder"
     menu="zmi_views" title="Contents"
     permission="zope.ManageServices"
     class="zope.app.browser.container.contents.Contents"
     attribute="contents" />

  <view
     name="+"
     menu="zmi_actions" title="Add"
     for="zope.app.site.interfaces.ISiteManagementFolder"
     permission="zope.ManageServices"
     class="zope.app.site.browser.ComponentAdding">

    <page name="index.html"  attribute="index"  />
    <page name="action.html" attribute="action" />

  </view>

<!-- For services, just treat @@manage as @@index.html by default -->

  <!-- Get first accessable item from zmi_views menu -->
  <page
     for="zope.app.site.interfaces.ILocalService"
     name="index.html"
     permission="zope.ManageServices"
     class="zope.app.menu.browser.managementviewselector.ManagementViewSelector"
     allowed_interface="zope.publisher.interfaces.browser.IBrowserPublisher"
     />

<!-- Service Manager navigation action -->

  <page
      for="zope.app.site.interfaces.IPossibleSite"
      name="addServiceManager.html"
      permission="zope.ManageServices"
      class=".MakeSite"
      attribute="addSiteManager"
      />

  <menuItem
      menu="zmi_actions" title="Make a site"
      for="zope.app.site.interfaces.IPossibleSite"
      action="addServiceManager.html"
      filter="python:
          not modules['zope.app.site.interfaces'].ISite.providedBy(context)"
      permission="zope.ManageServices"
      />

  <menuItem
      menu="zmi_actions"
      title="Manage Site"
      for="zope.app.site.interfaces.ISite"
      action="++etc++site/@@SelectedManagementView.html"
      permission="zope.ManageServices"
      />

<!-- ServiceManager -->

  <page
     for="zope.app.site.interfaces.ISiteManager"
     name="tasks.html"
     menu="zmi_views" title="Tasks"
     template="tasks.pt"
     permission="zope.ManageServices" />


  <page
     for="zope.app.site.interfaces.ISiteManager"
     name="services.html"
     menu="zmi_views" title="Services"
     template="services.pt"
     class=".ServiceSummary"
     permission="zope.ManageServices" />

  <page
     for="zope.app.site.interfaces.ISiteManager"
     name="serviceActivation.html"
     template="serviceactivation.pt"
     class=".ServiceActivation"
     permission="zope.ManageServices" />


  <page
      for="zope.app.site.interfaces.ISiteManager"
      name="interfacebrowse.html"
      template="interfacebrowse.pt"
      class=".Interfaces"
      permission="zope.ManageServices"
      menu="zmi_views" title="Interface Browse" 
      />
  
  <page
      for="zope.app.site.interfaces.ISiteManager"
      name="interfacedetail.html"
      template="interfacedetail.pt"
      class=".Detail"
      permission="zope.ManageServices"
      />

  <page
      for="zope.app.site.interfaces.ISiteManager"
      name="interfacemethoddetail.html"
      template="interfacemethoddetail.pt"
      class=".MethodDetail"
      permission="zope.ManageServices"
      />


  <icon
      name="zmi_icon"
      for="zope.app.site.interfaces.ISiteManager"
      file="service_manager.gif" />

  <menuItems
      menu="zmi_actions"
      for="zope.app.site.interfaces.ISiteManager">

    <menuItem
        title="Visit default folder"
        action="default/@@SelectedManagementView.html"
        permission="zope.ManageServices" />
    <menuItem
        title="Add service"
        action="default/AddService"
        permission="zope.ManageServices" />
    <menuItem
        title="Add utility"
        action="default/AddUtility"
        permission="zope.ManageServices" />

  </menuItems>

  <page
      name="contents.html"
      for="zope.app.site.interfaces.ISiteManager"
      menu="zmi_views" title="Software"
      permission="zope.ManageServices"
      class="zope.app.browser.container.contents.Contents"
      attribute="contents" />

  <view
      name="+"
      menu="zmi_actions" title="Add Site Management Folder"
      for="zope.app.site.interfaces.ISiteManager"
      permission="zope.ManageServices"
      class="zope.app.browser.container.adding.Adding" 
      >

    <page name="index.html" attribute="index"/>
    <page name="action.html" attribute="action"/>
  </view>

  <pages
      for="zope.app.site.interfaces.ISiteManager"
      permission="zope.ManageServices"
      class="zope.app.browser.container.contents.JustContents">

    <page name="index.html" attribute="index" />

  </pages>

  <!-- ServiceRegistration -->

  <editform
      name="index.html"
      schema=
        "zope.app.site.interfaces.IServiceRegistration"
      menu="zmi_views"
      label="Edit Service Registration"
      permission="zope.ManageServices"
      fields="name componentPath permission status" />

  <page
      name="addRegistration.html"
      for="zope.app.site.interfaces.ILocalService"
      template="add_svc_config.pt"
      class=".AddServiceRegistration"
      permission="zope.ManageServices" />

  <page
      name="add_svc_config.html"
      for="zope.app.site.interfaces.ILocalService"
      attribute="action"
      class=".AddServiceRegistration"
      permission="zope.ManageServices" />

<!-- "Add Service" menu -->

  <menuItem
      menu="add_component"
      for="zope.app.container.interfaces.IAdding"
      action="../AddService"
      title="Service"
      description="Takes you to a menu of services to add"
      permission="zope.ManageServices"
      />

  <view
     name="AddService"
     for="zope.app.site.interfaces.ISiteManagementFolder"
     permission="zope.ManageServices"
     class=".ServiceAdding">

    <page name="index.html"  attribute="index"  />
    <page name="action.html" attribute="action" />

  </view>

</zope:configure>


=== Added File Zope3/src/zope/app/site/browser/interfacebrowse.pt ===
<html metal:use-macro="context/@@standard_macros/page">
<body>
<div metal:fill-slot="body">

  <h2 i18n:translate="">Interfaces registered with the Utility service</h2>
  
  <table class="listingdescription" summary="Interfaces Listing"
      cellspacing="0">
    <thead>
      <th>Interface Name</th>
      <th>Title</th>
    </thead>
    <tal:repeat tal:repeat="dict view/getInterfaces">
    <tr tal:define="oddrow repeat/dict/odd;"
        tal:attributes="class python:oddrow and 'even' or 'odd'">
      <td>
        <a href="/" 
         tal:attributes="href string:interfacedetail.html?id=${dict/id}"
         tal:content="dict/name">An interface name
        </a></td>  
      <td tal:content="dict/doc">Interface DocString</td>
    </tr>
    </tal:repeat>
  </table>  

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


=== Added File Zope3/src/zope/app/site/browser/interfacedetail.pt ===
<html metal:use-macro="context/@@standard_macros/page">
<body>
<div metal:fill-slot="body" tal:define="ignored view/setup">

  <h2 i18n:translate="">
    Interface
    <span tal:content="view/name" i18n:name="iface_name">name</span>
  </h2>

  <div tal:condition="view/doc">
    <h3 i18n:translate="">Documentation</h3>
    <div tal:content="view/doc">This is a doc string.</div>
  </div>

  <div tal:condition="view/methods">
    <h3 i18n:translate="class-methods">Methods</h3> 
      <table class="listingdescription" summary="Method Listing"
          cellspacing="0">
        <thead>
          <th>Method Signature</th>
          <th>Description</th>
        </thead>    
        <tal:repeat repeat="methoddict view/methods">
        <tr tal:define="oddrow repeat/methoddict/odd;"
            tal:attributes="class python:oddrow and 'even' or 'odd'">
          <td>
            <a href="/" 
               tal:attributes="href string:interfacemethoddetail.html?interface_id=${request/id}&method_id=${methoddict/method/__name__}">
               <strong><span tal:replace="string:${methoddict/method/__name__}"
                   >Method Name</span></strong><span 
                   tal:replace="string:${methoddict/method/getSignatureString}"
                   >Method Signature</span>
            </a>
          </td>
          <td tal:content="methoddict/title"></td>
        </tr>
        </tal:repeat>
      </table>  
  </div>

  <div tal:condition="view/schema">
    <h3 i18n:translate="schema-component">Schema</h3>
      <table class="listingdescription" summary="Schema Listing"
          cellspacing="0">
        <thead>
          <th>Field Name</th>
          <th>Type</th>
          <th>Description</th>
        </thead>    
        <tal:repeat repeat="field view/schema">
        <tal:define define="oddrow repeat/field/odd;
                            class python:oddrow and 'even' or 'odd'">
        <tr tal:attributes="class class">
          <td nowrap="nowrap">
            <strong>
              <span tal:replace="field/__name__" />
              <span tal:condition="field/required"
                  tal:replace="string:*">Required?</span>
            </strong>
          </td>  
          <td tal:content="field/__class__/__name__"></td>  
          <td tal:content="field/description"></td>
        </tr>
        </tal:define>
        </tal:repeat>
      </table>  
      <p>* indicates required fields.</p>
  </div>

  <div tal:repeat="service view/getServices">
    <h3 i18n:translate="">Registrations for 
      <span tal:content="service/name" i18n:name="service_name">Name</span> 
       service
    </h3>

  <table class="listingdescription" summary="Registration Listing"
      cellspacing="0">
    <thead>
      <th>Status</th>
      <th>Usage Summary</th>
      <th>Implementation Summary</th>
    </thead>
    <tal:repeat repeat="reg service/registrations">
      <tr tal:define="oddrow repeat/reg/odd"
          tal:attributes="class python:oddrow and 'even' or 'odd'">
        <td tal:content="reg/status">Status</td>
        <td tal:content="reg/usageSummary">Usage Summary</td>
        <td tal:content="reg/implementationSummary">Implementation</td>
      </tr>
    </tal:repeat>
  </table>

  </div>

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


=== Added File Zope3/src/zope/app/site/browser/interfacemethoddetail.pt ===
<html metal:use-macro="context/@@standard_macros/page">
<body>
<div metal:fill-slot="body" tal:define="ignored view/setup">

  <h2 i18n:translate="">
    <span tal:replace="string:${view/iface/__name__}.${view/name}${view/method/getSignatureString}">Method Signature</span>
  </h2>

  <div tal:content="view/doc">This is a doc string.</div>

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


=== Added File Zope3/src/zope/app/site/browser/service.gif ===
  <Binary-ish file>

=== Added File Zope3/src/zope/app/site/browser/service_manager.gif ===
  <Binary-ish file>

=== Added File Zope3/src/zope/app/site/browser/service_manager.png ===
  <Binary-ish file>

=== Added File Zope3/src/zope/app/site/browser/serviceactivation.pt ===
<html metal:use-macro="views/standard_macros/page">
<body>
<tal:block
    metal:fill-slot="headers"
    tal:define="global pagetip string:
    To activate a particular service implementation,
    check its radio button and click Update.
    "/>

<div metal:fill-slot="body">

  <h2 i18n:translate="">Registrations for service
    <i tal:content="request/type|default" i18n:name="service_type"
       i18n:translate="">No service type specified</i>
  </h2>

  <p tal:content="view/update">Message from update() goes here</p>

  <form action="." method="post"
        tal:attributes="action request/URL">
    <table tal:define="registry view/listRegistry">

      <thead>
        <tr> 
          <td></td> 
          <th align="left" i18n:translate="">Service</th> 
          <th align="left" i18n:translate="">Registration</th>
        </tr>
      </thead>

      <tbody>

        <tr tal:repeat="config registry">
          <td><input type="radio" name="active" value="default/configure/1"
                     tal:attributes="value config/id;
                                     checked config/active" /></td>
          <td tal:condition="not:config/name">Disabled</td>
          <td tal:condition="config/name"><a href="foo"
                 tal:content="config/name"
                 tal:attributes="href config/url">Implementation</a>
          </td>
          <td tal:condition="config/name"><a href="foo"
                 tal:content="config/id"
                 tal:attributes="href config/config">Registration</a>
          </td>
        </tr>
      
      </tbody>
  
    </table>

    <input type="hidden" name="type" value="Events"
           tal:attributes="value request/type|nothing" />
    <input type="submit" value="Submit" 
           i18n:attributes="value submit-button" />

  </form>

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


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

  <h2 i18n:translate="">
    Services registered in this site manager
  </h2>

  <div tal:define="message view/update;
                   registries view/listConfiguredServices">

    <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 services are registered.
    </p>
    
    <div tal:condition="registries">
      <p i18n:translate="">
         Unless a service is disabled the service name links to the
         active service.
         The (change registration)
         link allows activating a different implementation or
         disabling the service altogether.
      </p>
    
      <form method="POST" action="services.html">
    
        <table>
          <tr tal:repeat="reg registries">
            <td><input tal:condition="reg/manageable" type="checkbox"
                       name="selected:list" tal:attributes="value reg/name" />
            </td>
            <td>
             <a href="(link to the active service)"
                tal:condition="reg/url"
                tal:attributes= "href reg/url"
                tal:content="reg/name">
               Foobar (the service type)
             </a>

             <span tal:condition="reg/disabled"
                   tal:replace="string:${reg/name} (disabled)" />

             <span tal:condition="python:not reg['url'] and not reg['disabled']"
                   tal:replace="reg/name" />
            </td>
            <td>
             <tal:block condition="reg/manageable">
              <a href="xxx"
                 tal:condition="reg/manageable"
                 tal:attributes="href string:@@serviceActivation.html?type=${reg/name}"
                 i18n:translate="">
                (change registration)
              </a>
             </tal:block>
              <span tal:condition="not:reg/manageable" tal:replace="reg/parent" />
            </td>
          </tr>
        </table>

        <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="Delete" value="Delete"
               i18n:attributes="value delete-button"/>
        &nbsp;
        <input type="submit" name="Refresh" value="Refresh"
               i18n:attributes="value refresh-button"/>

      </form>

    </div>
  </div>

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


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

  <h2 i18n:translate="">
    Common Site Management Tasks
  </h2>

      <p i18n:translate="">
         The site management interface allows you to do stuff.
         Some of this stuff is good.
      </p>

  <dl>

    <dt i18n:translate=""> Tools: </dt>
    <dd i18n:translate="">
 	    Tools consist of
        <span title="Services register themselves with the ServiceService">Services</span>
 and <span title="Utilities register themselves with the UtilityService">Utilities</span>. These perform tasks like
        error logging, translation, authentication and so on.
        Your site may provide
        <a href="default/AddService" i18n:translate="">new services</a> or
        <a href="default/AddUtility" i18n:translate="">new utilities</a>
        (which may override existing tools). You may also configure the
        <a href="@@services.html" i18n:translate="">services</a> and
        <a href="default/Utilities/@@utilities.html"
          i18n:translate="">utilities</a> already present in this site.
    </dd>
    <dt i18n:translate=""> Software: </dt>
    <dd i18n:translate="">
       The site may <a href="@@contents.html" i18n:translate="">customise
        the behaviour of existing software</a>, or define its own.
        The first step in creating a new software package is to
        <a href="@@+">create a new Site Management Folder</a> to 
        contain the software.
        If you've already added your own software, you may 
        <a href="@@contents.html" i18n:translate="">edit it</a>.
   </dd>

    <!-- When software bundles are more than a wiki page, revisit this.
     <dt i18n:translate=""> Software Bundles: </dt><dd i18n:translate="">
        Installing,
        Removing
     </dd>
    -->


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




More information about the Zope3-Checkins mailing list