[Zope3-checkins] CVS: Zope3/lib/python/Zope/App/OFS/Services/Browser - AdapterConfigSummary.pt:1.2 PageConfigSummary.pt:1.2 ViewConfigSummary.pt:1.2 adapter.py:1.2 adapter_search.pt:1.2 add_adapter_config.pt:1.2 field.py:1.2 view.py:1.2 view_search.pt:1.2 zpt.py:1.2 configure.zcml:1.7

Jim Fulton jim@zope.com
Thu, 19 Dec 2002 15:38:54 -0500


Update of /cvs-repository/Zope3/lib/python/Zope/App/OFS/Services/Browser
In directory cvs.zope.org:/tmp/cvs-serv26340/lib/python/Zope/App/OFS/Services/Browser

Modified Files:
	configure.zcml 
Added Files:
	AdapterConfigSummary.pt PageConfigSummary.pt 
	ViewConfigSummary.pt adapter.py adapter_search.pt 
	add_adapter_config.pt field.py view.py view_search.pt zpt.py 
Log Message:
Merged changes made by Albertas and Jim from the AdapterAndView-branch
branch:

- Added TTW adapter service

  Todo: 

    o Named adapters

    o Getting classes in persistent modules working so we can actually
      create TTW adapters.

- Added TTW view service

  o View service

  o View configurations
 
    For configuting views from view factories

  o Page configurations 

    For configuring views based on templates (and optional classes)

  o View (sub)packages.  These get added to packages. You configure
    them with default configuration info and then add page templates
    to them. Added page temlates are automatically added as views with
    the same name.




=== Zope3/lib/python/Zope/App/OFS/Services/Browser/AdapterConfigSummary.pt 1.1 => 1.2 ===
--- /dev/null	Thu Dec 19 15:38:54 2002
+++ Zope3/lib/python/Zope/App/OFS/Services/Browser/AdapterConfigSummary.pt	Thu Dec 19 15:38:23 2002
@@ -0,0 +1 @@
+<span tal:replace="context/factoryName" />


=== Zope3/lib/python/Zope/App/OFS/Services/Browser/PageConfigSummary.pt 1.1 => 1.2 ===
--- /dev/null	Thu Dec 19 15:38:54 2002
+++ Zope3/lib/python/Zope/App/OFS/Services/Browser/PageConfigSummary.pt	Thu Dec 19 15:38:23 2002
@@ -0,0 +1,2 @@
+<span tal:replace="context/factoryName" />
+<span tal:replace="context/template" />


=== Zope3/lib/python/Zope/App/OFS/Services/Browser/ViewConfigSummary.pt 1.1 => 1.2 ===
--- /dev/null	Thu Dec 19 15:38:54 2002
+++ Zope3/lib/python/Zope/App/OFS/Services/Browser/ViewConfigSummary.pt	Thu Dec 19 15:38:23 2002
@@ -0,0 +1 @@
+<span tal:replace="context/factoryName" />


=== Zope3/lib/python/Zope/App/OFS/Services/Browser/adapter.py 1.1 => 1.2 ===
--- /dev/null	Thu Dec 19 15:38:54 2002
+++ Zope3/lib/python/Zope/App/OFS/Services/Browser/adapter.py	Thu Dec 19 15:38:23 2002
@@ -0,0 +1,112 @@
+##############################################################################
+#
+# 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.
+# 
+##############################################################################
+"""Views for local adapter configuration.
+
+  AdapterSeviceView -- it's a bit different from other services, as it
+  has a lot of things in it, so we provide a search interface:
+
+    search page
+    browsing page
+
+  AdapterConfigrationAdd
+
+$Id$
+"""
+__metaclass__ = type
+
+import md5
+from Zope.App.Forms.Utility \
+     import setUpWidgets, getWidgetsData, getWidgetsDataForContent, fieldNames
+from Zope.Publisher.Browser.BrowserView import BrowserView
+from Zope.App.OFS.Services.interfaces \
+     import IAdapterConfiguration, IAdapterConfigurationInfo
+from Zope.Event import publish
+from Zope.Event.ObjectEvent import ObjectCreatedEvent
+from Zope.App.OFS.Services.ConfigurationInterfaces import IConfiguration
+from Zope.App.OFS.Services.adapter import AdapterConfiguration
+from Zope.App.ComponentArchitecture.InterfaceField import InterfaceField
+from Interface import Interface
+from Zope.ComponentArchitecture import getView
+from Zope.Proxy.ContextWrapper import ContextWrapper
+
+class IAdapterSearch(Interface):
+
+    forInterface = InterfaceField(title=u"For interface",
+                                  required=False,
+                                  )
+    providedInterface = InterfaceField(title=u"Provided interface",
+                                       required=False,
+                                       )
+    
+
+class AdapterServiceView(BrowserView):
+
+    def __init__(self, *args):
+        super(AdapterServiceView, self).__init__(*args)
+        setUpWidgets(self, IAdapterSearch)
+    
+    def configInfo(self):
+        forInterface = self.forInterface.getData()
+        providedInterface = self.providedInterface.getData()
+
+
+        result = []
+        for (forInterface, providedInterface, registry
+             ) in self.context.getRegisteredMatching(forInterface,
+                                                     providedInterface):
+            forInterface = (
+                forInterface.__module__ +"."+ forInterface.__name__)
+            providedInterface = (
+                providedInterface.__module__ +"."+ providedInterface.__name__)
+
+            registry = ContextWrapper(registry, self.context)
+            view = getView(registry, "ChangeConfigurations", self.request)
+            prefix = md5.new('%s %s' %
+                             (forInterface, providedInterface)).hexdigest()
+            view.setPrefix(prefix)
+            view.update()
+            result.append(
+                {'forInterface': forInterface,
+                 'providedInterface': providedInterface,
+                 'view': view,
+                 })
+
+        return result
+
+
+class AdapterConfigurationAdd(BrowserView):
+
+    def __init__(self, *args):
+        super(AdapterConfigurationAdd, self).__init__(*args)
+        setUpWidgets(self, IAdapterConfiguration)
+
+    def refresh(self):
+        if "FINISH" in self.request:
+            data = getWidgetsData(self, IAdapterConfigurationInfo)
+            configuration = AdapterConfiguration(**data)
+            publish(self.context.context, ObjectCreatedEvent(configuration))
+            configuration = self.context.add(configuration)
+            getWidgetsDataForContent(self, IConfiguration, configuration)
+            self.request.response.redirect(self.context.nextURL())
+            return False
+
+        return True
+
+    def getWidgets(self):
+        return ([getattr(self, name)
+                 for name in fieldNames(IAdapterConfigurationInfo)]
+                +
+                [getattr(self, name)
+                 for name in fieldNames(IConfiguration)]
+                )


=== Zope3/lib/python/Zope/App/OFS/Services/Browser/adapter_search.pt 1.1 => 1.2 ===
--- /dev/null	Thu Dec 19 15:38:54 2002
+++ Zope3/lib/python/Zope/App/OFS/Services/Browser/adapter_search.pt	Thu Dec 19 15:38:23 2002
@@ -0,0 +1,48 @@
+<html metal:use-macro="views/standard_macros/page">
+<head><title></title></head>
+<body>
+<div metal:fill-slot="body">
+
+<form action="." method="GET"
+      tal:attributes="action request/URL"
+      >
+  <table>
+    <tr tal:content="structure view/forInterface/row" />
+    <tr tal:content="structure view/providedInterface/row" />
+    <tr>
+      <td></td>
+      <td> 
+         <input type="submit" value="Refresh">
+         <input type="submit" value="Search" name="SEARCH">
+     </td>
+    </tr>
+  </table>
+</form>
+
+<form action="." method="POST"
+      tal:attributes="action request/URL"
+      tal:condition="request/SEARCH|nothing"
+      >
+  <table>
+    <tr>
+       <th>For/<br>Provided</th>
+       <th>Configuration</th>
+    </tr>
+    
+    <tr tal:repeat="config view/configInfo">
+      <td> <span tal:content="config/forInterface" />/<br>
+           <span tal:content="config/providedInterface" />
+      </td>
+      <td tal:content="structure config/view" />
+    </tr>
+    <tr>
+      <td></td>
+      <td></td>
+      <td> 
+         <input type="submit" value="Update" name="UPDATE_SUBMIT">
+      </td>
+    </tr>
+  </table>
+</form>
+
+</div></body></html>


=== Zope3/lib/python/Zope/App/OFS/Services/Browser/add_adapter_config.pt 1.1 => 1.2 ===
--- /dev/null	Thu Dec 19 15:38:54 2002
+++ Zope3/lib/python/Zope/App/OFS/Services/Browser/add_adapter_config.pt	Thu Dec 19 15:38:23 2002
@@ -0,0 +1,21 @@
+<html metal:use-macro="views/standard_macros/page">
+<head><title></title></head>
+<body>
+<div metal:fill-slot="body">
+
+<form action="." method="post"
+      tal:attributes="action request/URL"
+      tal:condition="view/refresh"
+      >
+  <table>
+     <tr tal:repeat="widget view/getWidgets"
+         tal:content="structure widget/row">
+       <td>Label</td>
+       <td>Roles</td>
+     </tr>
+  </table>
+  <input type="submit" value="Refresh" />
+  <input type="submit" name="FINISH" value="Finish" />
+</form>
+
+</div></body></html>


=== Zope3/lib/python/Zope/App/OFS/Services/Browser/field.py 1.1 => 1.2 ===
--- /dev/null	Thu Dec 19 15:38:54 2002
+++ Zope3/lib/python/Zope/App/OFS/Services/Browser/field.py	Thu Dec 19 15:38:23 2002
@@ -0,0 +1,46 @@
+##############################################################################
+#
+# 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.
+# 
+##############################################################################
+"""A widget for ComponentLocation field.
+
+$Id$
+"""
+__metaclass__ = type
+
+from Zope.App.Forms.Views.Browser.Widget import BrowserWidget
+from Zope.ComponentArchitecture import getServiceManager
+
+class ComponentLocationWidget(BrowserWidget):
+
+    def _convert(self, value):
+        return value or None
+
+    def __call__(self):
+        selected = self._showData()
+        service_manager = getServiceManager(self.context.context)
+        info = service_manager.queryComponent(self.context.type)
+        result = []
+
+        result.append('<select name="%s">' % self.name)
+        result.append('<option></option>')
+
+        for item in info:
+            item = item['path']
+            if item == selected:
+                result.append('<option selected>%s</option>' % item)
+            else:
+                result.append('<option>%s</option>' % item)
+
+        result.append('</select>')
+
+        return "\n".join(result)


=== Zope3/lib/python/Zope/App/OFS/Services/Browser/view.py 1.1 => 1.2 ===
--- /dev/null	Thu Dec 19 15:38:54 2002
+++ Zope3/lib/python/Zope/App/OFS/Services/Browser/view.py	Thu Dec 19 15:38:23 2002
@@ -0,0 +1,110 @@
+##############################################################################
+#
+# 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.
+# 
+##############################################################################
+"""Views for local view configuration.
+
+  ViewSeviceView -- it's a bit different from other services, as it
+  has a lot of things in it, so we provide a search interface:
+
+    search page
+    browsing page
+
+  ViewConfigrationAdd
+
+$Id$
+"""
+__metaclass__ = type
+
+import md5
+from Zope.App.Forms.Utility \
+     import setUpWidgets, getWidgetsData, getWidgetsDataForContent, fieldNames
+from Zope.Publisher.Browser.BrowserView import BrowserView
+from Zope.App.OFS.Services.interfaces \
+     import IViewConfiguration, IViewConfigurationInfo
+from Zope.App.OFS.Services.interfaces \
+     import IPageConfiguration, IPageConfigurationInfo
+from Zope.Event import publish
+from Zope.Event.ObjectEvent import ObjectCreatedEvent
+from Zope.App.OFS.Services.ConfigurationInterfaces import IConfiguration
+from Zope.App.OFS.Services.view import ViewConfiguration, PageConfiguration
+from Zope.App.ComponentArchitecture.InterfaceField import InterfaceField
+from Interface import Interface
+from Zope.ComponentArchitecture import getView
+from Zope.Proxy.ContextWrapper import ContextWrapper
+from Zope.Schema import TextLine, BytesLine
+from Zope.ComponentArchitecture.IPresentation import IPresentation
+
+class IViewSearch(Interface):
+
+    forInterface = InterfaceField(title=u"For interface",
+                                  required=False,
+                                  )
+    presentationType = InterfaceField(title=u"Provided interface",
+                                      required=False,
+                                      type=IPresentation
+                                      )
+
+    viewName = TextLine(title=u'View name',
+                        required=False,
+                        )
+
+    layer = BytesLine(title=u'Layer',
+                      required=False,
+                        )
+    
+
+class ViewServiceView(BrowserView):
+
+    def __init__(self, *args):
+        super(ViewServiceView, self).__init__(*args)
+        setUpWidgets(self, IViewSearch)
+    
+    def configInfo(self):
+        input_for = self.forInterface.getData()
+        input_type = self.presentationType.getData()
+        input_name = self.viewName.getData()
+        input_layer = self.layer.getData()
+
+        result = []
+        for info in self.context.getRegisteredMatching(
+            input_for, input_type, input_name, input_layer):
+
+            forInterface, presentationType, registry, layer, viewName = info
+            
+            forInterface = (
+                forInterface.__module__ +"."+ forInterface.__name__)
+            presentationType = (
+                presentationType.__module__ +"."+ presentationType.__name__)
+
+            registry = ContextWrapper(registry, self.context)
+            view = getView(registry, "ChangeConfigurations", self.request)
+            prefix = md5.new('%s %s' %
+                             (forInterface, presentationType)).hexdigest()
+            view.setPrefix(prefix)
+            view.update()
+
+            if input_name is not None:
+                viewName = None
+
+            if input_layer is not None:
+                layer = None
+            
+            result.append(
+                {'forInterface': forInterface,
+                 'presentationType': presentationType,
+                 'view': view,
+                 'viewName': viewName,
+                 'layer': layer,
+                 })
+
+        return result


=== Zope3/lib/python/Zope/App/OFS/Services/Browser/view_search.pt 1.1 => 1.2 ===
--- /dev/null	Thu Dec 19 15:38:54 2002
+++ Zope3/lib/python/Zope/App/OFS/Services/Browser/view_search.pt	Thu Dec 19 15:38:23 2002
@@ -0,0 +1,59 @@
+<html metal:use-macro="views/standard_macros/page">
+<head><title></title></head>
+<body>
+<div metal:fill-slot="body">
+
+<form action="." method="GET"
+      tal:attributes="action request/URL"
+      >
+  <table>
+    <tr tal:content="structure view/forInterface/row" />
+    <tr tal:content="structure view/presentationType/row" />
+    <tr>
+      <td></td>
+      <td> 
+         <input type="submit" value="Refresh">
+         <input type="submit" value="Search" name="SEARCH">
+     </td>
+    </tr>
+  </table>
+</form>
+
+<form action="." method="POST"
+      tal:attributes="action request/URL"
+      tal:condition="request/SEARCH|nothing"
+      >
+  <table      
+      tal:define="layer not:request/field.layer|nothing;
+                  viewName not:request/field.viewName|nothing;
+                  "
+      >
+    <tr>
+       <th>For/<br>Provided</th>
+       <th tal:condition="layer">Layer</th>
+       <th tal:condition="viewName">View name</th>
+       <th>Configuration</th>
+       
+    </tr>
+    
+    <tr tal:repeat="config view/configInfo">
+      <td> <span tal:content="config/forInterface" />/<br>
+           <span tal:content="config/presentationType" />
+      </td>
+      <td tal:condition="layer"
+          tal:content="config/layer">Layer</td>
+      <td tal:condition="viewName"
+          tal:content="config/viewName">View name</td>      
+      <td tal:content="structure config/view" />
+    </tr>
+    <tr>
+      <td></td>
+      <td></td>
+      <td> 
+         <input type="submit" value="Update" name="UPDATE_SUBMIT">
+      </td>
+    </tr>
+  </table>
+</form>
+
+</div></body></html>


=== Zope3/lib/python/Zope/App/OFS/Services/Browser/zpt.py 1.1 => 1.2 ===
--- /dev/null	Thu Dec 19 15:38:54 2002
+++ Zope3/lib/python/Zope/App/OFS/Services/Browser/zpt.py	Thu Dec 19 15:38:23 2002
@@ -0,0 +1,31 @@
+##############################################################################
+#
+# 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.
+# 
+##############################################################################
+"""XXX short summary goes here.
+
+XXX longer description goes here.
+
+$Id$
+"""
+from Zope.Publisher.Browser.BrowserView import BrowserView
+
+__metaclass__ = type
+
+class Source(BrowserView):
+
+    def __call__(self):
+        self.request.response.setHeader('content-type',
+                                        self.context.contentType)
+        return self.context.source
+
+    


=== Zope3/lib/python/Zope/App/OFS/Services/Browser/configure.zcml 1.6 => 1.7 ===
--- Zope3/lib/python/Zope/App/OFS/Services/Browser/configure.zcml:1.6	Wed Dec 18 18:36:59 2002
+++ Zope3/lib/python/Zope/App/OFS/Services/Browser/configure.zcml	Thu Dec 19 15:38:23 2002
@@ -81,4 +81,224 @@
     <page name="index.html" attribute="index" />
   </view>
 
+<!-- Component Location widget -->
+
+<view
+    for=".field.IComponentLocation"
+    name="edit"
+    factory=".Browser.field.ComponentLocationWidget"
+    allowed_interface="Zope.App.Forms.Views.Browser.IBrowserWidget."
+    permission="Zope.ManageServices"
+    />
+
+<defaultView for=".interfaces.IAdapterConfiguration" name="edit.html" />
+
+<!-- Adapters -->
+
+<form:edit
+    schema=".interfaces.IAdapterConfiguration"
+    name="edit.html"
+    label="Change adapter"
+    permission="Zope.ManageServices"
+    />
+
+<form:subedit
+    schema=".interfaces.IAdapterConfiguration"
+    name="ItemEdit"
+    label="Adapter"
+    permission="Zope.ManageServices"
+    fields="forInterface providedInterface factoryName title status"
+    />
+
+<view
+     for = ".interfaces.IAdapterConfiguration"
+     name = "ConfigurationSummary"
+     template = "Browser/AdapterConfigSummary.pt"
+     permission="Zope.ManageServices" 
+     />  
+
+<defaultView
+     for = "Zope.ComponentArchitecture.IAdapterService."
+     name = "index.html"
+     />
+
+<view
+     for = "Zope.ComponentArchitecture.IAdapterService."
+     name = "index.html"
+     template = "Browser/adapter_search.pt"
+     permission="Zope.ManageServices" 
+     class=".Browser.adapter.AdapterServiceView"
+     />  
+
+<view
+     for = "Zope.App.OFS.Container.IAdding."
+     name="AdapterConfiguration"
+     permission="Zope.ManageServices" 
+     factory=".Browser.adapter.AdapterConfigurationAdd"
+     >
+  <page
+      name="index.html"
+      template="Browser/add_adapter_config.pt"
+      />
+</view>
+
+<menuItem
+      for="Zope.App.OFS.Container.IAdding."
+      menu="add_configuration"
+      action="AdapterConfiguration"
+      title="Adapter"
+      />
+
+<menuItem
+      for="Zope.App.OFS.Container.IAdding."
+      menu="add_component"
+      action="Zope.App.OFS.Services.AdapterService"
+      title="Adapter Service"
+      />
+
+<!-- Views -->
+
+<form:edit
+    schema=".interfaces.IViewConfiguration"
+    name="edit.html"
+    label="Change view"
+    permission="Zope.ManageServices"
+    />
+
+<form:subedit
+    schema=".interfaces.IViewConfiguration"
+    name="ItemEdit"
+    label="View"
+    permission="Zope.ManageServices"
+    fields="forInterface viewName presentationType factoryName layer
+            title status"
+    />
+
+<view
+     for = ".interfaces.IViewConfiguration"
+     name = "ConfigurationSummary"
+     template = "Browser/ViewConfigSummary.pt"
+     permission="Zope.ManageServices" 
+     />  
+
+<form:add
+      schema = ".interfaces.IViewConfiguration"
+      name= "ViewConfiguration"
+      content_factory = ".view.ViewConfiguration"
+      keyword_arguments = "forInterface presentationType factoryName viewName"
+      set_before_add = "layer"
+      label = "Configure a view" 
+      permission="Zope.ManageServices" 
+      fields="forInterface viewName presentationType
+              factoryName layer title status description"
+      />
+
+<menuItem
+      for="Zope.App.OFS.Container.IAdding."
+      menu="add_configuration"
+      action="ViewConfiguration"
+      title="View"
+      />
+
+<defaultView
+     for = "Zope.ComponentArchitecture.IViewService."
+     name = "index.html"
+     />
+
+<view
+     for = "Zope.ComponentArchitecture.IViewService."
+     name = "index.html"
+     template = "Browser/view_search.pt"
+     permission="Zope.ManageServices" 
+     class=".Browser.view.ViewServiceView"
+     />  
+
+<menuItem
+      for="Zope.App.OFS.Container.IAdding."
+      menu="add_component"
+      action="Zope.App.OFS.Services.ViewService"
+      title="View Service"
+      />
+
+<!-- View pages -->
+
+
+<form:edit
+    schema=".interfaces.IPageConfiguration"
+    name="edit.html"
+    label="Change page"
+    permission="Zope.ManageServices"
+    />
+
+<form:subedit
+    schema=".interfaces.IPageConfiguration"
+    name="ItemEdit"
+    label="Page"
+    permission="Zope.ManageServices"
+    fields="forInterface viewName presentationType factoryName layer 
+            title status"
+    />
+
+<view
+     for = ".interfaces.IPageConfiguration"
+     name = "ConfigurationSummary"
+     template = "Browser/PageConfigSummary.pt"
+     permission="Zope.ManageServices" 
+     />  
+
+<form:add
+      schema = ".interfaces.IPageConfiguration"
+      name= "PageConfiguration"
+      content_factory = ".view.PageConfiguration"
+      keyword_arguments = "forInterface presentationType factoryName
+                           viewName"
+      set_before_add = "template layer"
+      label = "Configure a view page" 
+      permission="Zope.ManageServices" 
+      fields="forInterface viewName presentationType
+              template factoryName layer title status description"
+      />
+
+<menuItem
+      for="Zope.App.OFS.Container.IAdding."
+      menu="add_configuration"
+      action="PageConfiguration"
+      title="Page"
+      />
+
+<!-- ZPT Templates -->
+
+<defaultView
+    for=".interfaces.IZPTTemplate"
+    name="index.html"
+    />
+
+<view 
+    for=".interfaces.IZPTTemplate"
+    name="index.html"
+    factory=".Browser.zpt.Source"
+    permission="Zope.ManageServices"
+    />
+
+<form:edit
+    schema=".interfaces.IZPTTemplate"
+    name="edit.html"
+    label="ZPT Template"
+    permission="Zope.ManageServices"
+    />
+
+<menuItems menu="zmi_views" for=".interfaces.IZPTTemplate">
+  <menuItem action="edit.html" title="Edit" />
+  <menuItem title="View" action="index.html"/>
+</menuItems>
+
+<menuItem
+    for="Zope.App.OFS.Container.IAdding."
+    menu="add_component"
+    action="Zope.app.services.zpt.template"
+    title="ZPT Template"
+    />
+
+
+
 </zope:zopeConfigure>