| Author |
Message |
![[Post New]](/rsf/templates/default/images/icon_minipost_new.gif) 25/04/2006 13:39:51
|
stevegithens
Request-scope Wrangler
Joined: 04/04/2006 20:34:52
Messages: 84
Location: ooeepooee
Offline
|
I'm trying to do some ajax stuff and am wondering the appropriate way to specify a different file extension for my template file.
If I have a viewId and java based producer, "ajaxreq", it automatically looks for ajaxreq.html (or in my case sakai-ajaxreq.html). I would like it to look for ajaxreq.xml instead.
In the future I'd also like to use other extensions like *.xul.
Thanks!
|
|
|
 |
![[Post New]](/rsf/templates/default/images/icon_minipost_new.gif) 25/04/2006 14:35:40
|
antranig
Request-scope Wrangler
Joined: 03/04/2006 13:29:55
Messages: 643
Offline
|
The key customisation point here is the viewTemplateResolver - the default definition in RSF from blank-applicationContext.xml is as follows:
Code:
<bean id="viewTemplateResolver"
class="uk.org.ponder.rsf.templateresolver.BasicTemplateResolver">
<property name="baseDirectory">
<value>/content/templates/</value>
</property>
<property name="consumerInfo">
<ref bean="consumerInfoProxy" />
</property>
</bean>
I'm imagining this will be prime grounds for user-defined customisation, since TemplateResolver is a prime RSF OLI:
Code:
public interface TemplateResolver {
public ViewTemplate locateTemplate(ViewParameters viewparams);
}
As you've noticed, the BasicTemplateResolver operates a simple 2-step strategy which first looks for any ConsumerRequestInfo which might provide a template file prefix, and then looks up a file with named after the viewId (possibly with prefix) in the baseDirectory with the .html suffix.
From what you're saying, it sounds like you will want to look up different viewIds to different suffixes. This currently isn't implemented but as you see BasicTemplateResolver is fairly straightforward and easy to provide alternate implementations. That said, we should talk about how you would like to specify your mappings from viewID to extension (I guess in some kind of XML file) and I will refactor BasicTemplateResolver to make it easier for people to provide their own. Until you came along I had no real idea what sort of template resolution people would actually want so I left this stuff quite basic
Just in time to get this in for 0.6.1.
|
|
|
 |
![[Post New]](/rsf/templates/default/images/icon_minipost_new.gif) 03/05/2006 17:47:26
|
stevegithens
Request-scope Wrangler
Joined: 04/04/2006 20:34:52
Messages: 84
Location: ooeepooee
Offline
|
Back to the Ajax stuff.
Looking at blank-applicationContext:
Code:
<bean id="viewTemplateResolver"
class="uk.org.ponder.rsf.templateresolver.BasicTemplateResolver">
<property name="templateExtensionInferrer" ref="templateExtensionInferrer"/>
<property name="templateResolverStrategy" ref="templateResolverStrategy"/>
</bean>
<bean id="templateExtensionInferrer"
class="uk.org.ponder.rsf.templateresolver.StaticTemplateExtensionInferrer">
<property name="extension" value="html"/>
</bean>
<bean id="templateResolverStrategy" class="uk.org.ponder.rsf.templateresolver.CRITemplateResolverStrategy">
<property name="baseDirectory">
<value>/content/templates/</value>
</property>
<property name="consumerInfo">
<ref bean="consumerInfoProxy" />
</property>
</bean>
It looks like what I should do is write my own TemplateResolverStrategy and TemplateExtensionInferrer, then redeclare ViewTemplateResolver in my webapps applicationContext, still using uk.org.ponder.rsf.templateresolver.BasicTemplateResolver, but with my custom strategy and inferrer.
Does this make sense?
|
|
|
 |
![[Post New]](/rsf/templates/default/images/icon_minipost_new.gif) 03/05/2006 18:10:14
|
antranig
Request-scope Wrangler
Joined: 03/04/2006 13:29:55
Messages: 643
Offline
|
You only need to implement a TemplateExtensionInferrer (interface) and redeclare templateExtensionInferrer (bean). That is assuming you're happy with the default choice of baseDirectory.
If I understand you right, the point of confusion is whether the bean references from viewTemplateResolver are happy to resolve "up" the stack to your own tEI, and the answer is yes they are - overrides happen on a bean-by-bean basis.
|
|
|
 |
![[Post New]](/rsf/templates/default/images/icon_minipost_new.gif) 03/05/2006 18:20:49
|
stevegithens
Request-scope Wrangler
Joined: 04/04/2006 20:34:52
Messages: 84
Location: ooeepooee
Offline
|
That's great ( that I don't have to redeclare the Resolver .
I will probably override both of them though, so I can put different gallery examples in different directories.
|
|
|
 |
![[Post New]](/rsf/templates/default/images/icon_minipost_new.gif) 03/05/2006 21:04:56
|
stevegithens
Request-scope Wrangler
Joined: 04/04/2006 20:34:52
Messages: 84
Location: ooeepooee
Offline
|
K. I've got it looking up my files with different extensions and have been able to perform some simple Ajax requests, with a caveat.
Here is the xml file I have my viewId hooked up to:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<ajax>Some text</ajax>
The string I'm getting back in the response is:
Code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><ajax>Some text</ajax>
This is the response text from:
Code:
function onSuccess(t)
{
alert("Success: " + t.responseText);
}
How do I get RSF to switch up the DOCTYPE? I'm guessing it's probably in RSF, because when I've done Ajax by hand with strings, nothing ever got prepended.
|
|
|
 |
![[Post New]](/rsf/templates/default/images/icon_minipost_new.gif) 03/05/2006 22:35:30
|
antranig
Request-scope Wrangler
Joined: 03/04/2006 13:29:55
Messages: 643
Offline
|
Oops! I forgot about the actual "rendering" part of handling AJAX requests...
I suggest for now you adopt the following Very Bad Practice and derive from the HTMLRenderSystem which is responsible for handling leaf components for IKAT.
Like this:
Code:
public class MultiRenderSystem extends HTMLRenderSystem {
public void setViewParameters(ViewParameters viewparams) {
this.viewparams = viewparams;
}
public void setTemplateExtensionInferrer(TemplateExtensionInferrer inferrer) {
this.inferrer = inferrer;
}
public String getDeclaration() {
String extension = inferrer.inferTemplateExtension(viewparams);
return extension.equals("html")? super.getDeclaration() : "";
}
}
Then declare this in your requestContext.xml file with the following definition:
Code:
<bean id="renderSystem"
class="yourpackage.MultiRenderSystem">
<property name="staticRenderers" ref="staticRenderers" />
<property name="viewParameters" ref="viewParameters" />
<property name="templateExtensionInferrer" ref="templateExtensionInferrer"/>
</bean>
I'll sort you out something better for 0.6.2/0.7 - in particular note that HTMLRenderSystem will be blasted to small pieces in 0.7 so I won't be able to avoid improving it
Yes, I'd generally forgotten about the RenderSystem aspect of AJAX - but as long as you stick to the non-HTML-specific types of component - UIOutput, UIVerbatim and UIBranchContainer, you should be fine.
|
|
|
 |
![[Post New]](/rsf/templates/default/images/icon_minipost_new.gif) 04/05/2006 00:23:01
|
stevegithens
Request-scope Wrangler
Joined: 04/04/2006 20:34:52
Messages: 84
Location: ooeepooee
Offline
|
I'm generally getting things to work. I had to make the definitions as 'bean' and not 'local'. I'm assuming this won't make a difference? ( I don't have to redefine those again locally correct?)
I'm getting some sort of NullPointerException on each Ajax call, which looks like it might be related to RSF's Sakai integration, but I'm still looking into it.
Some interesting behavior:
This template file:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<ajax rsf:id="value">Some text</ajax>
and this producer:
Code:
public class SimpleajaxXMLProducer implements ViewComponentProducer {
public String getViewID() {
return "simpleajax-xml";
}
public void fillComponents(UIContainer arg0, ViewParameters arg1, ComponentChecker arg2) {
UIOutput.make(arg0, "value", "Value from Producer");
}
}
produce the following response:
Code:
<ajax id="value">Value from Producer</ajax>
So the value is getting substituted, but the id sans rsf namespace remains.
|
|
|
 |
![[Post New]](/rsf/templates/default/images/icon_minipost_new.gif) 04/05/2006 00:31:04
|
antranig
Request-scope Wrangler
Joined: 03/04/2006 13:29:55
Messages: 643
Offline
|
Yes, sorry I went back and edited the definition behind your back to remove the "locals" which used to be there from cut 'n paste
Yes, the id, derived from the paths of rsf:id throught the template, will remain... the idea is that every element in the document will get a unique id assigned that gets touched by IKAT.
If you think it would be useful I could put in an option to suppress them when we have Renderer Reform in 0.7.
|
|
|
 |
![[Post New]](/rsf/templates/default/images/icon_minipost_new.gif) 04/05/2006 00:37:29
|
stevegithens
Request-scope Wrangler
Joined: 04/04/2006 20:34:52
Messages: 84
Location: ooeepooee
Offline
|
Here is the trace from up above. I think it may be the result of not using the correct URL from JavaScript calls...
I'm not even close to connecting the correct way yet, and am still just hacking along with:
Code:
requrl = "http://localhost:8080" + urlref + "/faces/simpleajax-xml?panel=main";
alert('The Requrl: ' + requrl);
new Ajax.Request(requrl, {onSuccess: onSuccess, onFailure: onFailure});
Code:
2006-05-03 18:13:46,409 INFO (RSACUtils.java:40) - <Got rsacbg uk.org.ponder.rsac.RSACBeanLocator@8222635>
2006-05-03 18:13:46,431 INFO (ServletEarlyRequestParser.java:28) - <begin parseRequest>
2006-05-03 18:13:46,447 INFO (PostDecoder.java:64) - <PostInit: key panel value main>
2006-05-03 18:13:46,469 INFO (SakaiEarlyRequestParser.java:42) - <Beginning ToolSinkTunnelServlet service with
requestURL of http:!!localhost:8080/portal/tool/92b97927-8e6d-435c-80f8-9162908d5f58/faces/simpleajax-xml
and extra path of /simpleajax-xml>
2006-05-03 18:13:46,841 ERROR (RSFActionHandler.java:213) - <Error invoking action>
java.lang.NullPointerException
at uk.org.ponder.rsf.processor.PostDecoder.decodeSubmittingControl(PostDecoder.java:140)
at uk.org.ponder.rsf.processor.RSFActionHandler.handle(RSFActionHandler.java:209)
at uk.org.ponder.rsf.processor.RSFActionHandler$$FastClassByCGLIB$$a2f2c5e.invoke(<generated>)
at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:149)
at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:635)
at uk.org.ponder.rsf.processor.RSFActionHandler$$EnhancerByCGLIB$$b13e123b.handle(<generated>)
at uk.org.ponder.rsf.servlet.RootHandlerBean.handlePost(RootHandlerBean.java:113)
at uk.org.ponder.rsf.servlet.RootHandlerBean.handle(RootHandlerBean.java:81)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java(Compiled Code))
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java(Compiled Code))
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java(Compiled Code))
at java.lang.reflect.Method.invoke(Method.java(Compiled Code))
at uk.org.ponder.reflect.JDKReflectiveCache.invokeMethod(JDKReflectiveCache.java:27)
at uk.org.ponder.reflect.JDKReflectiveCache.invokeMethod(JDKReflectiveCache.java:21)
at uk.org.ponder.reflect.JDKReflectiveCache.invokeMethod(JDKReflectiveCache.java:81)
at uk.org.ponder.rsac.RSACBeanLocator.createBean(RSACBeanLocator.java:457)
at uk.org.ponder.rsac.RSACBeanLocator.getLocalBean(RSACBeanLocator.java:293)
at uk.org.ponder.rsac.RSACBeanLocator.getBean(RSACBeanLocator.java:310)
at uk.org.ponder.rsac.PerRequestInfo$1.locateBean(PerRequestInfo.java:46)
at uk.ac.cam.caret.sakai.rsf.servlet.ReasonableSakaiServlet.service(ReasonableSakaiServlet.java:65)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:672)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:463)
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:359)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:301)
at org.sakaiproject.component.kernel.tool.ActiveToolComponent$MyActiveTool.forward(ActiveToolComponent.java:333)
at org.sakaiproject.portal.charon.CharonPortal.forwardTool(CharonPortal.java:1233)
at org.sakaiproject.portal.charon.CharonPortal.doTool(CharonPortal.java:1185)
at org.sakaiproject.portal.charon.CharonPortal.doPost(CharonPortal.java:856)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at org.sakaiproject.util.RequestFilter.doFilter(RequestFilter.java:535)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:856)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:744)
at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:80)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
at java.lang.Thread.run(Thread.java:570)
2006-05-03 18:13:46,954 INFO (SakaiRequestParser.java:105) - <Got tool dispatcher id of sakai.rsf.gallery
resourceBaseURL http:!!localhost:8080/ChemTopics/
baseURL http:!!localhost:8080/portal/tool/92b97927-8e6d-435c-80f8-9162908d5f58/faces/
and Sakai PID 92b97927-8e6d-435c-80f8-9162908d5f58>
2006-05-03 18:13:46,983 INFO (RootHandlerBean.java:130) - <Redirecting to
http:!!localhost:8080/portal/tool/92b97927-8e6d-435c-80f8-9162908d5f58/faces/simpleajax-xml?endflow=1&panel=Main>
2006-05-03 18:13:46,995 INFO (RSACUtils.java:40) - <Got rsacbg uk.org.ponder.rsac.RSACBeanLocator@8222635>
2006-05-03 18:13:47,003 INFO (ServletEarlyRequestParser.java:28) - <begin parseRequest>
2006-05-03 18:13:47,008 INFO (SakaiEarlyRequestParser.java:42) - <Beginning ToolSinkTunnelServlet service with
requestURL of http:!!localhost:8080/portal/tool/92b97927-8e6d-435c-80f8-9162908d5f58/faces/simpleajax-xml
and extra path of /simpleajax-xml>
SWG: GalleryTemplateResolverStrategy
2006-05-03 18:13:47,075 INFO (SakaiRequestParser.java:105) - <Got tool dispatcher id of sakai.rsf.gallery
resourceBaseURL http:!!localhost:8080/ChemTopics/
baseURL http:!!localhost:8080/portal/tool/92b97927-8e6d-435c-80f8-9162908d5f58/faces/ and Sakai PID 92b97927-8e6d-435c-80f8-9162908d5f58>
SWG: Item> /content/templates/sakai-simpleajax-xml
SWG: Item> /content/templates/simpleajax-xml
SWG: GalleryTemplateExtensionInferrer
SWG: View> simpleajax-xml
2006-05-03 18:13:47,081 INFO (CachingInputStreamSource.java:90) - <Trying to load from path /content/templates/sakai-simpleajax-xml.xml>
SWG: GalleryRenderSystem
SWG: GalleryTemplateExtensionInferrer
SWG: View> simpleajax-xml
SWG:
[Edited AMB to fit width]
|
|
|
 |
![[Post New]](/rsf/templates/default/images/icon_minipost_new.gif) 04/05/2006 02:29:48
|
antranig
Request-scope Wrangler
Joined: 03/04/2006 13:29:55
Messages: 643
Offline
|
This is caused by sending a non-RSF POST request through the RSF action cycle. Actually the cycle ends up working "just fine" since the default ARI on a n Action request simply redirects to the same view in a Render cycle, with some error parameters added. For better performance with non-RSF POSTs you should register a HandlerHook and process them yourself.
|
|
|
 |
|
|