[Zope3-checkins]
SVN: Zope3/branches/srichter-blow-services/src/zope/app/presentation/
Started fixing page folder code;
all tests pass, but I get some exception in the GUI
Stephan Richter
srichter at cosmos.phy.tufts.edu
Fri Feb 4 12:57:39 EST 2005
Log message for revision 29041:
Started fixing page folder code; all tests pass, but I get some exception in the GUI
Changed:
U Zope3/branches/srichter-blow-services/src/zope/app/presentation/__init__.py
D Zope3/branches/srichter-blow-services/src/zope/app/presentation/browser/
A Zope3/branches/srichter-blow-services/src/zope/app/presentation/browser.py
A Zope3/branches/srichter-blow-services/src/zope/app/presentation/browser.zcml
U Zope3/branches/srichter-blow-services/src/zope/app/presentation/configure.zcml
A Zope3/branches/srichter-blow-services/src/zope/app/presentation/fssync.py
A Zope3/branches/srichter-blow-services/src/zope/app/presentation/interfaces.py
U Zope3/branches/srichter-blow-services/src/zope/app/presentation/pagefolder.py
D Zope3/branches/srichter-blow-services/src/zope/app/presentation/pagefolder.zcml
D Zope3/branches/srichter-blow-services/src/zope/app/presentation/presentation.py
A Zope3/branches/srichter-blow-services/src/zope/app/presentation/registration.py
A Zope3/branches/srichter-blow-services/src/zope/app/presentation/tests/
U Zope3/branches/srichter-blow-services/src/zope/app/presentation/tests/test_pagefolder.py
D Zope3/branches/srichter-blow-services/src/zope/app/presentation/tests/test_presentation.py
A Zope3/branches/srichter-blow-services/src/zope/app/presentation/tests/test_presentation.py
U Zope3/branches/srichter-blow-services/src/zope/app/presentation/tests/test_zpt.py
D Zope3/branches/srichter-blow-services/src/zope/app/presentation/xxx_Tests/
U Zope3/branches/srichter-blow-services/src/zope/app/presentation/zpt.py
D Zope3/branches/srichter-blow-services/src/zope/app/presentation/zpt.zcml
-=-
Modified: Zope3/branches/srichter-blow-services/src/zope/app/presentation/__init__.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/presentation/__init__.py 2005-02-04 17:55:08 UTC (rev 29040)
+++ Zope3/branches/srichter-blow-services/src/zope/app/presentation/__init__.py 2005-02-04 17:57:38 UTC (rev 29041)
@@ -16,6 +16,3 @@
$Id$
"""
__docformat__ = 'restructuredtext'
-
-from zope.app.presentation.interfaces import IPageRegistration
-from zope.app.presentation.presentation import PageRegistration
Added: Zope3/branches/srichter-blow-services/src/zope/app/presentation/browser.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/presentation/browser.py 2005-02-04 17:55:08 UTC (rev 29040)
+++ Zope3/branches/srichter-blow-services/src/zope/app/presentation/browser.py 2005-02-04 17:57:38 UTC (rev 29041)
@@ -0,0 +1,45 @@
+##############################################################################
+#
+# 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.
+#
+##############################################################################
+"""Presentation component views.
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+
+class PageFolderDefaultConfiguration(object):
+ "Make sure to update all page template registrations, when info changed"
+
+ def changed(self):
+ """Apply changes to existing configurations"""
+
+ folder = self.context
+ if folder.apply:
+ folder.applyDefaults()
+
+
+class Source(object):
+ """Set the content type of the rendered template code."""
+ def __call__(self):
+ self.request.response.setHeader('content-type',
+ self.context.contentType)
+ return self.context.source
+
+
+class PageRegistrationView(object):
+ """Helper class for the page edit form."""
+
+ def update(self):
+ super(PageRegistrationView, self).update()
+ if "UPDATE_SUBMIT" in self.request:
+ self.context.validate()
Added: Zope3/branches/srichter-blow-services/src/zope/app/presentation/browser.zcml
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/presentation/browser.zcml 2005-02-04 17:55:08 UTC (rev 29040)
+++ Zope3/branches/srichter-blow-services/src/zope/app/presentation/browser.zcml 2005-02-04 17:57:38 UTC (rev 29041)
@@ -0,0 +1,92 @@
+<configure
+ xmlns="http://namespaces.zope.org/browser">
+
+ <addform
+ schema=".interfaces.IPageRegistration"
+ name="AddPageRegistration.html"
+ label="Register a view page"
+ content_factory=".registration.PageRegistration"
+ fields="required name template factoryName permission status attribute"
+ keyword_arguments="required factoryName name permission attribute"
+ set_before_add="template"
+ permission="zope.ManageSite"
+ />
+
+ <editform
+ schema=".interfaces.IPageRegistration"
+ name="index.html"
+ class=".browser.PageRegistrationView"
+ menu="zmi_views" label="Change page"
+ permission="zope.ManageSite" />
+
+
+ <!-- Page Folder -->
+
+ <containerViews
+ for=".interfaces.IPageFolder"
+ index="zope.ManageSite"
+ contents="zope.ManageSite"
+ add="zope.ManageSite"
+ />
+
+ <editform
+ name="DefaultRegistration.html"
+ label="Default registration parameters"
+ schema=".interfaces.IPageFolderInfo"
+ class=".browser.PageFolderDefaultConfiguration"
+ menu="zmi_views" title="Default Registration"
+ permission="zope.ManageSite"
+ />
+
+ <addform
+ name="AddPageFolder.html"
+ label="Default registration parameters"
+ schema=".interfaces.IPageFolderInfo"
+ content_factory=".pagefolder.PageFolder"
+ permission="zope.ManageSite"
+ />
+
+ <addMenuItem
+ class=".pagefolder.PageFolder"
+ title="Page Folder"
+ permission="zope.ManageSite"
+ view="AddPageFolder.html"
+ />
+
+
+ <!-- Page Template -->
+
+ <view
+ for=".interfaces.IZPTTemplate"
+ name="index.html"
+ class=".browser.Source"
+ permission="zope.ManageSite" />
+
+ <editform
+ schema=".interfaces.IZPTInfo"
+ name="edit.html"
+ menu="zmi_views"
+ label="ZPT Template"
+ permission="zope.ManageSite"
+ />
+
+ <addMenuItem
+ permission="zope.ManageSite"
+ class=".zpt.ZPTTemplate"
+ title="ZPT Template" />
+
+ <addform
+ for=".interfaces.IZPTTemplate"
+ schema=".interfaces.IPageRegistration"
+ name="addRegistration.html"
+ class="zope.app.component.browser.registration.AddComponentRegistration"
+ content_factory=".registration.PageRegistration"
+ keyword_arguments="required factoryName name permission attribute"
+ set_before_add="template"
+ label="Register a view ZPT"
+ permission="zope.ManageSite"
+ fields="required name
+ template factoryName permission status attribute"
+ />
+
+</configure>
Modified: Zope3/branches/srichter-blow-services/src/zope/app/presentation/configure.zcml
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/presentation/configure.zcml 2005-02-04 17:55:08 UTC (rev 29040)
+++ Zope3/branches/srichter-blow-services/src/zope/app/presentation/configure.zcml 2005-02-04 17:57:38 UTC (rev 29041)
@@ -1,43 +1,126 @@
<configure
- xmlns='http://namespaces.zope.org/zope'
+ xmlns="http://namespaces.zope.org/zope"
+ xmlns:fssync="http://namespaces.zope.org/fssync"
i18n_domain="zope"
>
-<!-- XXX: temporarily deactivated
+ <content class=".registration.PageRegistration">
+ <require
+ permission="zope.ManageSite"
+ interface=".interfaces.IPageRegistration"
+ set_schema=".interfaces.IPageRegistration"
+ />
+ </content>
+
+ <subscriber
+ factory=".registration.PageRegistrationAddSubscriber"
+ for=".interfaces.IPageRegistration
+ zope.app.container.interfaces.IObjectAddedEvent"
+ />
+
+ <subscriber
+ factory=".registration.PageRegistrationRemoveSubscriber"
+ for=".interfaces.IPageRegistration
+ zope.app.container.interfaces.IObjectRemovedEvent"
+ />
-<content class=".presentation.ViewRegistration">
- <require
+
+ <!-- Page Folder -->
+
+ <content class=".pagefolder.PageFolder">
+ <factory
+ id="zope.app.presentation.pagefolder.PageFolder"
+ title="View Folder"
+ />
+ <implements
+ interface="zope.app.annotation.interfaces.IAttributeAnnotatable"
+ />
+ <require
+ permission="zope.View"
+ interface="zope.app.container.interfaces.IReadContainer"
+ />
+ <require
+ permission="zope.ManageSite"
+ interface="zope.app.container.interfaces.IWriteContainer
+ .interfaces.IPageFolderInfo"
+ set_schema=".interfaces.IPageFolderInfo"
+ attributes="registrationManager applyDefaults"
+ />
+ </content>
+
+ <adapter
+ for=".interfaces.IPageFolder"
+ provides="zope.app.filerepresentation.interfaces.IFileFactory"
+ factory=".zpt.ZPTFactory"
permission="zope.ManageSite"
- interface=".presentation.IViewRegistration"
- set_schema="zope.app.registration.interfaces.IRegistration"
/>
-</content>
+
+ <adapter
+ for="zope.app.site.interfaces.ISiteManagementFolder"
+ provides="zope.app.filerepresentation.interfaces.IDirectoryFactory"
+ factory=".pagefolder.PageFolderFactory"
+ permission="zope.ManageContent"
+ />
+
+ <subscriber
+ factory=".pagefolder.templateAddedSubscriber"
+ for=".interfaces.IZPTTemplate
+ zope.app.container.interfaces.IObjectAddedEvent"
+ />
+
+ <subscriber
+ factory=".pagefolder.templateRemovedSubscriber"
+ for=".interfaces.IZPTTemplate
+ zope.app.container.interfaces.IObjectRemovedEvent"
+ />
-<content class=".presentation.PageRegistration">
- <require
+
+ <!-- Page Templates -->
+
+ <content class=".zpt.ZPTTemplate">
+ <factory
+ title="zope.app.ZPTTemplate"
+ description="Persistent View Page Template"
+ />
+ <require
+ permission="zope.View"
+ attributes="__call__"
+ />
+ <require
+ permission="zope.ManageServices"
+ interface=".interfaces.IZPTTemplate"
+ set_schema=".interfaces.IZPTTemplate"
+ />
+ <implements
+ interface="zope.app.annotation.interfaces.IAttributeAnnotatable"
+ />
+ </content>
+
+ <adapter
+ for=".interfaces.IZPTTemplate"
+ provides="zope.app.filerepresentation.interfaces.IReadFile"
+ factory=".zpt.ReadFile"
permission="zope.ManageSite"
- interface=".interfaces.IPageRegistration"
- set_schema=".interfaces.IPageRegistration"
/>
-</content>
+
+ <adapter
+ for=".interfaces.IZPTTemplate"
+ provides="zope.app.filerepresentation.interfaces.IWriteFile"
+ factory=".zpt.WriteFile"
+ permission="zope.ManageSite"
+ />
+
+ <!-- Filesystem synchronization support -->
+ <fssync:adapter
+ class=".pagefolder.PageFolder"
+ factory=".fssync.PageFolderAdapter"
+ />
-<subscriber
- factory=".presentation.PageRegistrationAddSubscriber"
- for=".interfaces.IPageRegistration
- zope.app.container.interfaces.IObjectAddedEvent"
- />
+ <fssync:adapter
+ class=".zpt.ZPTTemplate"
+ factory=".fssync.ZPTPageAdapter"
+ />
+
+ <include file="browser.zcml" />
-<subscriber
- factory=".presentation.PageRegistrationRemoveSubscriber"
- for=".interfaces.IPageRegistration
- zope.app.container.interfaces.IObjectRemovedEvent"
- />
-
-<include file="pagefolder.zcml" />
-<include file="zpt.zcml" />
-
-<include package=".browser" />
-
--->
-
</configure>
Added: Zope3/branches/srichter-blow-services/src/zope/app/presentation/fssync.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/presentation/fssync.py 2005-02-04 17:55:08 UTC (rev 29040)
+++ Zope3/branches/srichter-blow-services/src/zope/app/presentation/fssync.py 2005-02-04 17:57:38 UTC (rev 29041)
@@ -0,0 +1,53 @@
+##############################################################################
+#
+# 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.
+#
+##############################################################################
+"""FSSync adapters for local presentation components
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+from zope.interface import implements
+
+from zope.fssync.server.entryadapter import ObjectEntryAdapter, AttrMapping
+from zope.fssync.server.interfaces import IObjectDirectory, IObjectFile
+
+
+class PageFolderAdapter(ObjectEntryAdapter):
+ """ObjectFile adapter for `PageFolder` objects."""
+ implements(IObjectDirectory)
+
+ _attrNames = ('factoryName', 'required', 'permission')
+
+ def contents(self):
+ return self.context.items()
+
+ def extra(self):
+ return AttrMapping(self.context, self._attrNames)
+
+
+class ZPTPageAdapter(ObjectEntryAdapter):
+ """ObjectFile adapter for `ZPTTemplate` objects."""
+
+ implements(IObjectFile)
+
+ def getBody(self):
+ return self.context.source
+
+ def setBody(self, data):
+ # Convert the data to Unicode, since that's what ZPTTemplate
+ # wants; it's normally read from a file so it'll be bytes.
+ # The default encoding in Zope is UTF-8.
+ self.context.source = data.decode('UTF-8')
+
+ def extra(self):
+ return AttrMapping(self.context, ('contentType', 'expand'))
Added: Zope3/branches/srichter-blow-services/src/zope/app/presentation/interfaces.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/presentation/interfaces.py 2005-02-04 17:55:08 UTC (rev 29040)
+++ Zope3/branches/srichter-blow-services/src/zope/app/presentation/interfaces.py 2005-02-04 17:57:38 UTC (rev 29041)
@@ -0,0 +1,131 @@
+##############################################################################
+#
+# 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.
+#
+##############################################################################
+"""Presentation interfaces
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+import zope.interface
+import zope.schema
+
+import zope.app.container
+import zope.app.component.interfaces
+from zope.app.container import constraints
+from zope.app.i18n import ZopeMessageIDFactory as _
+
+
+class IPageRegistration(zope.app.component.interfaces.IAdapterRegistration):
+
+ requestType = zope.schema.Choice(
+ title = _(u"Request type"),
+ description = _(u"The type of requests the view works with"),
+ vocabulary="Interfaces",
+ readonly = True,
+ required = True,
+ )
+
+ template = zope.app.component.interfaces.registration.Component(
+ title = _(u"Page template"),
+ required = False,
+ )
+
+ attribute = zope.schema.TextLine(
+ title = _(u"Class attribute"),
+ required = False,
+ )
+
+ def validate(self):
+ """Verifies that the registration is valid.
+
+ Raises a ConfigurationError if the validation is failed.
+ """
+
+class IZPTInfo(zope.interface.Interface):
+ """ZPT Template configuration information
+ """
+
+ contentType = zope.schema.BytesLine(
+ title=u'Content type of generated output',
+ required=True,
+ default='text/html'
+ )
+
+ source = zope.schema.Text(
+ title=u"Source",
+ description=u"""The source of the page template.""",
+ required=True)
+
+ expand = zope.schema.Bool(
+ title=u"Expand macros",
+ )
+
+
+class IZPTTemplate(IZPTInfo,
+ zope.app.component.interfaces.registration.IRegisterable):
+ """ZPT Templates for use in views"""
+
+ def render(context, request, *args, **kw):
+ """Render the page template.
+
+ The context argument is bound to the top-level `context`
+ variable. The request argument is bound to the top-level
+ `request` variable. The positional arguments are bound to the
+ `args` variable and the keyword arguments are bound to the
+ `options` variable.
+
+ """
+
+
+class IPageFolderInfo(zope.interface.Interface):
+ """Default registration information for page folders
+
+ This information is used to configure the pages in the folder.
+ """
+
+ required = zope.schema.Choice(
+ title = _(u"For interface"),
+ description = _(u"The interface of the objects being viewed"),
+ vocabulary="Interfaces",
+ required = True,
+ )
+
+ factoryName = zope.schema.BytesLine(
+ title=_(u"The dotted name of a factory for creating the view"),
+ required = False,
+ )
+ permission = zope.schema.Choice(
+ title=_(u"Permission"),
+ description=_(u"The permission required to use the view"),
+ vocabulary="Permission Ids",
+ required = True,
+ )
+
+ apply = zope.schema.Bool(
+ title=_(u"Apply changes to existing pages"),
+ required = True,
+ )
+
+
+class IPageFolder(
+ IPageFolderInfo,
+ zope.app.container.interfaces.IContainer,
+ zope.app.component.interfaces.registration.IRegisterableContainer):
+
+ constraints.contains(IZPTTemplate)
+ constraints.containers(
+ zope.app.component.interfaces.registration.IRegisterableContainer)
+
+ def applyDefaults(self):
+ """Apply the default configuration to the already-registered pages.
+ """
Modified: Zope3/branches/srichter-blow-services/src/zope/app/presentation/pagefolder.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/presentation/pagefolder.py 2005-02-04 17:55:08 UTC (rev 29040)
+++ Zope3/branches/srichter-blow-services/src/zope/app/presentation/pagefolder.py 2005-02-04 17:57:38 UTC (rev 29041)
@@ -21,86 +21,23 @@
__docformat__ = 'restructuredtext'
from zope.interface import Interface, implements
-from zope.schema import BytesLine, Bool, Field, Choice
-
-from zope.app.container.btree import BTreeContainer
-from zope.fssync.server.entryadapter import ObjectEntryAdapter, AttrMapping
-from zope.app.component.interfaces.registration import ActiveStatus
-from zope.app.component.interfaces.registration import IRegistrationManager
-from zope.app.component.interfaces.registration import IRegisterableContainer
-from zope.app.component.interfaces.registration import IRegisterable
-from zope.app.container.constraints import ItemTypePrecondition
-from zope.app.presentation import PageRegistration
-from zope.app.component.registration import RegisterableContainer
-from zope.app.container.constraints import ContainerTypesConstraint
-from zpt import IZPTTemplate
-from zope.app.traversing.api import getPath
from zope.proxy import removeAllProxies
from zope.publisher.interfaces.browser import IBrowserRequest
-from zope.app.container.interfaces import IContainer
+from zope.app import zapi
+from zope.app.component.interfaces.registration import ActiveStatus
+from zope.app.component.interfaces.registration import InactiveStatus
+from zope.app.component.interfaces.registration import IRegistered
+from zope.app.component.registration import RegisterableContainer
+from zope.app.container.btree import BTreeContainer
from zope.app.filerepresentation.interfaces import IDirectoryFactory
-from zope.fssync.server.interfaces import IObjectDirectory
-from zope.app.component.interfaces.registration import IRegisterableContainer
-from zope.app.i18n import ZopeMessageIDFactory as _
-class IPageFolderInfo(Interface):
- """Default registration information for page folders
+import interfaces
+import registration
- This information is used to configure the pages in the folder.
- """
-
- required = Choice(
- title = _(u"For interface"),
- description = _(u"The interface of the objects being viewed"),
- vocabulary="Interfaces",
- required = True,
- )
-
- factoryName = BytesLine(
- title=_(u"The dotted name of a factory for creating the view"),
- required = False,
- )
-
- layer = BytesLine(
- title = _(u"Layer"),
- description = _(u"The skin layer the view is registered for"),
- required = False,
- min_length = 1,
- default = "default",
- )
-
- permission = Choice(
- title=_(u"Permission"),
- description=_(u"The permission required to use the view"),
- vocabulary="Permission Ids",
- required = True,
- )
-
- apply = Bool(
- title=_(u"Apply changes to existing pages"),
- required = True,
- )
-
-class IPageFolder(IPageFolderInfo, IContainer, IRegisterableContainer):
-
- def applyDefaults(self):
- """Apply the default configuration to the already-registered pages.
- """
-
- def __setitem__(name, template):
- """Add a template to the folder
- """
-
- __setitem__.precondition = ItemTypePrecondition(IZPTTemplate)
-
- __parent__ = Field(
- constraint = ContainerTypesConstraint(IRegisterableContainer))
-
-
class PageFolder(RegisterableContainer, BTreeContainer):
- implements(IPageFolder)
+ implements(interfaces.IPageFolder)
requestType = IBrowserRequest
layer = "default"
@@ -111,84 +48,54 @@
template = None
apply = True
- ########################################################
- # The logic for managing registrations is handled by the
- # decorator class below.
- ########################################################
-
-
- def __setitem__(self, name, object):
- if (IRegistrationManager.providedBy(object) or
- IZPTTemplate.providedBy(object)):
- super(PageFolder, self).__setitem__(name, object)
- else:
- raise TypeError("Can only add templates", object)
-
-
- # If a template is added, we need to configure it too.
- if IZPTTemplate.providedBy(object):
- template = self[name]
- template = getPath(template)
- registration = PageRegistration(
- required=self.required,
- name=name,
- permission=self.permission,
- factoryName=self.factoryName,
- template=template,
- layer=self.layer,
- )
-
- registrations = self.getRegistrationManager()
- id = registrations.addRegistration(registration)
- registration = registrations[id]
- registration.status = ActiveStatus
-
def applyDefaults(self):
- """Apply the default configuration to the already-registered pages.
- """
+ """Apply the default configuration to the already-registered pages."""
- rm = self.getRegistrationManager()
- for name in rm:
- registration = rm[name]
- status = registration.status
- if status == ActiveStatus:
- registration.status = RegisteredStatus
- registration.status = UnregisteredStatus
+ for name in self.registrationManager:
+ registration = self.registrationManager[name]
+ orig_status = registration.status
+ registration.status = InactiveStatus
- # Cheat and set required and layer even though they're
- # read-only. This is ok since the registration is now not
- # registered.
+ # Cheat and set required even though it is read-only. This is ok
+ # since the registration is now not registered.
registration.required = removeAllProxies(self.required)
registration.factoryName = self.factoryName
- registration.layer = self.layer
registration.permission = self.permission
# Now restore the registration status
- registration.status = status
+ registration.status = orig_status
-_attrNames = (
- 'factoryName',
- 'required',
- 'layer',
- 'permission',
- )
+def templateAddedSubscriber(template, event):
+ """Create a registration for the added template."""
+ pagefolder = zapi.getParent(template)
+ # Create and add template
+ reg = registration.PageRegistration(
+ required=pagefolder.required,
+ name=zapi.name(template),
+ permission=pagefolder.permission,
+ factoryName=pagefolder.factoryName,
+ template=template,
+ )
+
+ id = pagefolder.registrationManager.addRegistration(reg)
+ reg.status = ActiveStatus
-class PageFolderAdapter(ObjectEntryAdapter):
- """ObjectFile adapter for `PageFolder` objects."""
- implements(IObjectDirectory)
+def templateRemovedSubscriber(template, event):
+ """Remove the registration of a template, when it is removed."""
+ registered = IRegistered(template)
+ reg_manager = zapi.getParent(template.registrationManager)
+ for reg in registered.registrations():
+ del reg_manager[zapi.name(reg)]
- def contents(self):
- return self.context.items()
- def extra(self):
- return AttrMapping(self.context, _attrNames)
-
-
class PageFolderFactory(object):
+ """A directory factory to create page folders inside site
+ management folders.
+ """
implements(IDirectoryFactory)
Deleted: Zope3/branches/srichter-blow-services/src/zope/app/presentation/pagefolder.zcml
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/presentation/pagefolder.zcml 2005-02-04 17:55:08 UTC (rev 29040)
+++ Zope3/branches/srichter-blow-services/src/zope/app/presentation/pagefolder.zcml 2005-02-04 17:57:38 UTC (rev 29041)
@@ -1,47 +0,0 @@
-<configure
- xmlns="http://namespaces.zope.org/zope"
- xmlns:event="http://namespaces.zope.org/event"
- xmlns:fssync="http://namespaces.zope.org/fssync"
- >
-
-<!-- Page Folder -->
-
-<content class=".pagefolder.PageFolder">
- <factory
- id="zope.app.presentation.pagefolder.PageFolder"
- title="View Folder"
- />
- <require
- permission="zope.View"
- interface="zope.app.container.interfaces.IReadContainer" />
- <require
- permission="zope.ManageServices"
- interface="zope.app.container.interfaces.IWriteContainer
- .pagefolder.IPageFolderInfo"
- set_schema=".pagefolder.IPageFolderInfo"
- attributes="getRegistrationManager applyDefaults"
- />
- <implements
- interface="zope.app.annotation.interfaces.IAttributeAnnotatable" />
-</content>
-
-<adapter
- for=".pagefolder.IPageFolder"
- provides="zope.app.filerepresentation.interfaces.IFileFactory"
- factory=".zpt.ZPTFactory"
- permission="zope.ManageServices"
- />
-
-<adapter
- for="zope.app.site.interfaces.ISiteManagementFolder"
- provides="zope.app.filerepresentation.interfaces.IDirectoryFactory"
- factory=".pagefolder.PageFolderFactory"
- permission="zope.ManageContent"
- />
-
-<fssync:adapter
- class=".pagefolder.PageFolder"
- factory=".pagefolder.PageFolderAdapter"
- />
-
-</configure>
Deleted: Zope3/branches/srichter-blow-services/src/zope/app/presentation/presentation.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/presentation/presentation.py 2005-02-04 17:55:08 UTC (rev 29040)
+++ Zope3/branches/srichter-blow-services/src/zope/app/presentation/presentation.py 2005-02-04 17:57:38 UTC (rev 29041)
@@ -1,255 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2003 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.
-#
-##############################################################################
-"""Local presentation components
-
-$Id$
-"""
-__docformat__ = 'restructuredtext'
-
-import persistent.dict
-
-from zope.interface import implements, providedBy, Interface, Attribute
-from zope.security.checker import NamesChecker, ProxyFactory
-
-import zope.component.interfaces
-import zope.configuration.exceptions
-import zope.proxy
-import zope.publisher.interfaces.browser
-
-import zope.app.component.interfaces.registration
-import zope.app.component.adapter
-import zope.app.container.contained
-import zope.app.interface.interfaces
-from zope.app import zapi
-from zope.app.i18n import ZopeMessageIDFactory as _
-from zope.app.dependable.interfaces import IDependable, DependencyError
-
-import interfaces
-
-class GlobalViewRegistration(object):
- """Registrations representing global view thingies."""
-
- implements(zope.app.component.interfaces.registration.IRegistration)
-
- status = zope.app.component.interfaces.registration.ActiveStatus
-
- def __init__(self, context):
- self.context = context
- self.required = context.required[0]
- self.ptype = context.required[-1]
- self.factories = context.factory
- self.layer = context.layer
- self.viewName = context.name
-
- def usageSummary(self):
- if self.required is None:
- ifname = _("any-interface", "Anything")
- else:
- ifname = self.required.getName()
- summary = _("${view_name} ${ptype} View for ${iface_name}")
- if self.layer and self.layer != "default":
- summary = _(
- "${view_name} ${ptype} View for ${iface_name} in layer ${layer}"
- )
- summary.mapping = {'view_name': self.viewName,
- 'ptype': self.ptype.getName(),
- 'iface_name': ifname,
- 'layer': self.layer}
- return summary
-
- def implementationSummary(self):
- # Report that this registration is implied because it was
- # globally defined in ZCML
- return _("Registered by ZCML")
-
-class LocalLayer(
- zope.app.component.adapter.LocalAdapterRegistry,
- zope.app.container.contained.Contained,
- ):
-
- def __init__(self, base, next, parent, name):
- zope.app.adapter.LocalAdapterRegistry.__init__(
- self, base, next)
- self.__parent__ = parent
- self.__name__ = name
-
-class ViewRegistration(zope.app.component.registration.SimpleRegistration):
- implements(interfaces.IViewRegistration)
-
- provided = Interface
-
- # For usageSummary(); subclass may override
- _what = _("view-component", 'View')
-
- def __init__(self,
- required, name, requestType,
- factoryName, permission, layer='default'):
- self.required = required
- self.requestType = requestType
- self.factoryName = factoryName
- self.name = name
- self.layer = layer
- self.permission = permission
-
- def usageSummary(self):
- if self.required is None:
- ifname = _('any-interface', "Anything")
- else:
- ifname = self.required.getName()
-
- pname = self.requestType.getName()
- summary = _("${view_name} for ${pname} ${what} ${iface_name}")
- if self.layer and self.layer != "default":
- summary = _(
- "${view_name} for ${pname} ${what} ${iface_name}"
- " in layer ${layer}"
- )
- summary.mapping = {'view_name': self.name,
- 'pname': pname,
- 'what': self._what,
- 'iface_name': ifname,
- 'layer': self.layer}
- return summary
-
- def with(self):
- return (self.requestType, )
- with = property(with)
-
- def factory(self):
- folder = self.__parent__.__parent__
- return folder.resolve(self.factoryName)
- factory = property(factory)
-
-class PageRegistration(ViewRegistration):
- implements(interfaces.IPageRegistration)
-
- # We only care about browser pages
- requestType = zope.publisher.interfaces.browser.IBrowserRequest
-
- # For usageSummary()
- _what = _("page-component", "Page")
-
- def __init__(self,
- required, name, permission,
- factoryName=None, template=None, attribute=None,
- layer='default'):
-
- # An interface coming out of an interface widget is security
- # proxied which is not pickable, thus remove the proxies here
- required = zope.proxy.removeAllProxies(required)
-
- super(PageRegistration, self).__init__(
- required, name, self.requestType,
- factoryName, permission, layer)
-
- self.template = template
- self.attribute = attribute
-
- def validate(self):
- if self.template and self.attribute:
- raise zope.configuration.exceptions.ConfigurationError(
- "PageRegistration for %s view name %s: "
- "Cannot have both 'template' and 'attribute' at the same "
- "time." %
- (self.required, self.name))
-
- if not self.template and not self.attribute:
- raise zope.configuration.exceptions.ConfigurationError(
- "PageRegistration for %s view name %s: "
- "Should have a 'template' or 'attribute' attribute." %
- (self.required, self.name))
-
- if not self.factoryName and self.attribute:
- raise zope.configuration.exceptions.ConfigurationError(
- "PageRegistration for %s view name %s: "
- "Cannot have an 'attribute' without a 'factoryName'." %
- (self.required, self.name))
-
- def factory(self):
- self.validate()
- sm = zapi.getSiteManager(self)
-
- if self.factoryName:
- folder = self.__parent__.__parent__
- class_ = folder.resolve(self.factoryName)
- else:
- class_ = BrowserView
-
- if self.attribute:
- return AttrViewFactory(class_, self.attribute)
- else:
- if self.template[0]=='/':
- # This is needed because we need to do an unrestricted zapi.
- # traverse
- root = zope.proxy.removeAllProxies(zapi.getRoot(sm))
- template = zapi.traverse(root, self.template)
- else:
- template = zapi.traverse(self.__parent__.__parent__,
- self.template)
- return TemplateViewFactory(class_, template, self.permission)
-
- factory = property(factory)
-
-def PageRegistrationAddSubscriber(registration, event):
- if registration.template:
- template = zapi.traverse(registration.__parent__.__parent__,
- registration.template)
- dependents = IDependable(template)
- objectpath = zapi.getPath(registration)
- dependents.addDependent(objectpath)
-
-
-def PageRegistrationRemoveSubscriber(registration, event):
- if registration.template:
- template = zapi.traverse(registration.__parent__.__parent__,
- registration.template)
- dependents = IDependable(template)
- objectpath = zapi.getPath(registration)
- dependents.removeDependent(objectpath)
-
-class TemplateViewFactory(object):
-
- def __init__(self, cls, template, permission):
- self.cls, self.template, self.permission = cls, template, permission
-
- # TODO Trap code that uses 'Permissions' vocabulary instead of
- # 'Permission Ids'. This check should go away once the mess
- # with permissions is straigthened up.
- from zope.app.security.permission import Permission
- if isinstance(permission, Permission):
- raise TypeError('permission should be a string or CheckerPublic,'
- ' not %r' % permission)
-
- def __call__(self, object, request):
- checker = NamesChecker(__call__ = self.permission)
- template = BoundTemplate(self.template, self.cls(object, request))
- return ProxyFactory(template, checker)
-
-class AttrViewFactory(object):
-
- def __init__(self, cls, attr):
- self.cls, self.attr = cls, attr
-
- def __call__(self, object, request):
- attr = getattr(self.cls(object, request), self.attr)
- return ProxyFactory(attr)
-
-class BoundTemplate(object):
-
- def __init__(self, template, view):
- self.template = template
- self.view = view
-
- def __call__(self, *args, **kw):
- return self.template.render(self.view, *args, **kw)
Copied: Zope3/branches/srichter-blow-services/src/zope/app/presentation/registration.py (from rev 28853, Zope3/branches/srichter-blow-services/src/zope/app/presentation/presentation.py)
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/presentation/presentation.py 2005-01-17 15:30:10 UTC (rev 28853)
+++ Zope3/branches/srichter-blow-services/src/zope/app/presentation/registration.py 2005-02-04 17:57:38 UTC (rev 29041)
@@ -0,0 +1,146 @@
+##############################################################################
+#
+# Copyright (c) 2003 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.
+#
+##############################################################################
+"""Local presentation components
+
+$Id$
+"""
+__docformat__ = 'restructuredtext'
+
+import persistent.dict
+
+from zope.interface import implements, providedBy, Interface, Attribute
+from zope.security.checker import NamesChecker, ProxyFactory
+
+import zope.component.interfaces
+import zope.configuration.exceptions
+import zope.proxy
+import zope.publisher.interfaces.browser
+
+import zope.app.component.interfaces.registration
+import zope.app.component.site
+import zope.app.container.contained
+import zope.app.interface.interfaces
+import zope.app.module
+from zope.app import zapi
+from zope.app.dependable.interfaces import IDependable, DependencyError
+from zope.app.publisher.browser import BrowserView
+
+import interfaces
+
+
+class PageRegistration(zope.app.component.site.AdapterRegistration):
+ implements(interfaces.IPageRegistration)
+
+ provided = Interface
+ # We only care about browser pages
+ requestType = zope.publisher.interfaces.browser.IBrowserRequest
+
+ def __init__(self, required, name, permission,
+ factoryName=None, template=None, attribute=None):
+ # An interface coming out of an interface widget is security
+ # proxied which is not pickable, thus remove the proxies here
+ required = zope.proxy.removeAllProxies(required)
+
+ self.required = required
+ self.factoryName = factoryName
+ self.name = name
+ self.permission = permission
+ self.template = template
+ self.attribute = attribute
+
+ def validate(self):
+ if self.template and self.attribute:
+ raise zope.configuration.exceptions.ConfigurationError(
+ "PageRegistration for %s view name %s: "
+ "Cannot have both 'template' and 'attribute' at the same "
+ "time." %
+ (self.required, self.name))
+
+ if not self.template and not self.attribute:
+ raise zope.configuration.exceptions.ConfigurationError(
+ "PageRegistration for %s view name %s: "
+ "Should have a 'template' or 'attribute' attribute." %
+ (self.required, self.name))
+
+ if not self.factoryName and self.attribute:
+ raise zope.configuration.exceptions.ConfigurationError(
+ "PageRegistration for %s view name %s: "
+ "Cannot have an 'attribute' without a 'factoryName'." %
+ (self.required, self.name))
+
+ def with(self):
+ return (self.requestType, )
+ with = property(with)
+
+ def component(self):
+ self.validate()
+ sm = zapi.getSiteManager(self)
+
+ if self.factoryName:
+ class_ = zope.app.module.resolve(self.factoryName, self)
+ else:
+ class_ = BrowserView
+
+ if self.attribute:
+ return AttributeViewFactory(class_, self.attribute)
+ else:
+ return TemplateViewFactory(class_, self.template, self.permission)
+
+ component = property(component)
+
+
+def PageRegistrationAddSubscriber(registration, event):
+ if registration.template is not None:
+ dependents = IDependable(registration.template)
+ objectpath = zapi.getPath(registration)
+ dependents.addDependent(objectpath)
+
+
+def PageRegistrationRemoveSubscriber(registration, event):
+ if registration.template is not None:
+ dependents = IDependable(registration.template)
+ objectpath = zapi.getPath(registration)
+ dependents.removeDependent(objectpath)
+
+
+class TemplateViewFactory(object):
+ """Factory that produces a callable template-based view."""
+ def __init__(self, cls, template, permission):
+ self.cls, self.template, self.permission = cls, template, permission
+
+ def __call__(self, object, request):
+ checker = NamesChecker(__call__ = self.permission)
+ template = BoundTemplate(self.template, self.cls(object, request))
+ return ProxyFactory(template, checker)
+
+
+class AttributeViewFactory(object):
+ """Factory that produces an attribute-based view."""
+
+ def __init__(self, cls, attr):
+ self.cls, self.attr = cls, attr
+
+ def __call__(self, object, request):
+ attr = getattr(self.cls(object, request), self.attr)
+ return ProxyFactory(attr)
+
+
+class BoundTemplate(object):
+
+ def __init__(self, template, view):
+ self.template = template
+ self.view = view
+
+ def __call__(self, *args, **kw):
+ return self.template.render(self.view, *args, **kw)
Copied: Zope3/branches/srichter-blow-services/src/zope/app/presentation/tests (from rev 28825, Zope3/branches/srichter-blow-services/src/zope/app/presentation/xxx_Tests)
Modified: Zope3/branches/srichter-blow-services/src/zope/app/presentation/tests/test_pagefolder.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/presentation/xxx_Tests/test_pagefolder.py 2005-01-13 16:28:47 UTC (rev 28825)
+++ Zope3/branches/srichter-blow-services/src/zope/app/presentation/tests/test_pagefolder.py 2005-02-04 17:57:38 UTC (rev 29041)
@@ -15,40 +15,36 @@
$Id$
"""
-from unittest import TestCase, TestSuite, main, makeSuite
-from zope.app.testing import ztapi, setup
-from zope.app.component.testing import PlacefulSetup
-from zope.app.presentation.pagefolder import PageFolder, IPageFolder
-from zope.app.presentation.zpt import ZPTTemplate
-from zope.app.component.interfaces.registration import ActiveStatus
-from zope.interface import Interface
+import unittest
+import zope.interface
from zope.publisher.interfaces.browser import IBrowserRequest
-from zope.app.registration.tests.test_registrationmanager \
- import RegisterableContainerTests
-from zope.app.dependable.interfaces import IDependable
-from zope.app.annotation.interfaces import IAttributeAnnotatable
-from zope.app.dependable import Dependable
from zope.app import zapi
-from zope.app.annotation.interfaces import IAnnotations, IAnnotatable
-from zope.app.annotation.attribute import AttributeAnnotations
+from zope.app.component.interfaces.registration import ActiveStatus
+from zope.app.component.testing import PlacefulSetup
+from zope.app.container.interfaces import IObjectAddedEvent
+from zope.app.presentation.interfaces import IPageFolder, IZPTTemplate
+from zope.app.presentation.pagefolder import PageFolder
+from zope.app.presentation.pagefolder import templateAddedSubscriber
+from zope.app.presentation.zpt import ZPTTemplate
+from zope.app.testing import ztapi, setup
-
-class I(Interface):
+class I(zope.interface.Interface):
pass
-class I2(Interface):
+class I2(zope.interface.Interface):
pass
-class Test(RegisterableContainerTests, PlacefulSetup, TestCase):
+class PageFolderTest(PlacefulSetup, unittest.TestCase):
def setUp(self):
sm = PlacefulSetup.setUp(self, site=True)
default = zapi.traverse(self.rootFolder, '++etc++site/default')
+ setup.setUpAnnotations()
+ setup.setUpTraversal()
+ ztapi.subscribe((IZPTTemplate, IObjectAddedEvent),
+ None, templateAddedSubscriber)
- ztapi.provideAdapter(IAnnotatable, IAnnotations, AttributeAnnotations)
- ztapi.provideAdapter(IAnnotatable, IDependable, Dependable)
-
default["PF"] = PageFolder()
pagefolder = zapi.traverse(default, "PF")
@@ -58,60 +54,50 @@
self.__pagefolder = pagefolder
-
-
- def test___setitem__(self):
+ def test_templateAddedSubscriber(self):
pagefolder = self.__pagefolder
pagefolder['foo.html'] = ZPTTemplate()
- rm = pagefolder.getRegistrationManager()
- name = rm.keys()[-1]
- registration = zapi.traverse(pagefolder.getRegistrationManager(),
- name)
+ rm = pagefolder.registrationManager
+ name = rm.keys()[0]
+ registration = zapi.traverse(rm, name)
self.assertEqual(registration.status, ActiveStatus)
self.assertEqual(registration.required, I)
self.assertEqual(registration.requestType, IBrowserRequest)
self.assertEqual(registration.name, u'foo.html')
- self.assertEqual(registration.layer, 'default')
self.assertEqual(registration.factoryName, None)
self.assertEqual(registration.permission, 'zope.View')
self.assertEqual(registration.attribute, None)
- self.assertRaises(TypeError,
- pagefolder.__setitem__, 'bar.html', PageFolder())
-
def test_applyDefaults(self):
pagefolder = self.__pagefolder
pagefolder['foo.html'] = ZPTTemplate()
- rm = pagefolder.getRegistrationManager()
+ rm = pagefolder.registrationManager
name = rm.keys()[-1]
- registration = zapi.traverse(pagefolder.getRegistrationManager(), name)
+ registration = zapi.traverse(rm, name)
self.assertEqual(registration.status, ActiveStatus)
self.assertEqual(registration.required, I)
self.assertEqual(registration.requestType, IBrowserRequest)
self.assertEqual(registration.name, u'foo.html')
- self.assertEqual(registration.layer, 'default')
self.assertEqual(registration.factoryName, None)
self.assertEqual(registration.permission, 'zope.View')
self.assertEqual(registration.attribute, None)
pagefolder.required = I2
pagefolder.permission = 'zope.ManageContent'
- pagefolder.layer = 'debug'
pagefolder.applyDefaults()
- registration = zapi.traverse(pagefolder.getRegistrationManager(), name)
+ registration = zapi.traverse(rm, name)
self.assertEqual(registration.status, ActiveStatus)
self.assertEqual(registration.required, I2)
self.assertEqual(registration.requestType, IBrowserRequest)
self.assertEqual(registration.name, u'foo.html')
- self.assertEqual(registration.layer, 'debug')
self.assertEqual(registration.factoryName, None)
self.assertEqual(registration.permission, 'zope.ManageContent')
self.assertEqual(registration.attribute, None)
@@ -119,9 +105,9 @@
def test_suite():
- return TestSuite((
- makeSuite(Test),
+ return unittest.TestSuite((
+ unittest.makeSuite(PageFolderTest),
))
if __name__=='__main__':
- main(defaultTest='test_suite')
+ unittest.main(defaultTest='test_suite')
Deleted: Zope3/branches/srichter-blow-services/src/zope/app/presentation/tests/test_presentation.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/presentation/xxx_Tests/test_presentation.py 2005-01-13 16:28:47 UTC (rev 28825)
+++ Zope3/branches/srichter-blow-services/src/zope/app/presentation/tests/test_presentation.py 2005-02-04 17:57:38 UTC (rev 29041)
@@ -1,281 +0,0 @@
-##############################################################################
-#
-# 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.
-#
-##############################################################################
-"""Test the presentation module
-
-$Id$
-"""
-
-from unittest import TestCase, TestSuite, main, makeSuite
-from zope.testing.doctestunit import DocTestSuite
-from zope.app.testing.placelesssetup import setUp, tearDown
-
-from zope.app import zapi
-from zope.interface import Interface, directlyProvides, implements
-from zope.interface.verify import verifyObject
-
-from zope.app.container.interfaces import IObjectAddedEvent
-from zope.app.container.interfaces import IObjectRemovedEvent
-from zope.app.folder import rootFolder
-from zope.app.presentation.zpt import IZPTTemplate
-from zope.app.registration.tests.iregistry import TestingIRegistry
-from zope.app.site.tests.placefulsetup import PlacefulSetup
-from zope.app.presentation.presentation import ViewRegistration
-from zope.app.presentation.presentation import PageRegistration
-from zope.app.presentation.presentation import BoundTemplate
-from zope.app.presentation.presentation import IPageRegistration
-from zope.app.presentation.presentation import PageRegistrationAddSubscriber
-from zope.app.presentation.presentation import PageRegistrationRemoveSubscriber
-from zope.app.testing import setup
-from zope.app.traversing.api import traverse
-
-from zope.component.exceptions import ComponentLookupError
-from zope.app.testing import ztapi, setup
-from zope.configuration.exceptions import ConfigurationError
-
-from zope.proxy import removeAllProxies
-
-from zope.publisher.browser import TestRequest
-from zope.publisher.interfaces.browser import IBrowserRequest
-from zope.app.container.contained import contained, uncontained, setitem
-from zope.app.container.interfaces import IContained, ILocation
-
-from zope.app.dependable.interfaces import IDependable
-from zope.app.annotation.interfaces import IAttributeAnnotatable
-from zope.app.registration.interfaces import IRegistered
-from zope.app.traversing.interfaces import IPhysicallyLocatable
-from zope.app.dependable import Dependable
-
-class I1(Interface):
- pass
-
-class I1E(I1):
- pass
-
-I2 = IBrowserRequest
-
-class I3(Interface):
- pass
-
-class I4(Interface):
- pass
-
-
-class Registration(object):
- required = I1
- requestType = I2
- name = 'test'
- layer = 'default'
- provided = Interface
-
- with = property(lambda self: (self.requestType, ))
- factories = property(lambda self: (self.factory, ))
-
- def __repr__(self):
- return 'Registration(%s)' % self.factory.__name__
-
-class C(object): pass
-
-class PhonyTemplate(object):
- __name__ = __parent__ = None
- implements(IZPTTemplate, IDependable, IRegistered)
-
- _dependents = ()
-
- def addDependent(self, location):
- self._dependents = tuple(
- [d for d in self._dependents if d != location]
- +
- [location]
- )
-
- def removeDependent(self, location):
- self._dependents = tuple(
- [d for d in self._dependents if d != location]
- )
-
- def dependents(self):
- return self._dependents
-
-
-class A(object):
- def __init__(self, object, request):
- self.context = object
- self.request = request
-
- run = PhonyTemplate()
-
-
-class ModuleFinder(object):
-
- implements(IContained)
-
- __parent__ = __name__ = None
-
- def __init__(self):
- self._dict = {}
-
- def resolve(self, name):
- if name == "Foo.Bar.A":
- return A
- raise ImportError(name)
-
- def __setitem__(self, key, ob):
- setitem(self, self.__setitem, key, ob)
-
- def __setitem(self, key, ob):
- self._dict[key] = ob
-
- def get(self, key, default=None):
- return self._dict.get(key, default)
-
-
-class PhonyPathAdapter(object):
- implements(IPhysicallyLocatable)
-
- def __init__(self, context):
- self.context = context
-
- def getPath(self):
- return self.context.__name__
-
- def getRoot(self):
- root = self.context
- while root.__parent__ is not None:
- root = root.__parent__
- return root
-
-
-class TestViewRegistration(PlacefulSetup, TestCase):
-
- def test_factories(self):
- folder = ModuleFinder()
- folder = contained(folder, folder)
- registration = contained(
- ViewRegistration(I1, 'test', I2, "Foo.Bar.A", 'zope.View'),
- folder,
- )
-
- self.assertEqual(registration.required, I1)
- self.assertEqual(registration.requestType, I2)
-
- factory = registration.factory
- self.assertEqual(factory, A)
-
-
-class TestPageRegistration(PlacefulSetup, TestCase):
-
- def setUp(self):
- PlacefulSetup.setUp(self)
- self.rootFolder = rootFolder()
- setup.createSiteManager(self.rootFolder)
- default = traverse(self.rootFolder, '++etc++site/default')
- self.__template = PhonyTemplate()
- default['t'] = self.__template
- self.folder = contained(ModuleFinder(), self.rootFolder)
- self.folder = contained(ModuleFinder(), self.folder)
-
- def test_factories_template(self):
- registration = contained(
- PageRegistration(I1, 'test', 'zope.View',
- "Foo.Bar.A",
- template='/++etc++site/default/t',
- ),
- self.folder,
- )
-
- c = C()
- request = TestRequest()
- factory = registration.factory
- view = factory(c, request)
- self.assertEqual(view.__class__, BoundTemplate)
- self.assertEqual(removeAllProxies(view).template, self.__template)
-
- view = removeAllProxies(view).view
- self.assert_(issubclass(view.__class__, A))
- self.assertEqual(view.context, c)
- self.assertEqual(view.request, request)
- self.assertEqual(registration.required, I1)
- self.assertEqual(registration.requestType, I2)
-
- def test_factories_attribute(self):
- registration = contained(
- PageRegistration(
- I1, 'test', 'zope.View', "Foo.Bar.A", attribute='run'),
- self.folder,6
- )
- c = C()
- request = TestRequest()
- factory = registration.factory
- view = factory(c, request)
- self.assertEquals(view, A.run)
-
- def test_factories_errors(self):
- registration = contained(
- PageRegistration(I1, 'test', 'zope.View', "Foo.Bar.A"),
- self.folder,
- )
- c = C()
- request = TestRequest()
- self.assertRaises(ConfigurationError, lambda: registration.factory)
- registration.template = '/++etc++site/default/t'
- registration.attribute = 'run'
- self.assertRaises(ConfigurationError, lambda: registration.factory)
-
- def test_registerAddSubscriber_template(self):
- ztapi.provideAdapter(ILocation, IPhysicallyLocatable,
- PhonyPathAdapter)
- ztapi.handle((IPageRegistration, IObjectAddedEvent),
- PageRegistrationAddSubscriber)
- registration = PageRegistration(I1, 'test', 'zope.View', "Foo.Bar.A",
- template='/++etc++site/default/t')
-
- # Test add event
- self.folder['test'] = registration
- dependents = IDependable(self.__template)
- self.assert_('test' in dependents.dependents())
-
- def test_registerRemoveSubscriber_template(self):
- ztapi.provideAdapter(ILocation, IPhysicallyLocatable,
- PhonyPathAdapter)
- ztapi.handle((IPageRegistration, IObjectRemovedEvent),
- PageRegistrationRemoveSubscriber)
- registration = PageRegistration(I1, 'test', 'zope.View', "Foo.Bar.A",
- template='/++etc++site/default/t')
-
- # Test remove event
- self.folder['test'] = registration
- uncontained(registration, self.folder, 'test')
- dependents = IDependable(self.__template)
- self.assert_('test' not in dependents.dependents())
-
- def test_addremoveNotify_attribute(self):
- ztapi.provideAdapter(ILocation, IPhysicallyLocatable,
- PhonyPathAdapter)
- registration = PageRegistration(I1, 'test', 'zope.View',
- "Foo.Bar.A", attribute='run')
- # Just add and remove registration to see that no errors occur
- self.folder['test'] = registration
- uncontained(registration, self.folder, 'test')
-
-
-def test_suite():
- return TestSuite([
- makeSuite(TestViewRegistration),
- makeSuite(TestPageRegistration),
- ])
-
-if __name__ == '__main__':
- main(defaultTest='test_suite')
-
-
Copied: Zope3/branches/srichter-blow-services/src/zope/app/presentation/tests/test_presentation.py (from rev 29005, Zope3/branches/srichter-blow-services/src/zope/app/presentation/xxx_Tests/test_presentation.py)
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/presentation/xxx_Tests/test_presentation.py 2005-01-31 20:53:55 UTC (rev 29005)
+++ Zope3/branches/srichter-blow-services/src/zope/app/presentation/tests/test_presentation.py 2005-02-04 17:57:38 UTC (rev 29041)
@@ -0,0 +1,258 @@
+##############################################################################
+#
+# 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.
+#
+##############################################################################
+"""Test the presentation module
+
+$Id$
+"""
+import unittest
+
+import zope.interface
+from zope.component.exceptions import ComponentLookupError
+from zope.configuration.exceptions import ConfigurationError
+from zope.interface.verify import verifyObject
+from zope.proxy import removeAllProxies
+from zope.publisher.browser import TestRequest
+from zope.publisher.interfaces.browser import IBrowserRequest
+from zope.testing.doctestunit import DocTestSuite
+
+from zope.app import zapi
+from zope.app.annotation.interfaces import IAttributeAnnotatable
+from zope.app.component.interfaces.registration import IRegistered
+from zope.app.component.testing import PlacefulSetup
+from zope.app.container.contained import contained, uncontained, setitem
+from zope.app.container.interfaces import IContained, ILocation
+from zope.app.container.interfaces import IObjectAddedEvent
+from zope.app.container.interfaces import IObjectRemovedEvent
+from zope.app.dependable import Dependable
+from zope.app.dependable.interfaces import IDependable
+from zope.app.folder import rootFolder
+from zope.app.module import resolve
+from zope.app.module.manager import ModuleManager
+from zope.app.module.interfaces import IModuleManager
+from zope.app.presentation.interfaces import IPageRegistration
+from zope.app.presentation.interfaces import IZPTTemplate
+from zope.app.presentation.registration import PageRegistration
+from zope.app.presentation.registration import BoundTemplate
+from zope.app.presentation.registration import PageRegistrationAddSubscriber
+from zope.app.presentation.registration import PageRegistrationRemoveSubscriber
+from zope.app.testing import ztapi, setup
+from zope.app.testing.placelesssetup import setUp, tearDown
+from zope.app.traversing.api import traverse
+from zope.app.traversing.interfaces import IPhysicallyLocatable
+
+
+class I1(zope.interface.Interface):
+ pass
+
+class I1E(I1):
+ pass
+
+I2 = IBrowserRequest
+
+class I3(zope.interface.Interface):
+ pass
+
+class I4(zope.interface.Interface):
+ pass
+
+
+class Registration(object):
+ required = I1
+ requestType = I2
+ name = 'test'
+ layer = 'default'
+ provided = zope.interface.Interface
+
+ with = property(lambda self: (self.requestType, ))
+ factories = property(lambda self: (self.factory, ))
+
+ def __repr__(self):
+ return 'Registration(%s)' % self.factory.__name__
+
+class C(object): pass
+
+class PhonyTemplate(object):
+ __name__ = __parent__ = None
+ zope.interface.implements(IZPTTemplate, IDependable, IRegistered)
+
+ _dependents = ()
+
+ def addDependent(self, location):
+ self._dependents = tuple(
+ [d for d in self._dependents if d != location]
+ +
+ [location]
+ )
+
+ def removeDependent(self, location):
+ self._dependents = tuple(
+ [d for d in self._dependents if d != location]
+ )
+
+ def dependents(self):
+ return self._dependents
+
+
+source = '''
+from zope.app.presentation.tests.test_presentation import PhonyTemplate
+
+class A(object):
+ def __init__(self, object, request):
+ self.context = object
+ self.request = request
+
+ run = PhonyTemplate()
+'''
+
+class PhonyPathAdapter(object):
+ zope.interface.implements(IPhysicallyLocatable)
+
+ def __init__(self, context):
+ self.context = context
+
+ def getPath(self):
+ return self.context.__name__
+
+ def getRoot(self):
+ root = self.context
+ while root.__parent__ is not None:
+ root = root.__parent__
+ return root
+
+
+class Folder(object):
+
+ zope.interface.implements(IContained)
+
+ __parent__ = __name__ = None
+
+ def __init__(self):
+ self._dict = {}
+
+ def __setitem__(self, key, ob):
+ setitem(self, self.__setitem, key, ob)
+
+ def __setitem(self, key, ob):
+ self._dict[key] = ob
+
+ def get(self, key, default=None):
+ return self._dict.get(key, default)
+
+
+class TestPageRegistration(PlacefulSetup, unittest.TestCase):
+
+ def setUp(self):
+ PlacefulSetup.setUp(self)
+ self.rootFolder = rootFolder()
+ setup.createSiteManager(self.rootFolder)
+ default = self.rootFolder.getSiteManager()['default']
+ self.__template = PhonyTemplate()
+ default['t'] = self.__template
+ ztapi.provideUtility(IModuleManager, ModuleManager(source), 'Foo.Bar')
+ folder = contained(Folder(), self.rootFolder)
+ self.folder = contained(Folder(), folder)
+
+ def test_factories_template(self):
+ registration = contained(
+ PageRegistration(I1, 'test', 'zope.View',
+ "Foo.Bar.A",
+ template=self.__template,
+ ),
+ self.folder,
+ )
+
+ c = C()
+ request = TestRequest()
+ factory = registration.component
+ view = factory(c, request)
+ self.assertEqual(view.__class__, BoundTemplate)
+ self.assertEqual(removeAllProxies(view).template, self.__template)
+
+ view = removeAllProxies(view).view
+ self.assert_(issubclass(view.__class__, resolve('Foo.Bar.A')))
+ self.assertEqual(view.context, c)
+ self.assertEqual(view.request, request)
+ self.assertEqual(registration.required, I1)
+ self.assertEqual(registration.requestType, I2)
+
+ def test_factories_attribute(self):
+ registration = contained(
+ PageRegistration(
+ I1, 'test', 'zope.View', "Foo.Bar.A", attribute='run'),
+ self.folder,6
+ )
+ c = C()
+ request = TestRequest()
+ factory = registration.component
+ view = factory(c, request)
+ self.assertEquals(view, resolve('Foo.Bar.A').run)
+
+ def test_factories_errors(self):
+ registration = contained(
+ PageRegistration(I1, 'test', 'zope.View', "Foo.Bar.A"),
+ self.folder,
+ )
+ c = C()
+ request = TestRequest()
+ self.assertRaises(ConfigurationError, lambda: registration.component)
+ registration.template = self.__template
+ registration.attribute = 'run'
+ self.assertRaises(ConfigurationError, lambda: registration.component)
+
+ def test_registerAddSubscriber_template(self):
+ ztapi.provideAdapter(ILocation, IPhysicallyLocatable,
+ PhonyPathAdapter)
+ ztapi.handle((IPageRegistration, IObjectAddedEvent),
+ PageRegistrationAddSubscriber)
+ registration = PageRegistration(I1, 'test', 'zope.View', "Foo.Bar.A",
+ template=self.__template)
+
+ # Test add event
+ self.folder['test'] = registration
+ dependents = IDependable(self.__template)
+ self.assert_('test' in dependents.dependents())
+
+ def test_registerRemoveSubscriber_template(self):
+ ztapi.provideAdapter(ILocation, IPhysicallyLocatable,
+ PhonyPathAdapter)
+ ztapi.handle((IPageRegistration, IObjectRemovedEvent),
+ PageRegistrationRemoveSubscriber)
+ registration = PageRegistration(I1, 'test', 'zope.View', "Foo.Bar.A",
+ template=self.__template)
+
+ # Test remove event
+ self.folder['test'] = registration
+ uncontained(registration, self.folder, 'test')
+ dependents = IDependable(self.__template)
+ self.assert_('test' not in dependents.dependents())
+
+ def test_addremoveNotify_attribute(self):
+ ztapi.provideAdapter(ILocation, IPhysicallyLocatable,
+ PhonyPathAdapter)
+ registration = PageRegistration(I1, 'test', 'zope.View',
+ "Foo.Bar.A", attribute='run')
+ # Just add and remove registration to see that no errors occur
+ self.folder['test'] = registration
+ uncontained(registration, self.folder, 'test')
+
+
+def test_suite():
+ return unittest.TestSuite((
+ unittest.makeSuite(TestPageRegistration),
+ ))
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='test_suite')
+
+
Modified: Zope3/branches/srichter-blow-services/src/zope/app/presentation/tests/test_zpt.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/presentation/xxx_Tests/test_zpt.py 2005-01-13 16:28:47 UTC (rev 28825)
+++ Zope3/branches/srichter-blow-services/src/zope/app/presentation/tests/test_zpt.py 2005-02-04 17:57:38 UTC (rev 29041)
@@ -15,20 +15,18 @@
$Id$
"""
-from unittest import TestCase, TestSuite, makeSuite
+import unittest
+import zope.interface
+from zope.publisher.browser import TestRequest
+
from zope.app.presentation.zpt import ZPTTemplate, ZPTFactory
from zope.app.presentation.zpt import ReadFile, WriteFile
-from zope.publisher.browser import TestRequest
from zope.app.publisher.browser import BrowserView
# All this just to get zapi.getPath() work :(
-from zope.app.testing import ztapi
-from zope.interface import directlyProvides
+from zope.app.testing import ztapi, setup
from zope.app.testing.placelesssetup import PlacelessSetup
-from zope.app.traversing.interfaces import IPhysicallyLocatable
from zope.app.traversing.interfaces import IContainmentRoot
-from zope.app.location.traversing import LocationPhysicallyLocatable
-from zope.app.traversing.adapters import RootPhysicallyLocatable
from zope.app.container.contained import contained
@@ -36,7 +34,7 @@
pass
-class Test(TestCase):
+class ZPTTemplateTest(unittest.TestCase):
# TODO: We need tests for the template class itself and for the
# SearchableText adapter.
@@ -70,15 +68,18 @@
self.assertEqual(template.source, source)
-class TestDebugFlags(PlacelessSetup, TestCase):
+class TestDebugFlags(PlacelessSetup, unittest.TestCase):
def setUp(self):
PlacelessSetup.setUp(self)
- ztapi.provideAdapter(
- None, IPhysicallyLocatable, LocationPhysicallyLocatable)
- ztapi.provideAdapter(
- IContainmentRoot, IPhysicallyLocatable, RootPhysicallyLocatable)
+ setup.setUpTraversal()
+ def pageInContext(self, page):
+ root = Data()
+ zope.interface.directlyProvides(root, IContainmentRoot)
+ folder = contained(Data(), root, name='folder')
+ return contained(page, folder, name='zpt')
+
def test_source_file(self):
template = ZPTTemplate()
self.assert_(template.pt_source_file() is None)
@@ -86,12 +87,6 @@
template = self.pageInContext(template)
self.assertEquals(template.pt_source_file(), '/folder/zpt')
- def pageInContext(self, page):
- root = Data()
- directlyProvides(root, IContainmentRoot)
- folder = contained(Data(), root, name='folder')
- return contained(page, folder, name='zpt')
-
def test_debug_flags(self):
template = self.pageInContext(ZPTTemplate())
template.source = u'<tal:p>Test</tal:p>'
@@ -114,7 +109,10 @@
def test_suite():
- return TestSuite((
- makeSuite(Test),
- makeSuite(TestDebugFlags),
+ return unittest.TestSuite((
+ unittest.makeSuite(ZPTTemplateTest),
+ unittest.makeSuite(TestDebugFlags),
))
+
+if __name__=='__main__':
+ unittest.main(defaultTest='test_suite')
Modified: Zope3/branches/srichter-blow-services/src/zope/app/presentation/zpt.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/presentation/zpt.py 2005-02-04 17:55:08 UTC (rev 29040)
+++ Zope3/branches/srichter-blow-services/src/zope/app/presentation/zpt.py 2005-02-04 17:57:38 UTC (rev 29041)
@@ -16,64 +16,28 @@
$Id$
"""
__docformat__ = 'restructuredtext'
-
+import persistent
import re
-from zope.security.proxy import ProxyFactory
-from persistent import Persistent
-from zope.interface import Interface, implements
-from zope.schema import Text, BytesLine, Bool
+import zope.interface
+import zope.security.proxy
+from zope.pagetemplate.pagetemplate import PageTemplate
-from zope.app.container.contained import Contained
+import zope.app.filerepresentation.interfaces
+
+from zope.app import zapi
from zope.app.component.interfaces.registration import IRegisterable
-from zope.fssync.server.entryadapter import ObjectEntryAdapter, AttrMapping
-from zope.fssync.server.interfaces import IObjectFile
-from zope.app.filerepresentation.interfaces import IReadFile, IWriteFile
-from zope.app.filerepresentation.interfaces import IFileFactory
+from zope.app.container.contained import Contained
from zope.app.pagetemplate.engine import AppPT
-from zope.pagetemplate.pagetemplate import PageTemplate
-from zope.app import zapi
-class IZPTInfo(Interface):
- """ZPT Template configuration information
- """
+import interfaces
- contentType = BytesLine(
- title=u'Content type of generated output',
- required=True,
- default='text/html'
- )
+class ZPTTemplate(AppPT, PageTemplate, persistent.Persistent, Contained):
- source = Text(
- title=u"Source",
- description=u"""The source of the page template.""",
- required=True)
+ zope.interface.implements(interfaces.IZPTTemplate)
- expand = Bool(
- title=u"Expand macros",
- )
-
-class IZPTTemplate(IZPTInfo, IRegisterable):
- """ZPT Templates for use in views"""
-
- def render(context, request, *args, **kw):
- """Render the page template.
-
- The context argument is bound to the top-level `context`
- variable. The request argument is bound to the top-level
- `request` variable. The positional arguments are bound to the
- `args` variable and the keyword arguments are bound to the
- `options` variable.
-
- """
-
-class ZPTTemplate(AppPT, PageTemplate, Persistent, Contained):
-
- implements(IZPTTemplate)
-
contentType = 'text/html'
expand = False
- usage = u''
def getSource(self):
"""See `zope.app.presentation.zpt.IZPTInfo`"""
@@ -85,9 +49,8 @@
raise TypeError("source text must be Unicode" , text)
self.pt_edit(text, self.contentType)
- # See zope.app.presentation.zpt.IZPTInfo
- source = property(getSource, setSource, None,
- """Source of the Page Template.""")
+ # See zope.app.presentation.interfaces.IZPTInfo
+ source = property(getSource, setSource)
def pt_getContext(self, view, **_kw):
# instance is a View component
@@ -106,27 +69,22 @@
def render(self, view, *args, **keywords):
if args:
- args = ProxyFactory(args)
+ args = zope.security.proxy.ProxyFactory(args)
- if self.usage:
- if "template_usage" not in keywords:
- kw = {'template_usage': self.usage}
- kw.update(keywords)
- keywords = kw
+ kw = zope.security.proxy.ProxyFactory(keywords)
- kw = ProxyFactory(keywords)
-
namespace = self.pt_getContext(view, args=args, options=kw)
debug_flags = view.request.debug
return self.pt_render(namespace, showtal=debug_flags.showTAL,
sourceAnnotations=debug_flags.sourceAnnotations)
-# Adapters for file-system emulation
+# Adapters for file-system emulation
class ReadFile(object):
- implements(IReadFile)
+ zope.interface.implements(
+ zope.app.filerepresentation.interfaces.IReadFile)
def __init__(self, context):
self.context = context
@@ -140,7 +98,8 @@
class WriteFile(object):
- implements(IWriteFile)
+ zope.interface.implements(
+ zope.app.filerepresentation.interfaces.IWriteFile)
def __init__(self, context):
self.context = context
@@ -151,30 +110,13 @@
class ZPTFactory(object):
- implements(IFileFactory)
+ zope.interface.implements(
+ zope.app.filerepresentation.interfaces.IFileFactory)
def __init__(self, context):
self.context = context
def __call__(self, name, content_type, data):
- r = ZPTTemplate()
- r.source = data
- return r
-
-
-class ZPTPageAdapter(ObjectEntryAdapter):
- """ObjectFile adapter for `ZPTTemplate` objects."""
-
- implements(IObjectFile)
-
- def getBody(self):
- return self.context.source
-
- def setBody(self, data):
- # Convert the data to Unicode, since that's what ZPTTemplate
- # wants; it's normally read from a file so it'll be bytes.
- # The default encoding in Zope is UTF-8.
- self.context.source = data.decode('UTF-8')
-
- def extra(self):
- return AttrMapping(self.context, ('contentType', 'expand'))
+ template = ZPTTemplate()
+ template.source = data
+ return template
Deleted: Zope3/branches/srichter-blow-services/src/zope/app/presentation/zpt.zcml
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/presentation/zpt.zcml 2005-02-04 17:55:08 UTC (rev 29040)
+++ Zope3/branches/srichter-blow-services/src/zope/app/presentation/zpt.zcml 2005-02-04 17:57:38 UTC (rev 29041)
@@ -1,48 +0,0 @@
-<configure
- xmlns="http://namespaces.zope.org/zope"
- xmlns:event="http://namespaces.zope.org/event"
- xmlns:fssync="http://namespaces.zope.org/fssync"
- >
-
-<!-- Page Templates -->
-
-<content class=".zpt.ZPTTemplate">
- <factory
- title="zope.app.ZPTTemplate"
- description="Persistent View Page Template"
- />
- <require
- permission="zope.View"
- attributes="__call__"
- />
- <require
- permission="zope.ManageServices"
- interface=".zpt.IZPTTemplate"
- set_schema=".zpt.IZPTTemplate"
- />
- <implements
- interface="zope.app.annotation.interfaces.IAttributeAnnotatable"
- />
-</content>
-
-<adapter
- for=".zpt.IZPTTemplate"
- provides="zope.app.filerepresentation.interfaces.IReadFile"
- factory=".zpt.ReadFile"
- permission="zope.ManageServices"
- />
-
-<adapter
- for=".zpt.IZPTTemplate"
- provides="zope.app.filerepresentation.interfaces.IWriteFile"
- factory=".zpt.WriteFile"
- permission="zope.ManageServices"
- />
-
-<!-- Filesystem synchronization support -->
-<fssync:adapter
- class=".zpt.ZPTTemplate"
- factory=".zpt.ZPTPageAdapter"
- />
-
-</configure>
More information about the Zope3-Checkins
mailing list