cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Daniel Fagerstrom <dani...@nada.kth.se>
Subject Re: [RT] composition vs. inheritance in blocks
Date Thu, 31 Mar 2005 09:51:53 GMT
Ralph Goers wrote:

> Daniel Fagerstrom wrote:
>
>> Ok, I'll give you a new example trying to explain the concept. Let's 
>> start with the portal block and say that I want to use that for my 
>> app, MyPortal, but I want a different skin. The skin consists of the 
>> stylesheet "styles/portal-page.xsl" among other things. We assume 
>> that the designer of the portal block wanted to make the skin 
>> overridable so there is a sitemap rule that exposes the stylesheet in 
>> the Portal block.
>>
>> <match pattern="styles/portal-page.xsl">
>>   <read src="default-portal-page.xsl"/>
>> </match>
>>
>> Now I let MyPortal extends Portal and reimplements the stylesheet in 
>> MyPortal
>>
>> <match pattern="styles/portal-page.xsl">
>>   <read src="my-portal-page.xsl"/>
>> </match>
>>
>> and thanks to polymorphism the user of MyPortal will get 
>> "my-portal-page.xsl" when asking for "styles/portal-page.xsl" and 
>> everything else will be delivered from Portal.
>
>
> Normally, I try to avoid these "theoretical" posts, but since you are 
> picking on the portal...  Frankly, if the way you are proposing this 
> was actually how the portal worked we would not be using it.  Luckily, 
> to do what you are suggesting is as simply as doing something like:
>
> <map:match pattern="styles/portal-page.xsl">
>  <map:read 
> src="{globalConfig:/global-variables/skin}styles/portal-page.xsl"/>
> </map:match>
>
> I understand you were trying to make a point, but sometimes I feel 
> like these diatribes resort to using a sledgehammer where a simple 
> screwdriver would do the job nicely.

I based my example on the portal as Carsten asked about how one could 
use blocks for skins and for the portal (although my example didn't 
answer his questions). I also chosed it, to make the discussion less 
theoretical as it in the end is about highly practical things. And I 
doubt that we will ever get to the "real blocks", if we don't discuss 
and get feedback on practical usage.

Now I'm aware that the portal samples use the construction you show 
above, but it doesn't achieve exactly the same thing as the construction 
I propose. If you want to use a slightly modified skin, I would assume 
that you start by copying the +30 files from skins/commons and then 
point "global-variables/skin" to the new location and start to modify 
whatever you wanted to modify.

With my solution you just copy the file, in this case "portal-page.xsl" 
that you actually want to modify and write an overriding sitemap rule to 
use it. After having used thing like the global variable trick for a 
number of years in various applications, we had a tremendous amonount of 
different generations of esentially the same files and numerous copies 
of slightly modified sitemap snippets. Hardly supprising it was a 
maintainance nightmare. After having start to use the pattern that I 
propose we have seen a drastic decrease in the number of files in our 
new applications.

So is it complicated? Not particular. As we use it in our apps we would 
write:

<map:match pattern="styles/portal-page.xsl">
 <map:read src="cocoon://{request:sitemapPath}/styles/portal-page.xsl"/>
</map:match>

in the reusable portal sitemap. The "cocoon://{request:sitemapPath}/" 
prefix "absolutizes" the URI so that it will be searched from the root 
sitemap and a sitemap that mounts the portal sitemap can modify the 
behaviour by writing an alternative rule for an uri. request:sitemapPath 
is new in 2.2, so in 2.1 one need to write a module that makes 
Environment.getURIPefix() available.

When you want to resue and modify the behaviour of the reusable portal 
sitemap you write a new sitemap:

...
<pipeline>
  <match pattern="styles/portal-page.xsl">
    <read src="my-portal-page.xsl"/>
  </match>

  <mount uri-prefix="" src="context://block/portal"/>
</pipeline>

If this mechanism was used in the portal, there could be a small base 
portal with overridable example configurations and example data, in the 
portal jar. And a new portal user could start trying it as simple as:

<pipeline>
  <mount uri-prefix="" src="resource://org/apache/cocoon/portal/site"/>
</pipeline>

and the incrementally add own behaviour while always having a working 
portal. Today I would assume that a typical new user start by copying 
the demo and goes from there. It works, but it mean that they after a 
while they have several copies of base functionality in different portal 
based webapps, that they need to maintain and maybe synchronize with 
improvements in new Cocoon versions.

                                     --- o0o ---

My aim is to make this mechanism or something equally powerful part of 
the blocks.

/Daniel


Mime
View raw message