| Author |
Message |
![[Post New]](/rsf/templates/default/images/icon_minipost_new.gif) 24/10/2008 15:06:12
|
jimeng
Request-scope Wrangler
Joined: 11/07/2006 17:41:40
Messages: 84
Offline
|
In the confluence page on "Writing and Using SuperHelpers in Sakai" (http://bugs.sakaiproject.org/confluence/display/SAKDEV/Writing+and+using+SuperHelpers+within+Sakai), Antranig mentions the problem of getting the appropriate scripts (and css files, for that matter) included in a page when rendering a div within that page. I'd like to throw out an idea and see what you think.
Suppose we have an EntityProvider, "BlipProvider", that implements CRUDable. We also have a SuperHelper that renders UI's as an HTML fragments to create, revise or view a Blip, and the rendered elements require their own Javascript file and CSS file.
Now suppose our BlipProvider impl also implements two interfaces named "RequiredScriptProvider" and "RequiredLinkProvider". RequiredScriptProvider has a method something like this:
Code:
public Collection<String> getRequiredScriptUrl(...);
I'm not sure what the params would be ... maybe the mode ("new", "edit", etc) or maybe an entity-reference?
The webapp that wants to enable creation of Blips would call BlipProvider.getRequiredScriptUrl(...) and get URL's for any required scripts and include appropriate script tags in the head tag of the page. It would need to avoid duplicate tags. We'd need canonical sources for things like jquery and make sure dependencies are handled correctly. RequiredLinkProvider would be similar but simpler (since collisions are not as problemmatic).
Would something like this work? Any suggestions about the best way to do this?
Thanks.
Jim
|
|
|
 |
![[Post New]](/rsf/templates/default/images/icon_minipost_new.gif) 24/10/2008 15:25:16
|
jimeng
Request-scope Wrangler
Joined: 11/07/2006 17:41:40
Messages: 84
Offline
|
Maybe I have the method in the wrong place. When rendering the page, the EntityViewParamsInferrer provides a URL for the helper, like this:
Code:
public ViewParameters inferDefaultViewParameters(String reference) {
return new SimpleViewParameters(TestHelperProducer.VIEW_ID);
}
Maybe TestHelperProducer (rather than BlipProvider) is the class that needs to implement an interface to specify needed scripts and css files?
|
|
|
 |
![[Post New]](/rsf/templates/default/images/icon_minipost_new.gif) 24/10/2008 15:38:54
|
antranig
Request-scope Wrangler
Joined: 03/04/2006 13:29:55
Messages: 643
Offline
|
Probably the best place for this behaviour is in Javascript. In Fluid, we are actively working on an infrastructure for parsing and reforming incoming markup elements in this way, for a start because it is simply needed for our testing and QA procedures. Really, every supplier of markup for a <div> or whatever should supply along with it include directives for any scripts which it requires within the markup itself. For those demands which are made by subsidiary templates for a block, RSF already provides a mechanism for packaging these, by means of annotating a specially marked <div> with the annotation rsf:id="scr=head-collect" - you can see an earlier forum enquiry about this at
http://ponder.org.uk/rsf/posts/list/244.page
As it stands, browsers will not automatically evaluate scripts in blocks injected in this way via AJAX, but this can be achieved by the RSF.evaluateScripts function which is automatically invoked by its AHAH machinery. This function is currently underperformant since it fetches the required scripts via AJAX, and recent research has shown that they can be much more quickly and synchronously invoked by injecting their URLs into the document <head> - this is something we will make library support for in the Fluid release following 0.6.
I hope this is helpful, sorry to ramble as usual
Antranig.
|
|
|
 |
![[Post New]](/rsf/templates/default/images/icon_minipost_new.gif) 24/10/2008 16:10:03
|
jimeng
Request-scope Wrangler
Joined: 11/07/2006 17:41:40
Messages: 84
Offline
|
Is there documentation for this somewhere? I see an example of markup in the other page you referenced, but I don't see how it relates to a script tag. Is the point that you have a div with rsf:id="scr=head-collect" and then place a script tag inside it that gets moved to the head at some point?
There's some discussion of timing and performance issues related to this feature. Does the magic happen during rendering of the page or when an RSF ajax script is invoked on that part of the page?
|
|
|
 |
![[Post New]](/rsf/templates/default/images/icon_minipost_new.gif) 24/10/2008 16:20:54
|
antranig
Request-scope Wrangler
Joined: 03/04/2006 13:29:55
Messages: 643
Offline
|
Well, no, what happens at render time is, RSF dumps the whole heap of <script> tag references that have been dynamically demanded by the component set you have actually used into the <div> where you have written "head-collect". That is, they are physically written into the rendered markup. It is then the responsibility of the client to detect these and execute them "in a suitable manner" - since the browser will not automatically execute them by itself.
At the moment the "suitable manner" is by RSF.evaluateScripts which as I mentioned is asynchronous and a bit slow. We hope in the end to have a better "suitable manner" based on injecting them into <head> after suitable deduplication - you may be able to work on this yourselves in the meantime
|
|
|
 |
![[Post New]](/rsf/templates/default/images/icon_minipost_new.gif) 24/10/2008 16:23:30
|
jimeng
Request-scope Wrangler
Joined: 11/07/2006 17:41:40
Messages: 84
Offline
|
I see an example here:
https://saffron.caret.cam.ac.uk/svn/projects/RSFPortletSamples/trunk/HibernateCookbook/portlet/src/webapp/content/templates/layout.html
but there son't seem to be any script tags there.
|
|
|
 |
![[Post New]](/rsf/templates/default/images/icon_minipost_new.gif) 24/10/2008 16:28:48
|
antranig
Request-scope Wrangler
Joined: 03/04/2006 13:29:55
Messages: 643
Offline
|
The script tags are not written in the (root) template, but they are synthesised (actually simply aggregated) by RSF and injected into the final markup. It is one of the few cases where RSF will directly intervene and write some markup which was not directly present already (or rather, which was not present in the same place - all it is really doing is aggregating the <script> tags from the subcomponent templates which were previously marked with scr=contribute-script or scr=contribute-style into the overall output document).
|
|
|
 |
![[Post New]](/rsf/templates/default/images/icon_minipost_new.gif) 24/10/2008 16:59:55
|
jimeng
Request-scope Wrangler
Joined: 11/07/2006 17:41:40
Messages: 84
Offline
|
Sorry I'm so dense, but this seems backward to me. The layout.html template referenced above renders a div, and it has a placeholder div with rsf:id="scr=head-collect", while the portlet-recipes.html template ( https://saffron.caret.cam.ac.uk/svn/projects/RSFPortletSamples/trunk/HibernateCookbook/portlet/src/webapp/content/templates/portlet-recipes.html) renders a page and it has a style tag in head with rsf:id="scr=contribute-style" and a script tag in head with rsf:id="scr=contribute-script". I'd think the template for an html-fragment would be the contributor and the template for a full document would be the collector.
The only documentation I've found so far is here: http://rsf.fluidproject.org/wiki/Wiki.jsp?page=StaticComponentRenderer. Do you know of any other documentation that walks through an example?
|
|
|
 |
![[Post New]](/rsf/templates/default/images/icon_minipost_new.gif) 24/10/2008 17:18:34
|
antranig
Request-scope Wrangler
Joined: 03/04/2006 13:29:55
Messages: 643
Offline
|
OK, well what is going on here is that the "aggregation" is happening on the server for this particular pair of participants. I think what is confusing you is the recursive nature of the relations - here, "layout" is playing the role of the top-level recipient of the markup, which is, for example, what is sent out using the helper, or, in this case, a JSR-168 Portlet, and "recipe" is playing the role of a *server*-aggregated bit of "sub-markup", which in your cases might be representative of some kind of sub-component like FCKEdit or whatever, which demands some form of Javascript dependency which cannot be expected to be known statically by the overall producer.
So it is not the layout->recipe aggregation relationship which is the model for your "top level page"->"helper" model, but actually the layout itself which would take the role of the helper template in your situation.
I hope this helps a little - sorry there is no very strong documentation on the SCR system but I don't think overall it is particularly relevant here, since a "StaticComponentRenderer" is just the name for a generalised kind of rule which transforms markup, in the absence of a particular component in the component tree. These things can do practically anything, from rewriting a URL to inferring an id. I think it is the particular nature of the head-collect, contribute-script and contribute-style set that we are interested in here. Probably the best thing is to keep on asking questions
|
|
|
 |
|
|