[Checkins] SVN: grok/trunk/ Merge jw-simpler-skin-registration
branch.
Philipp von Weitershausen
philikon at philikon.de
Sat Aug 2 07:50:27 EDT 2008
Log message for revision 89198:
Merge jw-simpler-skin-registration branch.
Changed:
U grok/trunk/CHANGES.txt
U grok/trunk/doc/upgrade.txt
U grok/trunk/src/grok/__init__.py
U grok/trunk/src/grok/components.py
U grok/trunk/src/grok/directive.py
D grok/trunk/src/grok/ftests/view/layers.py
A grok/trunk/src/grok/ftests/view/skindirective.py
U grok/trunk/src/grok/ftests/viewlet/viewlet_security.py
U grok/trunk/src/grok/interfaces.py
U grok/trunk/src/grok/meta.py
D grok/trunk/src/grok/tests/conflict/skin.py
A grok/trunk/src/grok/tests/skin/
U grok/trunk/src/grok/tests/test_grok.py
-=-
Modified: grok/trunk/CHANGES.txt
===================================================================
--- grok/trunk/CHANGES.txt 2008-08-02 11:38:21 UTC (rev 89197)
+++ grok/trunk/CHANGES.txt 2008-08-02 11:50:27 UTC (rev 89198)
@@ -12,6 +12,11 @@
your environment, add ``grokui.admin`` to the required packages in
the ``setup.py`` of your package.
+* Removed ``grok.Skin`` baseclass in favour of a ``grok.skin(name)``
+ directive that can be used on layer interfaces. Also removed the
+ ``IGrokLayer`` interface in favour of exposing ``IBrowserRequest``
+ from the grok package.
+
Bug fixes
---------
Modified: grok/trunk/doc/upgrade.txt
===================================================================
--- grok/trunk/doc/upgrade.txt 2008-08-02 11:38:21 UTC (rev 89197)
+++ grok/trunk/doc/upgrade.txt 2008-08-02 11:50:27 UTC (rev 89198)
@@ -6,6 +6,28 @@
describes changes involving incompatibilities or deprecations, not new
features (please refer to ``CHANGES.txt`` for those).
+Upgrading to 0.14
+-----------------
+
+* The ``grok.Skin`` class has been removed in favour of a
+ ``grok.skin()`` directive for interfaces. For instance, if you
+ previously registered a browser layer as a skin like so::
+
+ class IMyLayer(grok.IGrokLayer):
+ pass
+
+ class MySkin(grok.Skin):
+ grok.layer(IMyLayer)
+
+ you can now simply write::
+
+ class IMyLayer(grok.IBrowserRequest):
+ grok.skin('myskin')
+
+ As you can see, ``IGrokLayer`` has also been removed, in favour of
+ the exposure of ``IBrowserRequest``.
+
+
Upgrading to 0.13
-----------------
Modified: grok/trunk/src/grok/__init__.py
===================================================================
--- grok/trunk/src/grok/__init__.py 2008-08-02 11:38:21 UTC (rev 89197)
+++ grok/trunk/src/grok/__init__.py 2008-08-02 11:50:27 UTC (rev 89198)
@@ -23,6 +23,9 @@
IObjectModifiedEvent, ObjectModifiedEvent,
IObjectCopiedEvent, ObjectCopiedEvent)
+from zope.publisher.interfaces.browser import IBrowserRequest
+from zope.publisher.interfaces.browser import IDefaultBrowserLayer
+
from zope.app.container.contained import (
IObjectAddedEvent, ObjectAddedEvent,
IObjectMovedEvent, ObjectMovedEvent,
@@ -39,7 +42,6 @@
from grok.components import Application, Form, AddForm, EditForm, DisplayForm
from grok.components import Indexes
from grok.components import Permission, Role, Public
-from grok.components import Skin, IGrokLayer
from grok.components import RESTProtocol, IRESTLayer
from grok.interfaces import IRESTSkinType
from grok.components import ViewletManager, Viewlet
@@ -49,7 +51,7 @@
context, name, title, description, provides, global_utility, direct)
from grok.directive import (
template, templatedir, local_utility, permissions, require, site,
- layer, viewletmanager, view, traversable, order)
+ layer, viewletmanager, view, traversable, order, skin)
from grokcore.component.decorators import subscribe, adapter, implementer
from martian.error import GrokError, GrokImportError
Modified: grok/trunk/src/grok/components.py
===================================================================
--- grok/trunk/src/grok/components.py 2008-08-02 11:38:21 UTC (rev 89197)
+++ grok/trunk/src/grok/components.py 2008-08-02 11:50:27 UTC (rev 89198)
@@ -29,6 +29,7 @@
from zope.securitypolicy.role import Role
from zope.publisher.browser import BrowserPage
from zope.publisher.interfaces import NotFound
+from zope.publisher.interfaces.browser import IBrowserRequest
from zope.publisher.interfaces.browser import IBrowserPublisher
from zope.publisher.interfaces.http import IHTTPRequest
from zope.publisher.publish import mapply
@@ -651,15 +652,9 @@
class Role(Role):
pass
-class IGrokLayer(interface.Interface):
+class IRESTLayer(IBrowserRequest):
pass
-class IRESTLayer(interface.Interface):
- pass
-
-class Skin(object):
- pass
-
class RESTProtocol(object):
pass
Modified: grok/trunk/src/grok/directive.py
===================================================================
--- grok/trunk/src/grok/directive.py 2008-08-02 11:38:21 UTC (rev 89197)
+++ grok/trunk/src/grok/directive.py 2008-08-02 11:50:27 UTC (rev 89198)
@@ -18,12 +18,14 @@
import grok
from zope import interface
from zope.interface.interfaces import IInterface
+from zope.interface.interface import TAGGED_DATA
+
from zope.publisher.interfaces.browser import IBrowserView
import martian
from martian import util
from martian.error import GrokImportError, GrokError
-from martian.directive import StoreMultipleTimes
+from martian.directive import StoreOnce, StoreMultipleTimes
from grokcore.component.scan import UnambiguousComponentScope
from grok import components
@@ -195,3 +197,33 @@
def factory(self, value=0):
order._order += 1
return value, order._order
+
+class TaggedValueStoreOnce(StoreOnce):
+ """Stores the directive value in a interface tagged value.
+ """
+
+ def get(self, directive, component, default):
+ return component.queryTaggedValue(directive.dotted_name(), default)
+
+ def set(self, locals_, directive, value):
+ if directive.dotted_name() in locals_:
+ raise GrokImportError(
+ "The '%s' directive can only be called once per %s." %
+ (directive.name, directive.scope.description))
+ # Make use of the implementation details of interface tagged
+ # values. Instead of being able to call "setTaggedValue()"
+ # on an interface object, we only have access to the "locals"
+ # of the interface object. We inject whatever setTaggedValue()
+ # would've injected.
+ taggeddata = locals_.setdefault(TAGGED_DATA, {})
+ taggeddata[directive.dotted_name()] = value
+
+ def setattr(self, context, directive, value):
+ context.setTaggedValue(directive.dotted_name(), value)
+
+class skin(martian.Directive):
+ # We cannot do any better than to check for a class scope. Ideally we
+ # would've checked whether the context is indeed an Interface class.
+ scope = martian.CLASS
+ store = TaggedValueStoreOnce()
+ validate = martian.validateText
Deleted: grok/trunk/src/grok/ftests/view/layers.py
===================================================================
--- grok/trunk/src/grok/ftests/view/layers.py 2008-08-02 11:38:21 UTC (rev 89197)
+++ grok/trunk/src/grok/ftests/view/layers.py 2008-08-02 11:50:27 UTC (rev 89198)
@@ -1,63 +0,0 @@
-"""
- >>> getRootFolder()["manfred"] = Mammoth()
-
- >>> from zope.testbrowser.testing import Browser
- >>> browser = Browser()
- >>> browser.handleErrors = False
- >>> browser.open("http://localhost/++skin++Basic/manfred/@@cavedrawings")
- >>> print browser.contents
- <html>
- <body>
- <h1>Hello, world!</h1>
- </body>
- </html>
-
- >>> browser.open("http://localhost/++skin++Rotterdam/manfred/@@moredrawings")
- >>> print browser.contents
- Pretty
-
- >>> browser.open("http://localhost/++skin++myskin/manfred/@@evenmoredrawings")
- >>> print browser.contents
- Awesome
-
-"""
-import grok
-from zope.app.basicskin import IBasicSkin
-from zope.publisher.interfaces.browser import IBrowserRequest
-from zope.app.rotterdam import rotterdam
-from zope import interface
-
-grok.layer(IBasicSkin)
-
-class MySkinLayer(grok.IGrokLayer):
- pass
-
-class MySkin(grok.Skin):
- grok.layer(MySkinLayer)
-
-class Mammoth(grok.Model):
- pass
-
-class CaveDrawings(grok.View):
- pass
-
-cavedrawings = grok.PageTemplate("""\
-<html>
-<body>
-<h1>Hello, world!</h1>
-</body>
-</html>
-""")
-
-class MoreDrawings(grok.View):
- grok.layer(rotterdam)
-
- def render(self):
- return "Pretty"
-
-
-class EvenMoreDrawings(grok.View):
- grok.layer(MySkinLayer)
-
- def render(self):
- return "Awesome"
Copied: grok/trunk/src/grok/ftests/view/skindirective.py (from rev 89197, grok/branches/jw-simpler-skin-registration/src/grok/ftests/view/skindirective.py)
===================================================================
--- grok/trunk/src/grok/ftests/view/skindirective.py (rev 0)
+++ grok/trunk/src/grok/ftests/view/skindirective.py 2008-08-02 11:50:27 UTC (rev 89198)
@@ -0,0 +1,61 @@
+"""
+ >>> getRootFolder()["manfred"] = Mammoth()
+
+ >>> from zope.testbrowser.testing import Browser
+ >>> browser = Browser()
+ >>> browser.handleErrors = False
+ >>> browser.open("http://localhost/++skin++Basic/manfred/@@cavedrawings")
+ >>> print browser.contents
+ <html>
+ <body>
+ <h1>Hello, world!</h1>
+ </body>
+ </html>
+
+ >>> browser.open("http://localhost/++skin++Rotterdam/manfred/@@moredrawings")
+ >>> print browser.contents
+ Pretty
+
+ >>> browser.open("http://localhost/++skin++myskin/manfred/@@evenmoredrawings")
+ >>> print browser.contents
+ Awesome
+
+"""
+import grok
+from zope.app.basicskin import IBasicSkin
+from zope.app.rotterdam import rotterdam
+
+grok.layer(IBasicSkin)
+
+class MySkinLayer(grok.IBrowserRequest):
+ pass
+
+class MySkin(MySkinLayer):
+ grok.skin('myskin')
+
+class Mammoth(grok.Model):
+ pass
+
+class CaveDrawings(grok.View):
+ pass
+
+cavedrawings = grok.PageTemplate("""\
+<html>
+<body>
+<h1>Hello, world!</h1>
+</body>
+</html>
+""")
+
+class MoreDrawings(grok.View):
+ grok.layer(rotterdam)
+
+ def render(self):
+ return "Pretty"
+
+
+class EvenMoreDrawings(grok.View):
+ grok.layer(MySkinLayer)
+
+ def render(self):
+ return "Awesome"
Modified: grok/trunk/src/grok/ftests/viewlet/viewlet_security.py
===================================================================
--- grok/trunk/src/grok/ftests/viewlet/viewlet_security.py 2008-08-02 11:38:21 UTC (rev 89197)
+++ grok/trunk/src/grok/ftests/viewlet/viewlet_security.py 2008-08-02 11:50:27 UTC (rev 89198)
@@ -154,8 +154,8 @@
def render(self):
return 'Gold Bone'
-class IBoneLayer(grok.IGrokLayer, IDefaultBrowserLayer):
- pass
+class IBoneLayer(IDefaultBrowserLayer):
+ grok.skin('boneskin')
class LayeredBone(grok.Viewlet):
grok.context(Interface)
@@ -180,9 +180,6 @@
def render(self):
return 'Lady Viewlet'
-class BoneSkin(grok.Skin):
- grok.layer(IBoneLayer)
-
class NamedViewletManager(grok.ViewletManager):
grok.context(Interface)
grok.name('managerwithname')
Modified: grok/trunk/src/grok/interfaces.py
===================================================================
--- grok/trunk/src/grok/interfaces.py 2008-08-02 11:38:21 UTC (rev 89197)
+++ grok/trunk/src/grok/interfaces.py 2008-08-02 11:50:27 UTC (rev 89198)
@@ -238,6 +238,8 @@
"""
IRESTSkinType = interface.Attribute('The REST skin type')
+ IBrowserRequest = interface.Attribute('Browser request interface')
+ IDefaultBrowserLayer = interface.Attribute('Default layer for browser views.')
class IGrokView(IBrowserPage, IBrowserView):
"""Grok views all provide this interface."""
Modified: grok/trunk/src/grok/meta.py
===================================================================
--- grok/trunk/src/grok/meta.py 2008-08-02 11:38:21 UTC (rev 89197)
+++ grok/trunk/src/grok/meta.py 2008-08-02 11:50:27 UTC (rev 89198)
@@ -17,6 +17,7 @@
import zope.component.interface
from zope import interface, component
+from zope.interface.interface import InterfaceClass
from zope.publisher.interfaces.browser import (IDefaultBrowserLayer,
IBrowserRequest,
IBrowserPublisher,
@@ -274,7 +275,7 @@
# this needs to happen before any other grokkers execute that actually
# use the templates
martian.priority(1000)
-
+
def grok(self, name, instance, module_info, config, **kw):
templates = module_info.getAnnotation('grok.templates', None)
if templates is None:
@@ -634,19 +635,35 @@
return intids
-class SkinGrokker(martian.ClassGrokker):
- martian.component(grok.Skin)
- martian.directive(grok.layer, default=IBrowserRequest)
- martian.directive(grok.name, get_default=default_view_name)
+_skin_not_used = object()
- def execute(self, factory, config, name, layer, **kw):
+class SkinInterfaceDirectiveGrokker(martian.InstanceGrokker):
+ martian.component(InterfaceClass)
+
+ def grok(self, name, interface, module_info, config, **kw):
+ skin = grok.skin.bind(default=_skin_not_used).get(interface)
+ if skin is _skin_not_used:
+ # The skin directive is not actually used on the found interface.
+ return False
+
+ if not interface.extends(IBrowserRequest):
+ # For layers it is required to extend IBrowserRequest.
+ raise GrokError(
+ "The grok.skin() directive is used on interface %r. "
+ "However, %r does not extend IBrowserRequest which is "
+ "required for interfaces that are used as layers and are to "
+ "be registered as a skin."
+ % (interface.__identifier__, interface.__identifier__),
+ interface
+ )
config.action(
- discriminator=('skin', name),
+ discriminator=('utility', IBrowserSkinType, skin),
callable=zope.component.interface.provideInterface,
- args=(name, layer, IBrowserSkinType)
+ args=(skin, interface, IBrowserSkinType)
)
return True
+
class RESTProtocolGrokker(martian.ClassGrokker):
martian.component(grok.RESTProtocol)
martian.directive(grok.layer, default=IBrowserRequest)
Deleted: grok/trunk/src/grok/tests/conflict/skin.py
===================================================================
--- grok/trunk/src/grok/tests/conflict/skin.py 2008-08-02 11:38:21 UTC (rev 89197)
+++ grok/trunk/src/grok/tests/conflict/skin.py 2008-08-02 11:50:27 UTC (rev 89198)
@@ -1,17 +0,0 @@
-"""
-We cannot register two skins under the same name::
-
- >>> grok.testing.grok(__name__)
- Traceback (most recent call last):
- ...
- ConfigurationConflictError: Conflicting configuration actions
- For: ('skin', 'foo')
-"""
-
-import grok
-
-class Skin1(grok.Skin):
- grok.name('foo')
-
-class Skin2(grok.Skin):
- grok.name('foo')
Copied: grok/trunk/src/grok/tests/skin (from rev 89197, grok/branches/jw-simpler-skin-registration/src/grok/tests/skin)
Modified: grok/trunk/src/grok/tests/test_grok.py
===================================================================
--- grok/trunk/src/grok/tests/test_grok.py 2008-08-02 11:38:21 UTC (rev 89197)
+++ grok/trunk/src/grok/tests/test_grok.py 2008-08-02 11:50:27 UTC (rev 89198)
@@ -44,7 +44,7 @@
suite = unittest.TestSuite()
for name in ['adapter', 'error', 'view', 'event', 'security', 'catalog',
'zcml', 'static', 'utility', 'xmlrpc', 'json', 'container',
- 'traversal', 'form', 'grokker', 'directive',
+ 'traversal', 'form', 'grokker', 'directive', 'skin',
'baseclass', 'annotation', 'application', 'template',
'viewlet', 'testsetup', 'conflict', 'order']:
suite.addTest(suiteFromPackage(name))
More information about the Checkins
mailing list