(Small note: This package may very well be renamed in the near future).

On day 2 of the Paris Sprint Godefroid and me worked on plone.grok, making specific grokkers for some Plone things. Yesterday we make a grokker for GenericSetup import steps, and today we made a grokker for portlets in Plone. Or, well, during the afternoon we did. Before lunch we mostly talked politics. Well, sprints are supposed to be fun too, right!? :-)

So did we succeed? Yes, we did, and here is the proof:

OK, it doesn’t look like much, and the Python code do do this is still a but more complicated than I think is necessary, but we need to discuss with both Grok and Plone people to figure out how it should best be done, and what simplifications we can do.

Here is the code to create the above portlet:

from plone import grok
from zope.interface import Interface
from zope.interface import implements

class IExamplePortlet(Interface):
    pass

class Renderer(grok.Renderer):
    def render(self):
        return self.data.title

class ExamplePortlet(grok.Portlet):
    implements(IExamplePortlet)
    grok.provides(IExamplePortlet)
    grok.name('ExamplePortlet')
    grok.portlet_renderer(Renderer)

    title = "This is my fantastic portlet"

As you see, it’s a simplification from the current way, and best of all: There is no ZCML needed. You still need the GenericSetup profiles portlet.xml, though. I want to get rid of that too, but I want to hear from Plone people if they want it as well.


  1. Jon Stahl

    Bravo! I see the dawn of a new day for Plone “approachability!” :-)

  2. Martin Aspeli

    Hi Lennart,

    This absolutely rocks. :-)

    Just a few minor points:

    * plone.grok sounds a bit too generic a name for me. In general, we reserve the plone.* namespace for things that are re-usable outside Plone (either with plain Python, plain Zope 3, plain Zope2/Five or plain CMF - in that order of preference) and use plone.app.* for Plone integration.

    If this is a “Grok” compatibility later for Plone, then it should be plone.app.grok. If it’s about grokker for Plone, then I’m not sure we need the name “Grok” (which is really a brand for a particular development framework) in the package name at all.

    Furthermore, the name “Renderer” is rather too generic as well. Obviously, it’s used in the context of portlet renderers here, but there’s nothing in the naming of plone.grok.Renderer that implies that.

    My preference would be to just put this in plone.app.portlets. We already have plone.app.portlets.portlets.base; I would suggest a package similar to that, or even to use that, if it can be done in a backwards-compatible way. Note that this would need to go into a branch and be PLIP’d for 3.2.

    If this will work with the plone plone.portlets package (which has dependencies only on Zope 3 and is used by Vudo as well), then it could be in plone.portlets.

    * I think generic Grokkers for Zope2 (e.g. for views, local adapters, local utilities etc) should be in five.something. I think that’s the case already, just checking.

    * Are we thinking to go down a filename-based matching of templates to renderers? Perhaps for a template-only portlet, you don’t need the Renderer class at all, if there is a template that matches the portlet name?

    * Why do we have both implements() and grok.provides()? They seem like the same thing.

    * Is there any support for overriding the add and edit views explicitly? I think there’d need to be, so that you can e.g. customise widgets

    * I think the name grok.Portlet (apart from the namespace, as per above) *may* be misleading. I assume it maps to a portlet assignment type. A “portlet” really is “an assignment + a renderer”. I’m willing to be convinced that grok.Portlet is clearer, though.

    Once again, though - I’m really excited about this!

    Martin

  3. Martijn Faassen

    Cool!

    I agree with Martin that this shouldn’t be called ‘grok.Renderer’ and ‘grok.Portlet’, as these are not Grok concepts at present. Let’s call these base classes ‘portlets.Renderer’ and ‘portlets.Portlet’ or something like that

    As discussed on the mailing list, the ‘grok’ namespace shouldn’t become some magical word that everything is in for easy access. I realize that this is really the ‘plone.grok’ namespace, but the impression the code gives here is that these things are available in Grok proper, and they’re not.

  4. Philipp von Weitershausen

    This is great news, Lennart. I knew this wouldn’t be difficult, but it’s great to see somebody’s doing it!

    However, I would also like to reiterate what I’ve been saying a lot of times already: frameworks and libraries that re-use grokcore.* and martian shouldn’t use the brand “Grok”. “Grok” is a web framework, not a technology (the technology is Martian). I would very much like the brand “Grok” to remain exclusively for Grok-the-web-framework.

    Also, the “from plone import grok” line is easily ignored, making the following code using grok.* easy to confuse with proper Grok code. All the more reason to come up with a new name, or even better, extend the already existing libraries (plone.portlet, etc.) to make use of martian and grokcore.component technology.

  5. Lennart Regebro

    Loads of great points here:

    On naming: Yes, plone,grok is not a good name. It came to be because of five.grok, which just ended up as the logical name (we tried other, but that just didn’t seem right).

    As pointed out, we might not need a plone.*.grok at all, but instead for most of it use base classes that already exists, and for the rest maybe we should crate the baseclasses even if they are empty? I wouldn’t mind putting it into plone.app.portlet, in fact I think it’s a great idea. I’m not sure what to do with the ImportStep, though. Maybe there should be a Products.GenericSetup.ImportStep class for example? The question is how to get that to work without GenericSetup requireing grokcore.component. (Not that I mind… ;)

    So plone.grok should away. If we want to call five.grok something else, suggestions must be made. We couldn’t come up with anything that made sense.

    “* Are we thinking to go down a filename-based matching of templates to renderers? Perhaps for a template-only portlet, you don’t need the Renderer class at all, if there is a template that matches the portlet name?”

    I think that would be a good idea.

    “* Why do we have both implements() and grok.provides()? They seem like the same thing.”

    It’s a testing artefact, we wanted to test that provides() worked.

    “* Is there any support for overriding the add and edit views explicitly? I think there’d need to be, so that you can e.g. customise widgets”

    Not yet, but there should be.

    I’m not sure what to do about the Assignment/Portlet thing. As mentioned otherwise, people expect to create Portlet class, and it’s very confusing that none actually exists when you create a portlet.

Leave a Comment