[Zope-Checkins]
SVN: Products.Five/branches/philikon-local-components/component/
Refactoring: Make browser.py smaller:
Philipp von Weitershausen
philikon at philikon.de
Sat Mar 4 19:31:09 EST 2006
Log message for revision 65813:
Refactoring: Make browser.py smaller:
Move local-ZPT logic out to zpt.py (we still could do more)
Move findSite out to __init__.py and make the siteManagerAdapter use it.
Changed:
U Products.Five/branches/philikon-local-components/component/__init__.py
U Products.Five/branches/philikon-local-components/component/browser.py
A Products.Five/branches/philikon-local-components/component/zpt.py
-=-
Modified: Products.Five/branches/philikon-local-components/component/__init__.py
===================================================================
--- Products.Five/branches/philikon-local-components/component/__init__.py 2006-03-05 00:26:36 UTC (rev 65812)
+++ Products.Five/branches/philikon-local-components/component/__init__.py 2006-03-05 00:31:08 UTC (rev 65813)
@@ -11,17 +11,16 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
-"""Component browser views
+"""Five local component look-up support
$Id$
"""
-from zope.event import notify
-from zope.interface import Interface, implementer
-from zope.interface import alsoProvides, noLongerProvides
-from zope.component import adapter, getGlobalSiteManager
+import zope.interface
+import zope.component
+import zope.event
from zope.component.interfaces import IComponentLookup
+from zope.app.component.interfaces import ISite, IPossibleSite
from zope.app.publication.zopepublication import BeforeTraverseEvent
-from zope.app.component.interfaces import ISite, IPossibleSite
import ExtensionClass
from Acquisition import aq_base, aq_inner, aq_parent
@@ -33,27 +32,29 @@
import zope.app.component.hooks
zope.app.component.hooks.setHooks()
- at adapter(Interface)
- at implementer(IComponentLookup)
+def findSite(obj, iface=ISite):
+ """Find a site by walking up the object hierarchy, supporting both
+ the ``ILocation`` API and Zope 2 Acquisition."""
+ while obj is not None and not iface.providedBy(obj):
+ obj = getattr(obj, '__parent__', aq_parent(aq_inner(obj)))
+ return obj
+
+ at zope.component.adapter(zope.interface.Interface)
+ at zope.interface.implementer(IComponentLookup)
def siteManagerAdapter(ob):
"""Look-up a site manager/component registry for local component
lookup. This is registered in place of the one in Zope 3 so that
- we lookup using acquisition in addition to ILocation."""
- current = ob
- while True:
- if ISite.providedBy(current):
- return current.getSiteManager()
- current = getattr(current, '__parent__', aq_parent(aq_inner(current)))
- if current is None:
- # It does not support acquisition or has no parent, so we
- # return the global site
- return getGlobalSiteManager()
+ we lookup using acquisition in addition to the ``ILocation`` API.
+ """
+ site = findSite(ob)
+ if site is None:
+ return zope.component.getGlobalSiteManager()
+ return site.getSiteManager()
-
class LocalSiteHook(ExtensionClass.Base):
def __call__(self, container, request):
- notify(BeforeTraverseEvent(container, request))
+ zope.event.notify(BeforeTraverseEvent(container, request))
HOOK_NAME = '__local_site_hook__'
@@ -70,7 +71,7 @@
if not hasattr(obj, HOOK_NAME):
setattr(obj, HOOK_NAME, LocalSiteHook())
- alsoProvides(obj, iface)
+ zope.interface.alsoProvides(obj, iface)
def disableSite(obj, iface=ISite):
"""Remove __before_traverse__ hook for Local Site
@@ -84,4 +85,4 @@
if hasattr(obj, HOOK_NAME):
delattr(obj, HOOK_NAME)
- noLongerProvides(obj, iface)
+ zope.interface.noLongerProvides(obj, iface)
Modified: Products.Five/branches/philikon-local-components/component/browser.py
===================================================================
--- Products.Five/branches/philikon-local-components/component/browser.py 2006-03-05 00:26:36 UTC (rev 65812)
+++ Products.Five/branches/philikon-local-components/component/browser.py 2006-03-05 00:31:08 UTC (rev 65813)
@@ -17,20 +17,21 @@
"""
import os.path
-from Acquisition import aq_parent, aq_acquire, aq_inner
+from Acquisition import aq_inner
from Products.Five.browser import BrowserView
-from Products.Five.component import enableSite, disableSite
+from Products.Five.component import enableSite, disableSite, findSite
from Products.Five.component.interfaces import IObjectManagerSite
+from Products.Five.component.zpt import ZPTViewFactory
from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate
-from Products.PageTemplates.Expressions import SecureModuleImporter
-from zope.interface import Interface, providedBy
-from zope.component import getMultiAdapter, getGlobalSiteManager
+import zope.interface
+import zope.component
from zope.component.globalregistry import base
from zope.component.persistentregistry import PersistentComponents
from zope.publisher.interfaces.browser import IBrowserRequest
from zope.app.component.hooks import clearSite
-from zope.app.apidoc.presentation import getViews, getViewInfoDictionary
+from zope.app.apidoc.presentation import getViews
+from zope.app.traversing.browser.absoluteurl import absoluteURL
class ComponentsView(BrowserView):
@@ -50,6 +51,8 @@
enableSite(self.context, iface=IObjectManagerSite)
+ #TODO in the future we'll have to walk up to other site
+ # managers and put them in the bases
components = PersistentComponents()
components.__bases__ = (base,)
self.context.setSiteManager(components)
@@ -72,24 +75,25 @@
class CustomizationView(BrowserView):
def templateViewRegistrations(self):
- for reg in getViews(providedBy(self.context), IBrowserRequest):
+ 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 templateFromViewname(self, viewname):
- view = getMultiAdapter((self.context, self.request),
- name=viewname)
+ view = zope.component.getMultiAdapter((self.context, self.request),
+ name=viewname)
return view.index
def doCustomizeTemplate(self, viewname):
# find the nearest site
- site = self.context
- while site is not None and not IObjectManagerSite.providedBy(site):
- site = aq_parent(site)
+ site = findSite(self.context, IObjectManagerSite)
if site is None:
raise TypeError("No site found") #TODO find right exception
@@ -105,7 +109,8 @@
# find out the view registration object so we can get at the
# provided and required interfaces
- for reg in getViews(providedBy(self.context), IBrowserRequest):
+ for reg in getViews(zope.interface.providedBy(self.context),
+ IBrowserRequest):
if reg.name == viewname:
break
@@ -118,56 +123,7 @@
def customizeTemplate(self, viewname):
viewzpt = self.doCustomizeTemplate(viewname)
- viewzpt = aq_inner(viewzpt)
- #TODO use @@absolute_url view
- url = viewzpt.absolute_url() + "/manage_workspace"
+ # 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)
-
-class ZPTViewFactory(object):
-
- def __init__(self, viewzpt, viewname):
- self.viewzpt = viewzpt
- self.viewname = viewname
-
- def __call__(self, context, request):
- return ZPTView(self.viewzpt, self.viewname, context, request)
-
-class ZPTView(BrowserView):
-
- def __init__(self, viewzpt, viewname, context, request):
- self.viewzpt = viewzpt
- self.viewname = self.__name__ = viewname
- self.context = context
- self.request = request
-
- def _findViewClass(self):
- #XXX we might want to walk up to the next site instead, not
- # just go to the global one directly
- gsm = getGlobalSiteManager()
- view = gsm.queryMultiAdapter((self.context, self.request), Interface,
- name=self.viewname)
- 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.viewzpt,
- '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.viewzpt.pt_render(namespace)
Added: Products.Five/branches/philikon-local-components/component/zpt.py
===================================================================
--- Products.Five/branches/philikon-local-components/component/zpt.py 2006-03-05 00:26:36 UTC (rev 65812)
+++ Products.Five/branches/philikon-local-components/component/zpt.py 2006-03-05 00:31:08 UTC (rev 65813)
@@ -0,0 +1,86 @@
+##############################################################################
+#
+# 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
+
+import zope.component
+import zope.interface
+
+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."""
+
+ 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)
Property changes on: Products.Five/branches/philikon-local-components/component/zpt.py
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
More information about the Zope-Checkins
mailing list