[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