<html><body><div style="color:#000; background-color:#fff; font-family:times new roman, new york, times, serif;font-size:14pt">I'd suggest another name for the directive like '<span style="font-weight: bold;">resources</span>' (in the plural, as with 'permissions').<br><br>'includes' is probably too generic but makes a lot of sense to me.<br><br>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':<br><br>class Layout1(grok.Layout):<br>&nbsp;&nbsp;&nbsp; grok.resources(r1, r2)<br><br>class Layout2(Layout1):<br>&nbsp;&nbsp;&nbsp; grok.resources(Layout1, r3)<br><br><font style="font-style: italic;" size="3">"In order to make this work for Layouts I don't see another way than<br>emitting an event right before the layout is rendered
 in<br>grokcore.layout:"</font><br><br>I haven't checked this, but can't you get the layout from the view being traversed to?<br><br>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 <span style="font-weight: bold;">update_resources</span> 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.<br><br>I hope we can reach an easy to use and natural way of including resources in Grok.<br><div><span><br></span></div><div> ------------------------------<br></div>  <div style="font-family: times new roman, new york, times, serif; font-size: 14pt;"><div style="font-family: times new roman, new york, times, serif; font-size: 12pt;"><br>Message: 3<br>Date: Tue, 1 May 2012 10:42:56 +0200<br>From: Jan-Jaap Driessen &lt;<a
 ymailto="mailto:jdriessen@minddistrict.com" href="mailto:jdriessen@minddistrict.com">jdriessen@minddistrict.com</a>&gt;<br>To: Grok &lt;<a ymailto="mailto:grok-dev@zope.org" href="mailto:grok-dev@zope.org">grok-dev@zope.org</a>&gt;<br>Subject: [Grok-dev] grokcore.resource<br>Message-ID:<br>&nbsp;&nbsp;&nbsp; &lt;CABk+M0B_rA+e7-aKFyWqY13EUDW4r0RbUb8qmj+<a ymailto="mailto:x6ZtjpN14-g@mail.gmail.com" href="mailto:x6ZtjpN14-g@mail.gmail.com">x6ZtjpN14-g@mail.gmail.com</a>&gt;<br>Content-Type: text/plain; charset=ISO-8859-1<br><br>In the train back home from the grok sprint yesterday I took some<br>parts of megrok.resource [1] to combine with fanstatic [2] into<br>grokcore.resource [3].<br><br>With grokcore.resource you can make resources part of your View classes like so:<br><br>"""<br>class MyView(grok.View):<br>&nbsp; &nbsp; grokcore.resource.include(css_a, css_b)<br>"""<br><br>This is a handsome replacement of the "old" way of declaring
 resource,<br>often in the update method of the view:<br><br>"""<br>&nbsp; &nbsp; def update(self):<br>&nbsp; &nbsp; &nbsp; &nbsp; css_a.need()<br>&nbsp; &nbsp; &nbsp; &nbsp; css_b.need()<br>"""<br><br>(This "old" way is still supported.)<br><br>The "include" directive code looks like this:<br><br>"""<br>class include(martian.Directive):<br>&nbsp; &nbsp; scope = martian.CLASS<br>&nbsp; &nbsp; store = martian.MULTIPLE<br>&nbsp; &nbsp; validate = validateInclusion<br><br>&nbsp; &nbsp; def factory(self, *resources):<br>&nbsp; &nbsp; &nbsp; &nbsp; zope.interface.declarations.addClassAdvisor(<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _resources_advice, depth=3)<br>&nbsp; &nbsp; &nbsp; &nbsp; return resources<br><br>def _resources_advice(cls):<br>&nbsp; &nbsp; if include.bind().get(cls):<br>&nbsp; &nbsp; &nbsp; &nbsp; if not grokcore.resource.interfaces.IResourcesIncluder.implementedBy(<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
 cls):<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; zope.interface.classImplements(<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cls,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; grokcore.resource.interfaces.IResourcesIncluder)<br>&nbsp; &nbsp; return cls<br>"""<br><br>The result of using the "include" directive is that the class which it<br>is used on will be marked with a marker interface<br>"IResourcesIncluder".<br>We add an event listener for IBeforeTraverseEvent that will listen to<br>this interface and will need the resources at that time::<br><br>"""<br>@grokcore.component.subscribe(<br>&nbsp; &nbsp; grokcore.resource.interfaces.IResourcesIncluder,<br>&nbsp; &nbsp; zope.app.publication.interfaces.IBeforeTraverseEvent)<br>def handle_inclusion(includer, event):<br>&nbsp; &nbsp; includer = zope.security.proxy.removeSecurityProxy(includer)<br>&nbsp; &nbsp; needs = set()<br>&nbsp; &nbsp; # XXX Need to fix this?<br>&nbsp;
 &nbsp; for class_ in includer.__class__.__mro__:<br>&nbsp; &nbsp; &nbsp; &nbsp; if grokcore.resource.interfaces.IResourcesIncluder.implementedBy(class_):<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; father = zope.security.proxy.removeSecurityProxy(class_)<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for resources in \<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; grokcore.resource.directives.include.bind().get(father):<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; needs.update(resources)<br>&nbsp; &nbsp; for resource in needs:<br>&nbsp; &nbsp; &nbsp; &nbsp; resource.need()<br>"""<br><br>I am not sure whether there is a smarter way of finding all resources<br>needed by a View if this View subclasses from another View. Maybe it<br>is just my limited understanding of how martian works. I need a second<br>pair of eyes here.<br><br>At this point, we can use grokcore.resource for grok.View classes, but<br>not yet for viewlets and on
 layouts (grokcore.layout).<br><br>In the zope.viewlet code, a BeforeUpdateEvent is sent, which we<br>subscribe to in grokcore.resource and need the resources for viewlets:<br><br>"""<br>@grokcore.component.subscribe(<br>&nbsp; &nbsp; grokcore.resource.interfaces.IResourcesIncluder,<br>&nbsp; &nbsp; zope.contentprovider.interfaces.IBeforeUpdateEvent)<br>def handle_inclusion(includer, event):<br>&nbsp; &nbsp; # Same inclusion code as before.<br>"""<br><br>In order to make this work for Layouts I don't see another way than<br>emitting an event right before the layout is rendered in<br>grokcore.layout:<br><br>"""<br>def __call__(self, view):<br>&nbsp; &nbsp; self.view = view<br>&nbsp; &nbsp; zope.event.notify(BeforeUpdateEvent(self, self.request))<br>&nbsp; &nbsp; self.update()<br>&nbsp; &nbsp; return self.render()<br>"""<br><br>Is this OK? We could make the event grokcore.layout specific of course.<br><br>I would appreciate your feedback on the questions
 above. Afterwards, I<br>can finish grokcore.resource (readme, tests for viewlet/layout) and<br>would like to integrate the directive in grok (the package) under the<br>name 'resource', so you can write:<br><br>"""<br>class MyView(grok.View):<br>&nbsp; &nbsp; grok.resource(css_a, css_b)<br>"""<br><br>Thanks for reading this far,<br><br>JJ<br><br>1) <a href="http://pypi.python.org/pypi/megrok.resource/0.5" target="_blank">http://pypi.python.org/pypi/megrok.resource/0.5</a><br>2) <a href="http://fanstatic.org" target="_blank">http://fanstatic.org</a><br>3) <a href="http://svn.zope.org/grokcore.resource/trunk/" target="_blank">http://svn.zope.org/grokcore.resource/trunk/</a><br><br><br>------------------------------<br><br>_______________________________________________<br>Grok-dev mailing list<br><a ymailto="mailto:Grok-dev@zope.org" href="mailto:Grok-dev@zope.org">Grok-dev@zope.org</a><br><a href="https://mail.zope.org/mailman/listinfo/grok-dev"
 target="_blank">https://mail.zope.org/mailman/listinfo/grok-dev</a><br><br><br>End of Grok-dev Digest, Vol 68, Issue 1<br>***************************************<br><br><br> </div> </div>  </div></body></html>