[Grok-dev] Re: Giving viewlets "the grok treatment"?

Martin Aspeli optilude at gmx.net
Sun May 11 07:25:22 EDT 2008


Hi Ethan,

> Well, I am actually building a somewhat pluggable UI, but with a
> fairly rigid and narrow set of "entry points" like "project creation
> options", "project info options", "user account options", etc.  So I
> don't need a whole lot of rich options about how things plug into
> those particular places, but I do need a way to aggregate and display
> an arbitrary number of UI plugins without knowing what they'll be.  I
> don't have very much experience with "vanilla" content providers; can
> they provide that aggregation for me by default?  (That is, without my
> writing extra code in the content provider which aggregates broadcast
> plugins before returning them to the template.)
 >
> I may be wrong, but my rough abstract understanding of viewlets and
> content providers is:
> 
>  * Content providers let you plug any, but not all, of (X, Y, Z, ...)
> into A, by allowing a single lookup on (context, request, view).
>  * Viewlets with viewlet managers let you plug any or all of (X, Y, Z,
> ...) into any or all of (A, B, C, ...), by allowing a single lookup on
> (context, request, view) for the viewlet manager which then does a
> multi-lookup on (context, request, view, manager).

Kind of, but I think there's an easier way to look at this.

  - zope.contentprovider is a low-level package. It defines an interface 
IContentProvider, which is a bit like an IBrowserView. It also defines a 
TAL expression type, "provider:", that lets you pull an IContentProvider 
into a template. It does so by looking up a named adapter on (context, 
request, view,) providing IContentProvider.

You can think of a "content provider" almost as a ZPT macro that's 
looked up (and thus can be overridden) via the adapter registry, and 
which has two-phase rendering (update, then render).

  - zope.viewlet uses zope.contentprovider to implement pluggable UIs. 
It defines an IViewletManager that is a special kind of 
IContentProvider. When using viewlets, you use e.g. 
tal:replace="structure provider:my.viewletmanger" in a template. That 
renders the viewlet manager with name "my.viewletmanger" that's 
appropriate for the current (context, request, view,).

  - This in turn will look up all viewlets that are registered for this 
viewlet manager and render them in order. The default implementation 
uses the adapter registry to look up IViewlet adapters registered for 
(context, request, view, viewlet_manager,), although other 
implementations are possible.

Thus, the viewlet manager/viewlet framework is a superset of the content 
provider mechanism.

 From what you described earlier, it looked like you were looking for a 
means to insert just a single "viewlet" into the page. That is, you were 
looking to compose your view from multiple pieces, each piece being its 
own, named, component. This is exactly what IContentProvider gives you. 
If you don't need the logic that locates and renders multiple viewlets 
inside a single "slot", then you're really after a simple content provider.

Another way to think about this is in terms of inversion-of-control. If 
you write tal:replace="structure provider:foo", and "foo" is a simple 
IContentProvider, then you're putting all control into the template. You 
are asking for a particular, named component to be pulled in. If "foo" 
is a viewlet manager, then you're just saying "here's a slot in my 
template, do whatever you want in it". The viewlet manager 
implementation is responsible for fiding the viewlets and rendering 
them, and third party code can potentially register new viewlets 
completely unbeknownst to your code.

To me, Grok could support "content providers" in a simple way by having 
a base class (by comparison, there's no explicit ZCML directive to 
create content providers as there is with viewlet managers and viewlets, 
although a properly constructed named multi-adapter will of course 
work). If you start out by having a content provider and you then want 
to switch to something more pluggable - a viewlet manager - it's a 
pretty easy refactoring.

> Viewlets with viewlet managers let you reuse the viewlets in any
> number of places,

In theory, yes, but if you use the <browser:viewlet /> directive, then 
note that you explicitly list the viewlet manager (by interface) that 
you want to plug into. Using a viewlet in more than one place requires 
two registrations with the default viewlet manager implementation.

> by abstracting a layer between the viewlet and the
> view, and allowing viewlets to associate with any number of managers
> which themselves associate with views.  This seems perfect for a
> general-purpose sort of system like Plone, where a single slot could
> be filled by six widgets, and a single widget could be inserted into
> six slots.  But for my far less general-purpose app, what I find that
> I really want is to plug any or all of (X, Y, Z, ...) into A.  In
> other words, I want any number of things to be "pluggably" inserted
> into a single template, but I don't need those things to be reused by
> other templates since my entry points are so specific.

Sure.

> So I'm not exactly proposing viewlets without viewlet managers --
> rather, I'm proposing viewlets with *hidden* viewlet managers, where
> Grok handles all the details of those viewlet managers, and as far as
> the end user is concerned the viewlets are just being plugged directly
> into views in a decoupled, but not reusable, way. 

I would be a bit cautious about this kind of magic. I don't really think 
it's necessary, at least not if Grok made it easy to make content providers.

If you're talking about having a one-to-one mapping between the name you 
invoke from your template (via the "provider:" expression type) and the 
name you give a visual component, then you really want an 
IContentProvider, not an IViewlet.

If you're talking about inverting the locus of control so that you just 
declare a "slot" and you let other parts of the code worry about what 
goes into it, then I think you want to make that explicit, with an 
explicit viewlet manager.

Martin

-- 
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book



More information about the Grok-dev mailing list