[Zope-Checkins]
SVN: Products.Five/branches/philikon-local-components/component/
Unregister locally defined views when the corresponding
PageTemplate object
Philipp von Weitershausen
philikon at philikon.de
Sat Mar 4 19:32:56 EST 2006
Log message for revision 65814:
Unregister locally defined views when the corresponding PageTemplate object
is deleted. We do that using an event subscriber which is very elegant (thanks
for making this available in Zope 2.9, Florent!).
Changed:
U Products.Five/branches/philikon-local-components/component/browser.py
U Products.Five/branches/philikon-local-components/component/configure.zcml
U Products.Five/branches/philikon-local-components/component/zpt.py
U Products.Five/branches/philikon-local-components/component/zpt.txt
-=-
Modified: Products.Five/branches/philikon-local-components/component/browser.py
===================================================================
--- Products.Five/branches/philikon-local-components/component/browser.py 2006-03-05 00:31:08 UTC (rev 65813)
+++ Products.Five/branches/philikon-local-components/component/browser.py 2006-03-05 00:32:56 UTC (rev 65814)
@@ -21,7 +21,7 @@
from Products.Five.browser import BrowserView
from Products.Five.component import enableSite, disableSite, findSite
from Products.Five.component.interfaces import IObjectManagerSite
-from Products.Five.component.zpt import ZPTViewFactory
+from Products.Five.component.zpt import ZPTViewFactory, IRegisteredViewPageTemplate
from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate
import zope.interface
@@ -104,6 +104,7 @@
zpt_id = os.path.basename(template.filename)
viewzpt = ZopePageTemplate(zpt_id, template.read())
+ zope.interface.alsoProvides(viewzpt, IRegisteredViewPageTemplate)
site._setObject(zpt_id, viewzpt) #XXXthere could be a naming conflict
components = site.getSiteManager()
Modified: Products.Five/branches/philikon-local-components/component/configure.zcml
===================================================================
--- Products.Five/branches/philikon-local-components/component/configure.zcml 2006-03-05 00:31:08 UTC (rev 65813)
+++ Products.Five/branches/philikon-local-components/component/configure.zcml 2006-03-05 00:32:56 UTC (rev 65814)
@@ -42,4 +42,6 @@
</browser:pages>
+ <subscriber handler=".zpt.unregisterViewWhenZPTIsDeleted" />
+
</configure>
Modified: Products.Five/branches/philikon-local-components/component/zpt.py
===================================================================
--- Products.Five/branches/philikon-local-components/component/zpt.py 2006-03-05 00:31:08 UTC (rev 65813)
+++ Products.Five/branches/philikon-local-components/component/zpt.py 2006-03-05 00:32:56 UTC (rev 65814)
@@ -18,10 +18,22 @@
from Acquisition import aq_inner, aq_acquire
from Products.PageTemplates.Expressions import SecureModuleImporter
from Products.Five.browser import BrowserView
+from Products.Five.component import findSite
import zope.component
import zope.interface
+from zope.pagetemplate.interfaces import IPageTemplate
+from zope.app.container.interfaces import IObjectRemovedEvent
+class IZPTViewFactory(zope.interface.Interface):
+ """Marker interface for those view factories that invoke locally
+ registered components.
+
+ By finding factories that provide this interface we can find the
+ registration object for a locally registered template and, for
+ example, unregister the view when the template is deleted."""
+ template = zope.interface.Attribute("The ZPT template to invoke.")
+
class ZPTViewFactory(object):
"""View factory that gets registered with a local component
registry.
@@ -31,6 +43,7 @@
persistent) reference only to the Page Template, everything else
needed for the template (e.g. its view class) is constructed by
the view."""
+ zope.interface.implements(IZPTViewFactory)
def __init__(self, template, name):
self.template = template
@@ -84,3 +97,17 @@
kwargs['args'] = args
namespace['options'] = kwargs
return self.template.pt_render(namespace)
+
+class IRegisteredViewPageTemplate(IPageTemplate):
+ """Marker interface for registered view page templates
+ """
+
+ at zope.component.adapter(IRegisteredViewPageTemplate, IObjectRemovedEvent)
+def unregisterViewWhenZPTIsDeleted(zpt, event):
+ components = zope.component.getSiteManager(zpt)
+ for reg in components.registeredAdapters():
+ if (IZPTViewFactory.providedBy(reg.factory) and
+ reg.factory.template == zpt):
+ break
+ components.unregisterAdapter(reg.factory, reg.required, reg.provided,
+ reg.name)
Modified: Products.Five/branches/philikon-local-components/component/zpt.txt
===================================================================
--- Products.Five/branches/philikon-local-components/component/zpt.txt 2006-03-05 00:31:08 UTC (rev 65813)
+++ Products.Five/branches/philikon-local-components/component/zpt.txt 2006-03-05 00:32:56 UTC (rev 65814)
@@ -25,9 +25,11 @@
>>> from Products.Five import zcml
>>> import Products.Five.component
+ >>> import zope.app.event
>>> zcml.load_config('meta.zcml', Products.Five)
>>> zcml.load_config('permissions.zcml', Products.Five)
>>> zcml.load_config('configure.zcml', Products.Five.component)
+ >>> zcml.load_config('configure.zcml', zope.app.event)
We should also create a root object:
@@ -175,6 +177,28 @@
<BLANKLINE>
+5. Deleting view templates
+--------------------------
+
+Once in a while we would like to get rid of the customized view. The
+easiest way to do that is to simply delete the template:
+
+ >>> if True:
+ ... site._delObject('customizetemplate.pt')
+
+Now the view look-up is back to the old way:
+
+ >>> view = zope.component.getMultiAdapter((item, request),
+ ... name=u"customizetemplate.html")
+ >>> print view.index.read() #doctest: +ELLIPSIS
+ <html metal:use-macro="context/@@standard_macros/view"
+ i18n:domain="zope">
+ ...
+ <p i18n:translate="">This is the source of the
+ <code tal:content="request/form/viewname">viewname</code>:</p>
+ ...
+
+
Clean up:
---------
More information about the Zope-Checkins
mailing list