[Grok-dev] Re: layers and skins

Martijn Faassen faassen at startifact.com
Fri Apr 20 07:35:40 EDT 2007

Philipp von Weitershausen wrote:
> Martijn Faassen wrote:
>> Even a Zope 3 developer won't be much misled if we use the word skin, 
>> I think, because I believe there are only a few Zope 3 developers with 
>> the detailed techno-historical information that you have. I certainly 
>> am somewhat fuzzy about the whole story in Zope 3 myself...
> Yeah, the Zope 3 story is fuzzy, no doubt, and I really want to make it 
> more straight-forward in Grok.
>> So, I'd still propose saying:
>> class MySkin(grok.Skin):
>>    grok.layer(IMyLayer)
>> registers IMyLayer as a skin. That is, IMyLayer can be accessed using 
>> a particular name in the URL.
> Ah, I get it. So if I had a bunch of layers that I'd like to combine to 
> a skin, I'd have to say:
>   class IMySkinLayer(IFirstLayer, ISecondLayer, IThirdLayer):
>       pass
>   class MySkin(grok.Skin):
>       grok.layer(IMySkinLayer)


> So the MySkin class with its grok.layer directive is just a marker to 
> actually register an already existing layer as a skin. Then how is this 
> better from
>   class IMySkinLayer(IFirstLayer, ISecondLayer, IThirdLayer):
>       pass
>   grok.register_skin(IMySkinLayer, 'myskin')
> ?

Because it is more consistent with the rest of grok. If we register an 
adapter as a view we don't just do something like 
grok.register_adapter() either. Granted there is a difference here as 
with adapters the class itself is registered, whereas here you register 
an external interface from your class. My argument is that the skin *not 
just* the layer but carries with it other information such as name, 
display name, presence in menu, heck, perhaps even permissions. I 
therefore think its own class makes sense.

We can use standard directives like grok.name. We don't rely on the name 
of the registered layer as the skin name - this concept is separated 
out. We will be able to apply future directives for display name and 
menu to skins just as we can to views. We can add methods to the skin 
that do post-processing in the future.

> Layers such as IDefaultBrowserLayer, zope.app.rotterdam.rotterdam, etc. 
> all extend IBrowserRequest because that's what they are marker 
> interfaces for, a browser request object.

Ah, I see. I hadn't realized they extend IBrowserRequest and had 
imagined them bare interfaces without any methods. I had imagined the 
request implemented IBrowserRequest and then got extended by directly 
providing layers on it as well.

>> Anyway, since this is too much of a lie whatever ILayer derives from, 
>> I propose we simply reuse grok.layer for saying what layer a skin 
>> uses. We say a skin is in a layer by using grok.layer. It's 
>> symmetrical with views.
> That sounds very confusing to me. We say a "skin is *in* a layer"? 
> Usually, skins are composed of multiple layers, so you could say that 
> multiple layers are in a skin, not the other way around.

You can have multiple skins for a single layer, I think? Not very common 
of course, but what will be common is a single layer showing up in 
multiple skins indirectly through layer inheritance.

> Using grok.layer doesn't seem very symmetrical at all to me.

>> The objection to that may be that skins in some ways don't feel 
>> symmetrical with views. Then again, there are so many parallels (name, 
>> layer, possible entry in a menu) that I think looking for symmetry 
>> between views and skins is in fact probably a *good* idea.
> I still don't see how skins and views are similar. They're almost 
> orthogonal to me. Sure, skins and views *might* happen to need/support 
> some similar data points for their registration. So, ok, we'll allow 
> those directives that make sense (grok.name and others, once we need 
> them) to work on both.

I'm not saying we should allow all directives on grok.Skin that we allow 
on grok.View. I'm just looking for similarities as a design strategy. 
Obviously there are differences. But thinking about how they are similar 
does give us ideas, like the reuse of grok.layer. Both have names in 
URLs. Both are about what the user sees.

grok.layer associates something with a layer. a view can be associated 
with a layer. a skin can also be associated with a layer. Typically you 
have way more views associated with a layer than skins of course, but 
the direction of association is the same. Since grok.layer can be used 
on module-level, sometimes you don't even have to mention the layer the 
skin is working for explicitly.



More information about the Grok-dev mailing list