[Grok-dev] grokcore.resource
Danilo G B
danilogbotelho at yahoo.com
Tue May 1 23:03:41 UTC 2012
I'd suggest another name for the directive like 'resources' (in the plural, as with 'permissions').
'includes' is probably too generic but makes a lot of sense to me.
Also, why include parents' resources for subclasses as the default behaviour? How to turn that off? I usually subclass layouts to change the needed resources. So, I'd suggest extending the 'resources' directive to have it accept resources and 'resource includers':
class Layout1(grok.Layout):
grok.resources(r1, r2)
class Layout2(Layout1):
grok.resources(Layout1, r3)
"In order to make this work for Layouts I don't see another way than
emitting an event right before the layout is rendered in
grokcore.layout:"
I haven't checked this, but can't you get the layout from the view being traversed to?
Maybe a solution which adds a method to the 'resource includers' makes this more easy and natural. I haven't thought this through. Lately I've been using a method named update_resources called from my layouts which is responsible for updating the resources required by each view. This allows for subclasses to decide whether use parents resources or not.
I hope we can reach an easy to use and natural way of including resources in Grok.
------------------------------
Message: 3
Date: Tue, 1 May 2012 10:42:56 +0200
From: Jan-Jaap Driessen <jdriessen at minddistrict.com>
To: Grok <grok-dev at zope.org>
Subject: [Grok-dev] grokcore.resource
Message-ID:
<CABk+M0B_rA+e7-aKFyWqY13EUDW4r0RbUb8qmj+x6ZtjpN14-g at mail.gmail.com>
Content-Type: text/plain; charset=ISO-8859-1
In the train back home from the grok sprint yesterday I took some
parts of megrok.resource [1] to combine with fanstatic [2] into
grokcore.resource [3].
With grokcore.resource you can make resources part of your View classes like so:
"""
class MyView(grok.View):
grokcore.resource.include(css_a, css_b)
"""
This is a handsome replacement of the "old" way of declaring resource,
often in the update method of the view:
"""
def update(self):
css_a.need()
css_b.need()
"""
(This "old" way is still supported.)
The "include" directive code looks like this:
"""
class include(martian.Directive):
scope = martian.CLASS
store = martian.MULTIPLE
validate = validateInclusion
def factory(self, *resources):
zope.interface.declarations.addClassAdvisor(
_resources_advice, depth=3)
return resources
def _resources_advice(cls):
if include.bind().get(cls):
if not grokcore.resource.interfaces.IResourcesIncluder.implementedBy(
cls):
zope.interface.classImplements(
cls,
grokcore.resource.interfaces.IResourcesIncluder)
return cls
"""
The result of using the "include" directive is that the class which it
is used on will be marked with a marker interface
"IResourcesIncluder".
We add an event listener for IBeforeTraverseEvent that will listen to
this interface and will need the resources at that time::
"""
@grokcore.component.subscribe(
grokcore.resource.interfaces.IResourcesIncluder,
zope.app.publication.interfaces.IBeforeTraverseEvent)
def handle_inclusion(includer, event):
includer = zope.security.proxy.removeSecurityProxy(includer)
needs = set()
# XXX Need to fix this?
for class_ in includer.__class__.__mro__:
if grokcore.resource.interfaces.IResourcesIncluder.implementedBy(class_):
father = zope.security.proxy.removeSecurityProxy(class_)
for resources in \
grokcore.resource.directives.include.bind().get(father):
needs.update(resources)
for resource in needs:
resource.need()
"""
I am not sure whether there is a smarter way of finding all resources
needed by a View if this View subclasses from another View. Maybe it
is just my limited understanding of how martian works. I need a second
pair of eyes here.
At this point, we can use grokcore.resource for grok.View classes, but
not yet for viewlets and on layouts (grokcore.layout).
In the zope.viewlet code, a BeforeUpdateEvent is sent, which we
subscribe to in grokcore.resource and need the resources for viewlets:
"""
@grokcore.component.subscribe(
grokcore.resource.interfaces.IResourcesIncluder,
zope.contentprovider.interfaces.IBeforeUpdateEvent)
def handle_inclusion(includer, event):
# Same inclusion code as before.
"""
In order to make this work for Layouts I don't see another way than
emitting an event right before the layout is rendered in
grokcore.layout:
"""
def __call__(self, view):
self.view = view
zope.event.notify(BeforeUpdateEvent(self, self.request))
self.update()
return self.render()
"""
Is this OK? We could make the event grokcore.layout specific of course.
I would appreciate your feedback on the questions above. Afterwards, I
can finish grokcore.resource (readme, tests for viewlet/layout) and
would like to integrate the directive in grok (the package) under the
name 'resource', so you can write:
"""
class MyView(grok.View):
grok.resource(css_a, css_b)
"""
Thanks for reading this far,
JJ
1) http://pypi.python.org/pypi/megrok.resource/0.5
2) http://fanstatic.org
3) http://svn.zope.org/grokcore.resource/trunk/
------------------------------
_______________________________________________
Grok-dev mailing list
Grok-dev at zope.org
https://mail.zope.org/mailman/listinfo/grok-dev
End of Grok-dev Digest, Vol 68, Issue 1
***************************************
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.zope.org/pipermail/grok-dev/attachments/20120501/94f2be56/attachment.html>
More information about the Grok-dev
mailing list