[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