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



Reply via email to