Log message for revision 67584: get rid of zpt customization prototype. it won't be ready in time for Five 1.5/Zope2.10
Changed: U Products.Five/branches/philikon-local-components/component/browser.py U Products.Five/branches/philikon-local-components/component/component.txt U Products.Five/branches/philikon-local-components/component/components.pt U Products.Five/branches/philikon-local-components/component/configure.zcml D Products.Five/branches/philikon-local-components/component/customizezpt.pt U Products.Five/branches/philikon-local-components/component/tests.py D Products.Five/branches/philikon-local-components/component/zpt.py D Products.Five/branches/philikon-local-components/component/zpt.txt D Products.Five/branches/philikon-local-components/component/zptviews.pt -=- Modified: Products.Five/branches/philikon-local-components/component/browser.py =================================================================== --- Products.Five/branches/philikon-local-components/component/browser.py 2006-04-25 08:46:29 UTC (rev 67583) +++ Products.Five/branches/philikon-local-components/component/browser.py 2006-04-25 08:49:16 UTC (rev 67584) @@ -15,26 +15,14 @@ $Id$ """ -import os.path - -from Acquisition import aq_inner from Products.Five.browser import BrowserView -from Products.Five.component import enableSite, disableSite, findSite +from Products.Five.component import enableSite, disableSite from Products.Five.component.interfaces import IObjectManagerSite -from Products.Five.component.zpt import ZPTViewFactory, IRegisteredViewPageTemplate -from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate -import zope.interface -import zope.component -import zope.dottedname.resolve -from zope.component.globalregistry import base from zope.component.persistentregistry import PersistentComponents -from zope.publisher.interfaces.browser import IBrowserRequest -from zope.traversing.browser import absoluteURL from zope.app.component.hooks import clearSite -from zope.app.apidoc.presentation import getViews -class ComponentsView(BrowserView): +class ObjectManagerSiteView(BrowserView): def update(self): form = self.request.form @@ -72,114 +60,3 @@ clearSite() self.context.setSiteManage(None) - -def mangleAbsoluteFilename(filename): - """ - Mangle an absolute filename when the file happens to be in a - package. The mangled name will then be of the form:: - - <dotted package name>/<base filename>. - - For example, let's take Five's configure.zcml as an example. We - assemble it in an OS-independent way so this test works on all - platforms: - - >>> def filesystemPath(*elements): - ... return os.path.sep.join(elements) - - We see that the filename is now mangled: - - >>> mangleAbsoluteFilename(filesystemPath( - ... '', 'path', 'to', 'Products', 'Five', 'configure.zcml')) - 'Products.Five/configure.zcml' - - The name of a file that's not in a package is returned unchanged: - - >>> not_in_a_package = filesystemPath('', 'path', 'to', 'configure.zcml') - >>> mangleAbsoluteFilename(not_in_a_package) == not_in_a_package - True - """ - if not os.path.isabs(filename): - raise ValueError("Can only determine package for absolute filenames") - dir, basename = os.path.split(filename) - pieces = dir.split(os.path.sep) - if pieces[0] == '': - pieces = pieces[1:] - while pieces: - try: - zope.dottedname.resolve.resolve('.'.join(pieces)) - break - except ImportError: - pieces = pieces[1:] - if not pieces: - return filename - return '.'.join(pieces) + '/' + basename - -class CustomizationView(BrowserView): - - def templateViewRegistrations(self): - for reg in getViews(zope.interface.providedBy(self.context), - IBrowserRequest): - factory = reg.factory - while hasattr(factory, 'factory'): - factory = factory.factory - #XXX this should really be dealt with using a marker interface - # on the view factory - if hasattr(factory, '__name__') and \ - factory.__name__.startswith('SimpleViewClass'): - yield reg - - def templateViewRegInfo(self): - def regkey(reg): - return reg.name - for reg in sorted(self.templateViewRegistrations(), key=regkey): - yield { - 'viewname': reg.name, - 'for': reg.required[0].__identifier__, - 'type': reg.required[1].__identifier__, - 'zptfile': mangleAbsoluteFilename(reg.factory.index.filename), - 'zcmlfile': mangleAbsoluteFilename(reg.info.file) - } - - def templateFromViewname(self, viewname): - view = zope.component.getMultiAdapter((self.context, self.request), - name=viewname) - return view.index - - def doCustomizeTemplate(self, viewname): - # find the nearest site - site = findSite(self.context, IObjectManagerSite) - if site is None: - raise TypeError("No site found") #TODO find right exception - - # we're using the original filename of the template, not the - # view name to avoid potential conflicts and/or confusion in - # URLs - template = self.templateFromViewname(viewname) - 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() - - # find out the view registration object so we can get at the - # provided and required interfaces - for reg in getViews(zope.interface.providedBy(self.context), - IBrowserRequest): - if reg.name == viewname: - break - - view_factory = ZPTViewFactory(viewzpt, viewname) - components.registerAdapter(view_factory, required=reg.required, - provided=reg.provided, name=viewname) #XXX info? - - viewzpt = getattr(site, zpt_id) - return viewzpt - - def customizeTemplate(self, viewname): - viewzpt = self.doCustomizeTemplate(viewname) - # to get a "direct" URL we use aq_inner for a straight - # acquisition chain - url = absoluteURL(aq_inner(viewzpt), self.request) + "/manage_workspace" - self.request.RESPONSE.redirect(url) Modified: Products.Five/branches/philikon-local-components/component/component.txt =================================================================== --- Products.Five/branches/philikon-local-components/component/component.txt 2006-04-25 08:46:29 UTC (rev 67583) +++ Products.Five/branches/philikon-local-components/component/component.txt 2006-04-25 08:49:16 UTC (rev 67584) @@ -67,6 +67,5 @@ Clean up: --------- -#XXX somehow this makes the zpt.txt tests fail -# >>> from zope.component.testing import tearDown -# >>> tearDown() + >>> from zope.component.testing import tearDown + >>> tearDown() Modified: Products.Five/branches/philikon-local-components/component/components.pt =================================================================== --- Products.Five/branches/philikon-local-components/component/components.pt 2006-04-25 08:46:29 UTC (rev 67583) +++ Products.Five/branches/philikon-local-components/component/components.pt 2006-04-25 08:49:16 UTC (rev 67584) @@ -18,11 +18,6 @@ </div> </form> - <p tal:condition="not:view/isSite">XXX perhaps list locally - registered comonents here, or just give some stats about locally - registered objects with links to pages who actually show them... - XXX</p> - </div> </body> Modified: Products.Five/branches/philikon-local-components/component/configure.zcml =================================================================== --- Products.Five/branches/philikon-local-components/component/configure.zcml 2006-04-25 08:46:29 UTC (rev 67583) +++ Products.Five/branches/philikon-local-components/component/configure.zcml 2006-04-25 08:49:16 UTC (rev 67584) @@ -17,31 +17,9 @@ <browser:page for="OFS.interfaces.IObjectManager" name="components.html" - class=".browser.ComponentsView" + class=".browser.ObjectManagerSiteView" template="components.pt" permission="five.ManageSite" /> - <browser:pages - for="OFS.interfaces.ISimpleItem" - class=".browser.CustomizationView" - permission="five.ManageSite"> - - <browser:page - name="zptviews.html" - template="zptviews.pt" - /> - <browser:page - name="customizezpt.html" - template="customizezpt.pt" - /> - <browser:page - name="customizezpt" - attribute="customizeTemplate" - /> - - </browser:pages> - - <subscriber handler=".zpt.unregisterViewWhenZPTIsDeleted" /> - </configure> Deleted: Products.Five/branches/philikon-local-components/component/customizezpt.pt =================================================================== --- Products.Five/branches/philikon-local-components/component/customizezpt.pt 2006-04-25 08:46:29 UTC (rev 67583) +++ Products.Five/branches/philikon-local-components/component/customizezpt.pt 2006-04-25 08:49:16 UTC (rev 67584) @@ -1,26 +0,0 @@ -<html metal:use-macro="context/@@standard_macros/view" - i18n:domain="zope"> - <body> - <div metal:fill-slot="body"> - - <p i18n:translate="">This is the source of the - <code tal:content="request/form/viewname">viewname</code>:</p> - - <pre style="background-color: #cccccc; border: 1px solid black; padding: 5px;" - tal:content="python:view.templateFromViewname(request.form['viewname']).read()"> - template source - </pre> - - <form action="@@customizezpt" method="post" - enctype="multipart/form-data"> - - <input type="hidden" name="viewname" value="theviewname" - tal:attributes="value request/form/viewname" /> - <input type="submit" name="" value="Customize" /> - - </form> - - </div> - </body> - -</html> Modified: Products.Five/branches/philikon-local-components/component/tests.py =================================================================== --- Products.Five/branches/philikon-local-components/component/tests.py 2006-04-25 08:46:29 UTC (rev 67583) +++ Products.Five/branches/philikon-local-components/component/tests.py 2006-04-25 08:49:16 UTC (rev 67584) @@ -23,8 +23,6 @@ def test_suite(): return unittest.TestSuite([ DocFileSuite('component.txt', package="Products.Five.component"), - DocFileSuite('zpt.txt', package="Products.Five.component"), - DocTestSuite('Products.Five.component.browser') ]) if __name__ == '__main__': Deleted: Products.Five/branches/philikon-local-components/component/zpt.py =================================================================== --- Products.Five/branches/philikon-local-components/component/zpt.py 2006-04-25 08:46:29 UTC (rev 67583) +++ Products.Five/branches/philikon-local-components/component/zpt.py 2006-04-25 08:49:16 UTC (rev 67584) @@ -1,113 +0,0 @@ -############################################################################## -# -# Copyright (c) 2006 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. -# -############################################################################## -"""Component browser views - -$Id$ -""" -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. - - When this factory is invoked, it returns a view that in turn - invokes the template upon publishing. We hold a (potentially - 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 - self.name = name - - def __call__(self, context, request): - return ZPTView(self.template, self.name, context, request) - -class ZPTView(BrowserView): - """View that invokes a locally placed ZopePageTemplate object. - """ - - def __init__(self, template, name, context, request): - self.template = template - self.context = context - self.request = request - - # this is needed for Zope 2's publication which wants to - # record some metadata in the transaction, among others the - # name of published objects - self.__name__ = name - - def _findViewClass(self): - #XXX we might want to walk up to the next site instead, not - # just go to the global one directly - gsm = zope.component.getGlobalSiteManager() - view = gsm.queryMultiAdapter((self.context, self.request), - zope.interface.Interface, self.__name__) - if view is not None: - return view - return self - - def _zptNamespace(self): - root = aq_acquire(self.context, 'getPhysicalRoot')() - here = aq_inner(self.context) - return { - 'template': self.template, - 'nothing': None, - 'request': self.request, - 'here': here, - 'context': here, - 'container': here, - 'view': self._findViewClass(), - 'root': root, - 'modules': SecureModuleImporter, - } - - def __call__(self, *args, **kwargs): - namespace = self._zptNamespace() - if not kwargs.has_key('args'): - kwargs['args'] = args - namespace['options'] = kwargs - return self.template.pt_render(namespace) - -class IRegisteredViewPageTemplate(IPageTemplate): - """Marker interface for registered view page templates - """ - [EMAIL PROTECTED](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) Deleted: Products.Five/branches/philikon-local-components/component/zpt.txt =================================================================== --- Products.Five/branches/philikon-local-components/component/zpt.txt 2006-04-25 08:46:29 UTC (rev 67583) +++ Products.Five/branches/philikon-local-components/component/zpt.txt 2006-04-25 08:49:16 UTC (rev 67584) @@ -1,207 +0,0 @@ -Locally customizing template-based views -======================================== - -This document describes a typical story of locally customizing a -global view component. The steps in this story are: - -1. Making a folder a site - -2. Walking up to an object and getting a list of its template-based - views - -3. Selecting a particular view, seeing its template source and - deciding to customize it - -4. Customizing the template and seeing the customized template take - effect - -5. Deleting the template and seeing the old view take over again - - -Setup ------ - -Before we can start we need to load some important ZCML: - - >>> 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('traversing.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: - - >>> from OFS.Application import Application - >>> root = Application() - - -1. Turning an ObjectManager into a site ----------------------------------------- - -Let's create a folder that we'll turn into a Zope3-style site: - - >>> from OFS.ObjectManager import ObjectManager - >>> site = ObjectManager() - -We need to add it to the root so that objects contained in it have a -proper acquisition chain all the way to the top: - - >>> id = root._setObject('site', site) - >>> site = root.site - -Now we make this a real site by using a view that a) sets -``IObjectManagerSite``, b) sets a traversal hook and c) gives the site -a component registration object (formerly known as site manager): - - >>> import zope.component - >>> from zope.publisher.browser import TestRequest - >>> request = TestRequest() - >>> view = zope.component.getMultiAdapter((site, request), - ... name=u"components.html") - >>> view.makeSite() - -Now the site provides ``IObjectManagerSite``: - - >>> from Products.Five.component.interfaces import IObjectManagerSite - >>> IObjectManagerSite.providedBy(site) - True - -And it has a site manager (component registry): - - >>> site.getSiteManager() #doctest: +ELLIPSIS - <zope.component.persistentregistry.PersistentComponents object at ...> - - -2. Template-based views available on an object ----------------------------------------------- - -Let's create a simple content object that we put into the folder -(a.k.a. the site): - - >>> from Products.Five.tests.testing.simplecontent import SimpleContent - >>> item = SimpleContent('item', 'An item') - >>> site._setOb('item', item) - >>> item = site.item - -Let's get a list of views (that also shows where each view is -registered at): - - >>> view = zope.component.getMultiAdapter((item, request), - ... name=u"zptviews.html") - >>> view = view.__of__(item) - >>> from pprint import pprint - >>> viewnames = [reg.name for reg in view.templateViewRegistrations()] - >>> viewnames.sort() - >>> pprint(viewnames) - [u'customizezpt.html', u'zptviews.html'] - - -3. and 4. Customizing a template-based view -------------------------------------------- - -In the list of template-based browser views we can select one and see -the source of its template: - - >>> view = zope.component.getMultiAdapter((item, request), - ... name=u"customizezpt.html") - >>> view = view.__of__(item) - >>> template = view.templateFromViewname(u'customizezpt.html') - >>> import os.path - >>> os.path.basename(template.filename) - 'customizezpt.pt' - - >>> print template.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> - ... - -We now hit the customize button and get a customized ZPT template: - - >>> zpt = view.doCustomizeTemplate(u'customizezpt.html') - -That actually creates a PageTemplate object in the nearest site -(perhaps later we'd like to have the option to pick which of the sites -above us should be targeted) - - >>> zpt = getattr(site, 'customizezpt.pt') - >>> print zpt.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> - ... - -It also registers this component as a view now, so when we look up the -view again, we get the customized one. Therefore let us actually -change the template to give us some info output: - - >>> zpt.pt_edit(""" - ... context: <tal:var replace="structure context" /> - ... container: <tal:var replace="structure container" /> - ... root: <tal:var replace="structure root" /> - ... template: <tal:var replace="structure nocall:template" /> - ... request: <tal:var replace="structure python:repr(request)" /> - ... view: <tal:var replace="structure nocall:view" /> - ... modules: <tal:var replace="structure modules" /> - ... options: <tal:var replace="structure options" /> - ... nothing: <tal:var replace="structure nothing" /> - ... """, content_type=None) - -In order to be able to look up the customized view now, we need to -make the site the current site: - - >>> from zope.app.component.hooks import setSite - >>> setSite(site) - -Now look it up and compare its output: - - >>> view = zope.component.getMultiAdapter((item, request), - ... name=u"customizezpt.html") - >>> view = view.__of__(item) - >>> print view() #doctest: +ELLIPSIS - context: <SimpleContent at item> - container: <SimpleContent at item> - root: <Application at > - template: <ZopePageTemplate at customizezpt.pt> - request: <zope.publisher.browser.TestRequest instance URL=http://127.0.0.1> - view: <Products.Five.metaclass.SimpleViewClass from .../Five/component/customizezpt.pt object at ...> - modules: <Products.PageTemplates.ZRPythonExpr._SecureModuleImporter instance at ...> - options: {'args': ()} - nothing: - <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('customizezpt.pt') - -Now the view look-up is back to the old way: - - >>> view = zope.component.getMultiAdapter((item, request), - ... name=u"customizezpt.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: ---------- - - >>> from zope.app.testing.placelesssetup import tearDown - >>> tearDown() Deleted: Products.Five/branches/philikon-local-components/component/zptviews.pt =================================================================== --- Products.Five/branches/philikon-local-components/component/zptviews.pt 2006-04-25 08:46:29 UTC (rev 67583) +++ Products.Five/branches/philikon-local-components/component/zptviews.pt 2006-04-25 08:49:16 UTC (rev 67584) @@ -1,33 +0,0 @@ -<html metal:use-macro="context/@@standard_macros/view" - i18n:domain="zope"> - <body> - <div metal:fill-slot="body"> - - <p i18n:translate="">Template-based (global) browser views available - for this component:</p> - - <table> - <tr> - <th></th> - <th>Name of View</th> - <th>Registration Info</th> - </tr> - <tr tal:repeat="info view/templateViewRegInfo"> - <td><img src="misc_/PageTemplates/zpt.gif" - tal:attributes="src string:${context/@@absolute_url}/misc_/PageTemplates/zpt.gif" /></td> - <td> - <a href="" - tal:attributes="href string:@@customizetemplate.html?viewname=${info/viewname}" - tal:content="info/viewname"> - </a> - </td> - <td><code tal:content="info/zptfile">zptfile</code><br /> - <code tal:content="info/for">for</code><br /> - <code tal:content="info/zcmlfile">zcmlfile</code></td> - </tr> - </table> - - </div> - </body> - -</html> _______________________________________________ Zope-Checkins maillist - Zope-Checkins@zope.org http://mail.zope.org/mailman/listinfo/zope-checkins