[Checkins] SVN: grok/branches/ksmith_mcweekly-layers/ *
grok.Viewlet behaves more like grok.View this
Kevin Smith
kevin at mcweekly.com
Fri Apr 27 14:12:39 EDT 2007
Log message for revision 74866:
* grok.Viewlet behaves more like grok.View this
means templates can be used or render overridden
* add grok.OrderedViewletManager which sorts by
class name
Changed:
U grok/branches/ksmith_mcweekly-layers/buildout.cfg
U grok/branches/ksmith_mcweekly-layers/src/grok/__init__.py
U grok/branches/ksmith_mcweekly-layers/src/grok/components.py
U grok/branches/ksmith_mcweekly-layers/src/grok/directive.py
U grok/branches/ksmith_mcweekly-layers/src/grok/ftests/url/url_function.py
U grok/branches/ksmith_mcweekly-layers/src/grok/interfaces.py
U grok/branches/ksmith_mcweekly-layers/src/grok/meta.py
U grok/branches/ksmith_mcweekly-layers/src/grok/tests/test_grok.py
-=-
Modified: grok/branches/ksmith_mcweekly-layers/buildout.cfg
===================================================================
--- grok/branches/ksmith_mcweekly-layers/buildout.cfg 2007-04-27 18:10:18 UTC (rev 74865)
+++ grok/branches/ksmith_mcweekly-layers/buildout.cfg 2007-04-27 18:12:36 UTC (rev 74866)
@@ -1,10 +1,11 @@
[buildout]
develop = . grokwiki ldapaddressbook
-parts = zope3 data instance testdata testinstance test
+parts = data instance testdata testinstance test
[zope3]
-recipe = zc.recipe.zope3checkout
-url = svn://svn.zope.org/repos/main/Zope3/branches/3.3
+location = /root/Zope-3.3.1
+#recipe = zc.recipe.zope3checkout
+#url = svn://svn.zope.org/repos/main/Zope3/branches/3.3
[data]
recipe = zc.recipe.filestorage
@@ -54,7 +55,7 @@
[test]
recipe = zc.recipe.testrunner
eggs = grok
-extra-paths = parts/zope3/src
+extra-paths = /root/Zope-3.3.1/lib/python
working-directory = parts/testinstance
defaults = ['--tests-pattern', '^f?tests$',
'-v'
Modified: grok/branches/ksmith_mcweekly-layers/src/grok/__init__.py
===================================================================
--- grok/branches/ksmith_mcweekly-layers/src/grok/__init__.py 2007-04-27 18:10:18 UTC (rev 74865)
+++ grok/branches/ksmith_mcweekly-layers/src/grok/__init__.py 2007-04-27 18:12:36 UTC (rev 74866)
@@ -34,10 +34,11 @@
from grok.components import PageTemplate, PageTemplateFile, Container, Traverser
from grok.components import Site, GlobalUtility, LocalUtility, Annotation
from grok.components import Application, Form, AddForm, EditForm, DisplayForm
-from grok.components import Indexes, Skin, ILayer
+from grok.components import Indexes, Skin, ILayer, ViewletManager, Viewlet
+from grok.components import OrderedViewletManager
from grok.directive import (context, name, template, templatedir, provides,
baseclass, global_utility, local_utility,
- define_permission, require, site, layer)
+ define_permission, require, site, layer, viewletmanager)
from grok._grok import do_grok as grok # Avoid name clash within _grok
from grok._grok import SubscribeDecorator as subscribe
Modified: grok/branches/ksmith_mcweekly-layers/src/grok/components.py
===================================================================
--- grok/branches/ksmith_mcweekly-layers/src/grok/components.py 2007-04-27 18:10:18 UTC (rev 74865)
+++ grok/branches/ksmith_mcweekly-layers/src/grok/components.py 2007-04-27 18:12:36 UTC (rev 74866)
@@ -40,6 +40,8 @@
from zope.traversing.browser.absoluteurl import AbsoluteURL
from zope.traversing.browser.absoluteurl import _safe as SAFE_URL_CHARACTERS
from zope.annotation.interfaces import IAttributeAnnotatable
+from zope.viewlet.manager import ViewletManagerBase
+from zope.viewlet.viewlet import ViewletBase
from zope.app.pagetemplate.engine import TrustedAppPT
from zope.app.publisher.browser import getDefaultViewName
@@ -511,3 +513,83 @@
class Skin(object):
pass
+
+
+class ViewletManager(ViewletManagerBase):
+ template = None
+
+
+class OrderedViewletManager(ViewletManager):
+ def sort(self, viewlets):
+ # sort by viewlet class name as default
+ return sorted(viewlets, lambda x,y: cmp(x[0], y[0]))
+
+
+class Viewlet(ViewletBase):
+ """ Batteries included viewlet """
+
+
+ def __init__(self, context, request, view, manager):
+ super(Viewlet, self).__init__(context, request, view, manager)
+ 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/ksmith_mcweekly-layers/src/grok/directive.py
===================================================================
--- grok/branches/ksmith_mcweekly-layers/src/grok/directive.py 2007-04-27 18:10:18 UTC (rev 74865)
+++ grok/branches/ksmith_mcweekly-layers/src/grok/directive.py 2007-04-27 18:12:36 UTC (rev 74866)
@@ -284,3 +284,5 @@
layer = InterfaceOrClassDirective('grok.layer',
ClassOrModuleDirectiveContext())
+viewletmanager = InterfaceOrClassDirective('grok.viewletmanager',
+ ClassDirectiveContext())
Modified: grok/branches/ksmith_mcweekly-layers/src/grok/ftests/url/url_function.py
===================================================================
--- grok/branches/ksmith_mcweekly-layers/src/grok/ftests/url/url_function.py 2007-04-27 18:10:18 UTC (rev 74865)
+++ grok/branches/ksmith_mcweekly-layers/src/grok/ftests/url/url_function.py 2007-04-27 18:12:36 UTC (rev 74866)
@@ -6,8 +6,8 @@
>>> from grok import url
>>> import grok
>>> grok.grok('grok.ftests.url.url_function')
-
- >>> from grok.ftests.url.url import Herd, Mammoth
+
+ >>> from grok.ftests.url.url_function import Herd, Mammoth
>>> herd = Herd()
>>> getRootFolder()['herd'] = herd
>>> manfred = Mammoth()
@@ -24,7 +24,7 @@
>>> browser.open("http://localhost/herd/manfred/another")
>>> print browser.contents
http://localhost/herd/manfred/another
-
+
We get the views manually so we can do a greater variety of url() calls:
>>> from zope import component
@@ -65,6 +65,7 @@
True
"""
import grok
+from grok import url
class Herd(grok.Container, grok.Model):
pass
@@ -77,7 +78,7 @@
class Index(grok.View):
def render(self):
return url(self.request, self)
-
+
class Another(grok.View):
def render(self):
return url(self.request, self)
Modified: grok/branches/ksmith_mcweekly-layers/src/grok/interfaces.py
===================================================================
--- grok/branches/ksmith_mcweekly-layers/src/grok/interfaces.py 2007-04-27 18:10:18 UTC (rev 74865)
+++ grok/branches/ksmith_mcweekly-layers/src/grok/interfaces.py 2007-04-27 18:12:36 UTC (rev 74866)
@@ -41,8 +41,11 @@
AddForm = interface.Attribute("Base class for add forms.")
EditForm = interface.Attribute("Base class for edit forms.")
DisplayForm = interface.Attribute("Base class for display forms.")
- Layer = interface.Attribute("Base interface for skin layers.")
-
+ ILayer = 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):
def GrokError(message, component):
Modified: grok/branches/ksmith_mcweekly-layers/src/grok/meta.py
===================================================================
--- grok/branches/ksmith_mcweekly-layers/src/grok/meta.py 2007-04-27 18:10:18 UTC (rev 74865)
+++ grok/branches/ksmith_mcweekly-layers/src/grok/meta.py 2007-04-27 18:12:36 UTC (rev 74866)
@@ -7,8 +7,11 @@
IBrowserPublisher,
IBrowserSkinType)
from zope.publisher.interfaces.xmlrpc import IXMLRPCRequest
+from zope.publisher.browser import IBrowserView
+from zope.viewlet.interfaces import IViewletManager, IViewlet
from zope.security.permission import Permission
from zope.security.interfaces import IPermission
+from zope.security.checker import NamesChecker, defineChecker
from zope.annotation.interfaces import IAnnotations
from zope.app.publisher.xmlrpc import MethodPublisher
@@ -28,6 +31,7 @@
from grok.error import GrokError
+
class ModelGrokker(grok.ClassGrokker):
component_class = grok.Model
@@ -110,9 +114,6 @@
permission = getattr(method, '__grok_require__',
default_permission)
util.make_checker(factory, method_view, permission)
-
-class ILayerGrokker(grok.ClassGrokker):
- component_class = grok.ILayer
class ViewGrokker(grok.ClassGrokker):
@@ -298,19 +299,7 @@
interface.Interface, name=module_info.dotted_name)
-class RegisterSkinDirectiveGrokker(grok.ModuleGrokker):
- def register(self, context, module_info, templates):
- infos = module_info.getAnnotation('grok.register_skin',[])
- if infos:
- for skin in infos:
- name = skin.name
- if not skin.name:
- name = skin.layer.__name__
- zope.component.interface.provideInterface(name, skin.layer,
- IBrowserSkinType)
-
-
class GlobalUtilityDirectiveGrokker(grok.ModuleGrokker):
def register(self, context, module_info, templates):
@@ -586,6 +575,10 @@
return intids
+class ILayerGrokker(grok.ClassGrokker):
+ component_class = grok.ILayer
+
+
class SkinGrokker(grok.ClassGrokker):
component_class = grok.Skin
@@ -595,3 +588,65 @@
None) or grok.IDefaultBrowserLayer
name = grok.util.class_annotation(factory, 'grok.name', factory.__name__.lower())
zope.component.interface.provideInterface(name, layer, IBrowserSkinType)
+
+
+class ViewletManagerGrokker(grok.ClassGrokker):
+ component_class = (grok.ViewletManager, grok.OrderedViewletManager)
+
+ def register(self, context, name, factory, module_info, templates):
+
+ 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
+
+ view_context = util.determine_class_context(factory, context)
+ component.provideAdapter(factory,
+ adapts=(None, # TODO: Make configurable
+ view_layer, # TODO: Make configurable
+ view_context),
+ provides=IViewletManager,
+ name=name)
+
+
+class ViewletGrokker(grok.ClassGrokker):
+ component_class = grok.Viewlet
+
+ def register(self, context, name, factory, module_info, templates):
+ # Try to set up permissions (copied from the View grokker)
+
+ factory.module_info = module_info # to make /static available
+
+ permissions = grok.util.class_annotation(factory, 'grok.require', [])
+ if not permissions:
+ checker = NamesChecker(['update', 'render'])
+ elif len(permissions) > 1:
+ raise GrokError('grok.require was called multiple times in viewlet '
+ '%r. It may only be called once.' % factory,
+ factory)
+ elif permissions[0] == 'zope.Public':
+ checker = NamesChecker(['update','render'])
+ else:
+ perm = permissions[0]
+ if component.queryUtility(IPermission, name=perm) is None:
+ raise GrokError('Undefined permission %r in view %r. Use '
+ 'grok.define_permission first.'
+ % (perm, factory), factory)
+ checker = NamesChecker(['update','render'], permissions[0])
+
+ defineChecker(factory, checker)
+
+ # New directive
+ viewletmanager = grok.util.class_annotation(factory, 'grok.viewletmanager', [])
+ layer = util.class_annotation(factory, 'grok.layer',
+ None) or module_info.getAnnotation('grok.layer',
+ None) or IDefaultBrowserLayer
+
+ component.provideAdapter(factory,
+ adapts=(None, # TODO: Make configurable
+ layer,
+ IBrowserView,
+ viewletmanager),
+ provides=IViewlet,
+ name=name)
+
Modified: grok/branches/ksmith_mcweekly-layers/src/grok/tests/test_grok.py
===================================================================
--- grok/branches/ksmith_mcweekly-layers/src/grok/tests/test_grok.py 2007-04-27 18:10:18 UTC (rev 74865)
+++ grok/branches/ksmith_mcweekly-layers/src/grok/tests/test_grok.py 2007-04-27 18:12:36 UTC (rev 74866)
@@ -2,9 +2,12 @@
from pkg_resources import resource_listdir
from zope.testing import doctest, cleanup
import zope.component.eventtesting
+import zope.viewlet.tests
+
def setUpZope(test):
zope.component.eventtesting.setUp(test)
+ zope.viewlet.tests.setUp(test)
def cleanUpZope(test):
cleanup.cleanUp()
More information about the Checkins
mailing list