Ugo Cei wrote:
Il giorno 06/gen/05, alle 01:54, Daniel Fagerstrom ha scritto:
The requested resource will often be based on some content or combination of content that we can access from Cocoon. The content can be a file, data in a db, result from a business object etc. Let us assume that it resides in some kind of content repository. Now if we think about it, isn't it more natural to ask the content, that we are going to use, about its propertiies like type, format, status, access rights, etc, than to encode it in the URL? This properties can be encoded in the file name, in metadata in some property file, within the file, in a DB etc. Now instead of having the rule:
*.x.y.z ==> XYZPipeline
we have
* where repository:{1} have properites {x, y, z} ==> XYZPipeline
or
* where repository:{1}.x.y.z exists ==> XYZPipeline
We get the right pipeline by querying the repository instead of encoding it in the URL. A further advantage is that the rule becomes "listable" as the "where" clause in the match expresses what are the allowed values for the wildcard.
Unless I misinterpret what you mean, we already can do this:
<map:match pattern="*"> <map:call function="fun"> <map:parameter name="par" value="{1}"/> </map:call> </map:match>
function fun() {
var entity = repo.query("select * from entities where id = " + cocoon.parameters.par + " and {x, y, z}");
cocoon.sendPage("views/XYZPipeline", { entity : entity });
}
<map:match pattern="XYZPipeline">
<map:generate type="jx" src="xyz.jx.xml"/>
...
</map:match>
My example was a little bit unclear what I meant was that you could have a number of sitemap rules:
* where repository:{1} have properites {x, y, z} ==> XYZPipeline * where repository:{1} have properites {a, b, c} ==> ABCPipeline * where repository:{1} have properites {a, b, d} ==> ABDPipeline
Which rather would correspond to:
<map:match pattern="*" where="repository:{1} have properites {x, y, z}" type="property">
<!-- call XYZPipeline -->
</map:match>
<map:match pattern="*" where="repository:{1} have properites {a, b, c}" type="property">
<!-- call ABCPipeline -->
</map:match>
etc
That would be rather inneficient in the current sequencial search based sitemap, while it could be efficient in a tree based matcher.
Apart from the obviously contrived example, isn't the Flowscript just what we need to "get the right pipeline by querying the repository"?
You could implement that above example by putting the property based switch in a flowscript instead, thats true. My own experience with using a flowscript as switchboard, have made me believe that it is an anti patern that should be avoided. But maybe other people have been luckier.
One of my aims with the RT was to make the sitemap more usable as a map over the site, by making it tree structured and more declarative. From that view using flowscripts instead of sitemaps is a step in the wrong direction IMO.
I would propose to go even further, in the "real" site map it should only be allowed to call VPC pipelines, no pipeline construction is allowed, that should be done in the component area.
In my sitemaps, public pipelines contain almost only <map:call> and <map:read> (for static resources) elements. All "classical" generator-transformer-serializer pipelines go into an "internal-only" pipeline that can be called from flowscripts only.
Admittedly, this is fine for webapps, and maybe not so much for publishing-oriented websites. But what I want to point out is that your otherwise very well thought-out RT is incomplete if it doesn't take Flowscript in consideration, IMHO.
I hoped that no one would notice, and that we could discuss the publish oriented stuff before handling such complications ;)
But you are completely right, flowscripts must also be discussed. This breaks down in two parts: how do we design a cool URL space for a flowscript driven webapp, and how do we implement such a URL space in Cocoon. Does what we have give good support or do we need new mechanisms?
I'll try to say something about cool URLs for flowscripts and leave the second part to another time or as a rather non trivial exercise for the interested reader ;)
Cool URLs for webapps =====================
Ok, I continue to uncritically assume that the guidelines in http://www.w3.org/TR/2003/NOTE-chips-20030128/ are good and try to apply them on the current situation. Given that, I don't consider:
12345.cont
particulary cool. No way back at all after your web-continuations have expired. Sometimes that might be the most reasonable response that is available. But we could do better than always using it.
When planning the URL space for the webapp, all allowed access points to the webapp must be given a "cool" URL. Let us say that we have a wizard and that users only are allowed to access it from the first screen when they don't have a valid session. in this case we could have:
wizard
as URL to the start point and
wizard?cont=12345
as URL to a screen within the session. If that URL is bookmarked and used after the expiration of the continuation, the user will get a permanent redirect to the "wizard" URL as response, possibly with an "session expired" message in the respons page.
If we follow this idea, we can think of our webapps in a transaction oriented way. Each time we have "commited a transaction" in our flowscript we could give a "cool" URL for the next screen in the flow (if it is allowable as a starting point). Now, this is a little bit tricky as the user probably made a post to something like:
wizard?cont=23456
where the transaction was committed, and that the flow could continue to "wizard2" or "wizard3" depending on user choice. This could maybe be solved by doing a redirect to the new wizard.
If we are creating a persistent object in the wizard we can take it further if we want to. Then we start the wizard the object is given an id:
123456/wizard
then we can go back to a wizard initialized from the object later. If we want to use some other identification after the object is commited, we have to save a mapping from the initial id to the correct one and do a permanent redirect when the URL is accesed. If we don' like going to a wizard we do a permanent direct to something more relevant. We could even let the user go back to specific pages for persistent objects:
123456/wizard/3
for such cases there are not much use in having a continuation id at all in the URL except if we want to let the user having multiple instances of the same page with different content.
If we follow the URL style without continuation IDs we use the session for differing between users instead.
--- o0o ---
How much work you should spend in creating "cool" URLs in your webapp, varies of course from application to application. I just wanted to point out that we can do more than 123456.cont if we want to. I have used more than one webapp that goes through many "transactions" during use, but force me to start the navigation from some start screen if my session expires. At least I would found such applications more userfriendly if they had used "cooler" URIs.
If you think that reusable URLs is a good idea, not only in publishing oriented sites but in webapps as well, you will need to have more external URLs and your webapp will get more in common with publishing oriented sites.
/Daniel