[Grok-dev] grokcore.resource

Souheil CHELFOUH trollfot at gmail.com
Tue May 1 12:24:57 UTC 2012


Hi JJ,

The Layout is "constructed" in the Page component __call__.
You could also trigger the event there, which would at least free the
Layout from that, but on the other hand makes it harder for Page
components to be implemented from scratch, since they'd have to know
you have to do this.
To avoid a subscriber and include the resource of the layout, you can
resolve the resources declared by the layout in the view __call__.
Either way, this will require modifications in the grokcore.layout
package, the most generic one being an event, and the handler would be
in your app code... I guess :)

2012/5/1 Jan-Jaap Driessen <jdriessen at minddistrict.com>:
> 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


More information about the Grok-dev mailing list