[Checkins] SVN: grok/branches/snowsprint-viewlets2/ Create branch combining refactorings on trunk with snowsprint-viewlets

Martijn Faassen faassen at infrae.com
Thu Jan 24 08:06:13 EST 2008


Log message for revision 83163:
  Create branch combining refactorings on trunk with snowsprint-viewlets
  

Changed:
  U   grok/branches/snowsprint-viewlets2/setup.py
  U   grok/branches/snowsprint-viewlets2/src/grok/__init__.py
  U   grok/branches/snowsprint-viewlets2/src/grok/components.py
  U   grok/branches/snowsprint-viewlets2/src/grok/configure.zcml
  U   grok/branches/snowsprint-viewlets2/src/grok/directive.py
  U   grok/branches/snowsprint-viewlets2/src/grok/ftests/test_grok_functional.py
  A   grok/branches/snowsprint-viewlets2/src/grok/ftests/viewlet/
  U   grok/branches/snowsprint-viewlets2/src/grok/interfaces.py
  U   grok/branches/snowsprint-viewlets2/src/grok/meta.py
  U   grok/branches/snowsprint-viewlets2/src/grok/util.py
  U   grok/branches/snowsprint-viewlets2/versions.cfg

-=-
Modified: grok/branches/snowsprint-viewlets2/setup.py
===================================================================
--- grok/branches/snowsprint-viewlets2/setup.py	2008-01-24 12:58:53 UTC (rev 83162)
+++ grok/branches/snowsprint-viewlets2/setup.py	2008-01-24 13:06:13 UTC (rev 83163)
@@ -77,6 +77,7 @@
                       'zope.testing',
                       'zope.traversing',
                       'zope.testbrowser',
+                      'zope.viewlet',
                       'zc.catalog',
                       'z3c.flashmessage',
                       ],

Modified: grok/branches/snowsprint-viewlets2/src/grok/__init__.py
===================================================================
--- grok/branches/snowsprint-viewlets2/src/grok/__init__.py	2008-01-24 12:58:53 UTC (rev 83162)
+++ grok/branches/snowsprint-viewlets2/src/grok/__init__.py	2008-01-24 13:06:13 UTC (rev 83163)
@@ -40,9 +40,12 @@
 from grok.components import Skin, IGrokLayer
 from grok.components import RESTProtocol, IRESTLayer
 from grok.interfaces import IRESTSkinType
+from grok.components import ViewletManager, Viewlet
+
 from grok.directive import (context, name, title, template, templatedir,
                             provides, baseclass, global_utility, local_utility,
-                            permissions, require, site, layer, direct, order)
+                            permissions, require, site, layer, direct, viewletmanager,
+                            view, order)
 from grok.decorators import subscribe, adapter, implementer
 from martian.error import GrokError, GrokImportError
 

Modified: grok/branches/snowsprint-viewlets2/src/grok/components.py
===================================================================
--- grok/branches/snowsprint-viewlets2/src/grok/components.py	2008-01-24 12:58:53 UTC (rev 83162)
+++ grok/branches/snowsprint-viewlets2/src/grok/components.py	2008-01-24 13:06:13 UTC (rev 83163)
@@ -47,6 +47,9 @@
 from zope.app.component.site import SiteManagerContainer
 from zope.app.component.site import LocalSiteManager
 
+from zope.viewlet.manager import ViewletManagerBase
+from zope.viewlet.viewlet import ViewletBase
+
 import z3c.flashmessage.interfaces
 
 import martian.util
@@ -608,3 +611,134 @@
 
 class RESTProtocol(object):
     pass
+
+class ViewletManager(ViewletManagerBase):
+    template = None
+
+    def __init__(self, context, request, view):
+        super(ViewletManager, self).__init__(context, request, view)
+        self.__name__ = util.class_annotation(self.__class__,
+                                              'grok.name',
+                                              self.__class__.__name__.lower())
+        self.static = component.queryAdapter(
+            self.request,
+            interface.Interface,
+            name=self.module_info.package_dotted_name
+            )
+
+
+    def render(self):
+        """See zope.contentprovider.interfaces.IContentProvider"""
+        # Now render the view
+        if self.template:
+            #return self.template(viewlets=self.viewlets)
+            return self._render_template()
+        else:
+            return u'\n'.join([viewlet.render() for viewlet in self.viewlets])
+
+
+    @property
+    def response(self):
+        return self.request.response
+
+    def _render_template(self):
+        namespace = self.template.pt_getContext()
+        namespace['request'] = self.request
+        namespace['view'] = self
+        namespace['viewlets'] = self.viewlets
+        namespace['static'] = self.static
+        namespace['context'] = self.context
+        # XXX need to check whether we really want to put None here if missing
+        return self.template.pt_render(namespace)
+
+    def url(self, obj=None, name=None):
+        # if the first argument is a string, that's the name. There should
+        # be no second argument
+        if isinstance(obj, basestring):
+            if name is not None:
+                raise TypeError(
+                    'url() takes either obj argument, obj, string arguments, '
+                    'or string argument')
+            name = obj
+            obj = None
+
+        if name is None and obj is None:
+            # create URL to view itself
+            obj = self
+        elif name is not None and obj is None:
+            # create URL to view on context
+            obj = self.context
+        return util.url(self.request, obj, name)
+
+    def redirect(self, url):
+        return self.request.response.redirect(url)
+
+class Viewlet(ViewletBase):
+    """ Batteries included viewlet """
+
+
+    def __init__(self, context, request, view, manager):
+        super(Viewlet, self).__init__(context, request, view, manager)
+        self.__name__ = util.class_annotation(self.__class__,
+                                             'grok.name',
+                                              self.__class__.__name__.lower())
+        self.static = component.queryAdapter(
+            self.request,
+            interface.Interface,
+            name=self.module_info.package_dotted_name
+            )
+
+
+    @property
+    def response(self):
+        return self.request.response
+
+
+    def render(self):
+        mapply(self.update, (), self.request)
+        if self.request.response.getStatus() in (302, 303):
+            # A redirect was triggered somewhere in update().  Don't
+            # continue rendering the template or doing anything else.
+            return
+
+        template = getattr(self, 'template', None)
+        if template is not None:
+            return self._render_template()
+
+    def _render_template(self):
+        namespace = self.template.pt_getContext()
+        namespace['request'] = self.request
+        namespace['view'] = self
+        namespace['context'] = self.context
+        # XXX need to check whether we really want to put None here if missing
+        namespace['static'] = self.static
+        return self.template.pt_render(namespace)
+
+    def __getitem__(self, key):
+        # XXX give nice error message if template is None
+        return self.template.macros[key]
+
+    def url(self, obj=None, name=None):
+        # if the first argument is a string, that's the name. There should
+        # be no second argument
+        if isinstance(obj, basestring):
+            if name is not None:
+                raise TypeError(
+                    'url() takes either obj argument, obj, string arguments, '
+                    'or string argument')
+            name = obj
+            obj = None
+
+        if name is None and obj is None:
+            # create URL to view itself
+            obj = self
+        elif name is not None and obj is None:
+            # create URL to view on context
+            obj = self.context
+        return util.url(self.request, obj, name)
+
+    def redirect(self, url):
+        return self.request.response.redirect(url)
+
+    def update(self):
+        pass

Modified: grok/branches/snowsprint-viewlets2/src/grok/configure.zcml
===================================================================
--- grok/branches/snowsprint-viewlets2/src/grok/configure.zcml	2008-01-24 12:58:53 UTC (rev 83162)
+++ grok/branches/snowsprint-viewlets2/src/grok/configure.zcml	2008-01-24 13:06:13 UTC (rev 83163)
@@ -11,6 +11,7 @@
 
   <include package="zope.annotation" />
   <include package="zope.copypastemove" />
+  <include package="zope.contentprovider" />
   <include package="zope.formlib" />
   <include package="zope.i18n.locales" />
   <include package="zope.publisher" />

Modified: grok/branches/snowsprint-viewlets2/src/grok/directive.py
===================================================================
--- grok/branches/snowsprint-viewlets2/src/grok/directive.py	2008-01-24 12:58:53 UTC (rev 83162)
+++ grok/branches/snowsprint-viewlets2/src/grok/directive.py	2008-01-24 13:06:13 UTC (rev 83163)
@@ -138,5 +138,9 @@
     'grok.permissions', ClassDirectiveContext())
 layer = InterfaceOrClassDirective('grok.layer',
                            ClassOrModuleDirectiveContext())
+order = OrderDirective('grok.order', ClassDirectiveContext())
 direct = MarkerDirective('grok.direct', ClassDirectiveContext())
-order = OrderDirective('grok.order', ClassDirectiveContext())
+viewletmanager = InterfaceOrClassDirective('grok.viewletmanager',
+                                           ClassDirectiveContext())
+view = InterfaceOrClassDirective('grok.view',
+                                 ClassDirectiveContext())

Modified: grok/branches/snowsprint-viewlets2/src/grok/ftests/test_grok_functional.py
===================================================================
--- grok/branches/snowsprint-viewlets2/src/grok/ftests/test_grok_functional.py	2008-01-24 12:58:53 UTC (rev 83162)
+++ grok/branches/snowsprint-viewlets2/src/grok/ftests/test_grok_functional.py	2008-01-24 13:06:13 UTC (rev 83163)
@@ -70,7 +70,8 @@
 def test_suite():
     suite = unittest.TestSuite()
     for name in ['view', 'staticdir', 'xmlrpc', 'traversal', 'form', 'url',
-                 'security', 'utility', 'catalog', 'admin', 'site', 'rest']:
+                 'security', 'utility', 'catalog', 'admin', 'site', 'rest',
+                 'viewlet']:
         suite.addTest(suiteFromPackage(name))
 
     # this test cannot follow the normal testing pattern, as the

Copied: grok/branches/snowsprint-viewlets2/src/grok/ftests/viewlet (from rev 83155, grok/branches/snowsprint-viewlets/src/grok/ftests/viewlet)

Modified: grok/branches/snowsprint-viewlets2/src/grok/interfaces.py
===================================================================
--- grok/branches/snowsprint-viewlets2/src/grok/interfaces.py	2008-01-24 12:58:53 UTC (rev 83162)
+++ grok/branches/snowsprint-viewlets2/src/grok/interfaces.py	2008-01-24 13:06:13 UTC (rev 83163)
@@ -47,6 +47,8 @@
     Indexes = interface.Attribute("Base class for catalog index definitions.")
     Layer = interface.Attribute("Base interface for layers.")
     Skin = interface.Attribute("Base class for skin.")
+    ViewletManager = interface.Attribute("Base class for viewletmanager.")
+    Viewlet = interface.Attribute("Base class for viewlet.")
 
 
 class IGrokErrors(interface.Interface):

Modified: grok/branches/snowsprint-viewlets2/src/grok/meta.py
===================================================================
--- grok/branches/snowsprint-viewlets2/src/grok/meta.py	2008-01-24 12:58:53 UTC (rev 83162)
+++ grok/branches/snowsprint-viewlets2/src/grok/meta.py	2008-01-24 13:06:13 UTC (rev 83163)
@@ -17,11 +17,13 @@
 
 import zope.component.interface
 from zope import interface, component
+from zope.publisher.browser import IBrowserView
 from zope.publisher.interfaces.browser import (IDefaultBrowserLayer,
                                                IBrowserRequest,
                                                IBrowserPublisher,
                                                IBrowserSkinType)
 from zope.publisher.interfaces.xmlrpc import IXMLRPCRequest
+from zope.viewlet.interfaces import IViewletManager, IViewlet
 from zope.security.interfaces import IPermission
 from zope.securitypolicy.interfaces import IRole
 from zope.securitypolicy.rolepermission import rolePermissionManager
@@ -871,3 +873,121 @@
             args=(name, layer, IRESTSkinType)
             )
         return True
+
+class ViewletManagerGrokker(martian.ClassGrokker):
+    component_class = grok.ViewletManager
+
+    def grok(self, name, factory, module_info, config, **kw):
+
+        factory.module_info = module_info # to make /static available
+
+        name = grok.util.class_annotation(factory, 'grok.name', factory.__name__.lower())
+        view_layer = util.class_annotation(factory, 'grok.layer',
+                                                    None) or module_info.getAnnotation('grok.layer',
+                                                     None) or IDefaultBrowserLayer
+
+        context = module_info.getAnnotation('grok.context', interface.Interface)
+        view_context = util.determine_class_context(factory, context)
+
+        # content providers can be associated with a view as well
+        # we default to all views, or IBrowserView
+        view = grok.util.class_annotation(factory, 'grok.view', IBrowserView)
+
+        view_layer = determine_class_directive('grok.layer', factory,
+                                               module_info,
+                                               default=IDefaultBrowserLayer)
+
+        # TODO - manager is registered for IBrowserView instead of the real view
+        config.action(
+            discriminator = ('viewletManager', view_context, view_layer,
+                             view, name),
+            callable = component.provideAdapter,
+            args = (factory, (interface.Interface, view_layer, view),
+                    IViewletManager, name)
+            )
+
+        permission = get_default_permission(factory)
+        config.action(
+            discriminator=('protectName', factory, '__call__'),
+            callable=make_checker,
+            args=(factory, factory, permission),
+            )
+
+        return True
+
+class ViewletGrokker(martian.ClassGrokker):
+    component_class = grok.Viewlet
+
+    def grok(self, name, factory, module_info, config, **kw):
+        # Try to set up permissions (copied from the View grokker)
+
+        factory.module_info = module_info # to make /static available
+        factory_name = factory.__name__.lower()
+
+        # find templates
+        template_name = util.class_annotation(factory, 'grok.template',
+                                              factory_name)
+        templates = module_info.getAnnotation('grok.templates', None)
+        template = templates.get(template_name)
+
+        if factory_name != template_name:
+            # grok.template is being used
+            if templates.get(factory_name):
+                raise GrokError("Multiple possible templates for view %r. It "
+                                "uses grok.template('%s'), but there is also "
+                                "a template called '%s'."
+                                % (factory, template_name, factory_name),
+                                factory)
+
+        factory_template = getattr(factory,'template', None)
+
+        if template:
+            if (getattr(factory, 'render', None) and not
+                util.check_subclass(factory, components.GrokForm) and not
+                util.check_subclass(factory, components.Viewlet)):
+                # we do not accept render and template both for a view
+                # (unless it's a form, they happen to have render.)
+                # Forms currently not implemented in viewlets.
+                raise GrokError(
+                    "Multiple possible ways to render view %r. "
+                    "It has both a 'render' method as well as "
+                    "an associated template." % factory, factory)
+
+            templates.markAssociated(template_name)
+            factory.template = template
+        elif factory_template and isinstance(factory_template, (components.PageTemplate, components.PageTemplateFile)):
+            pass
+        else:
+            if not getattr(factory, 'render', None):
+                # we do not accept a view without any way to render it
+                raise GrokError("View %r has no associated template or "
+                                "'render' method." % factory, factory)
+
+        context = module_info.getAnnotation('grok.context', interface.Interface)
+        view_context = util.determine_class_context(factory, context)
+
+        # content providers can be associated with a view as well
+        # we default to all views, or IBrowserView
+        view = grok.util.class_annotation(factory, 'grok.view', IBrowserView)
+
+        viewletmanager = grok.util.class_annotation(factory, 'grok.viewletmanager', [])
+        view_layer = util.class_annotation(factory, 'grok.layer',
+                                            None) or module_info.getAnnotation('grok.layer',
+                                             None) or IDefaultBrowserLayer
+
+        config.action(
+            discriminator = ('viewlet', view_context, view_layer,
+                             view, viewletmanager, name),
+            callable = component.provideAdapter,
+            args = (factory, (view_context, view_layer, view,
+                    viewletmanager), IViewlet, name)
+            )
+
+        permission = get_default_permission(factory)
+        config.action(
+            discriminator=('protectName', factory, '__call__'),
+            callable=make_checker,
+            args=(factory, factory, permission, ['update', 'render']),
+            )
+
+        return True

Modified: grok/branches/snowsprint-viewlets2/src/grok/util.py
===================================================================
--- grok/branches/snowsprint-viewlets2/src/grok/util.py	2008-01-24 12:58:53 UTC (rev 83162)
+++ grok/branches/snowsprint-viewlets2/src/grok/util.py	2008-01-24 13:06:13 UTC (rev 83163)
@@ -33,18 +33,20 @@
                         "(use grok.adapts to specify)."
                         % class_, class_)
 
-def make_checker(factory, view_factory, permission):
+def make_checker(factory, view_factory, permission, method_names=None):
     """Make a checker for a view_factory associated with factory.
 
     These could be one and the same for normal views, or different
     in case we make method-based views such as for JSON and XMLRPC.
     """
+    if method_names is None:
+        method_names = ['__call__']
     if permission is not None:
         check_permission(factory, permission)
     if permission is None or permission == 'zope.Public':
-        checker = NamesChecker(['__call__'])
+        checker = NamesChecker(method_names)
     else:
-        checker = NamesChecker(['__call__'], permission)
+        checker = NamesChecker(method_names, permission)
     defineChecker(view_factory, checker)
 
 def check_permission(factory, permission):

Modified: grok/branches/snowsprint-viewlets2/versions.cfg
===================================================================
--- grok/branches/snowsprint-viewlets2/versions.cfg	2008-01-24 12:58:53 UTC (rev 83162)
+++ grok/branches/snowsprint-viewlets2/versions.cfg	2008-01-24 13:06:13 UTC (rev 83163)
@@ -62,6 +62,7 @@
 zope.cachedescriptors = 3.4.0
 zope.component = 3.4.0
 zope.configuration = 3.4.0
+zope.contentprovider = 3.4.0
 zope.contenttype = 3.4.0
 zope.copypastemove = 3.4.0
 zope.datetime = 3.4.0
@@ -98,3 +99,4 @@
 zope.testing = 3.5.1
 zope.thread = 3.4
 zope.traversing = 3.5.0a1.dev-r78730
+zope.viewlet = 3.4.1



More information about the Checkins mailing list