Gary, I wanted to thank you for your well-thought-out post just before
Christmas. I have attributes on my custom component now that support
selecting HTML or PDF, popup window or embedded, for reports. The embed
option (I ended up using an OBJECT tag) with a separate servlet serving up
the PDF avoided the need for extra renderkits for the PDF. The pop-up
options worked out well also. Thanks for pointing me in the right
directions.
I have been enjoying Clay the more I learn about how to use it. Good
stuff...
----- Original Message -----
From: "Gary VanMatre" <[EMAIL PROTECTED]>
To: <[email protected]>
Sent: Sunday, December 24, 2006 10:04 AM
Subject: Re: Question about custom component and PDF
>From: "Steve Olson" <[EMAIL PROTECTED]>
I'm new to Clay, and just slightly less new to JSF. I'm experimenting
with a
JSF custom component that renders an eclipse BIRT report. I'm using Clay
HTML
views in a webapp that among other things needs to render various
reports. I'm
not using any JSP, so didn't bother with a JSP tag for this component.
BIRT reports can either be rendered as embedded HTML, or as a PDF. I
think I
understand how everything works rendering HTML. My question is with
rendering a
report to PDF - the content is no longer HTML and the response content
type has
to be application/pdf. So my custom component based on UIComponentBase
that
works fine with embeded HTML won't work for PDF. If an attribute on this
component indicates a PDF rendering is desired, what's a good strategy
for
implementing this? One thought that comes to mind is rendering javascript
back
in the HTML response, that would pop up a separate window, and have that
served
by a separate URL handled outside of Clay/JSF. Are there better
alternatives
for handling this? I know very little about custom RenderKits or other
options,
and would appreciate it if anyone is interested in pointing me in other
directions.
Thanks in advance for any tips...
If you are using full clay views (no-jsp), the clay view handler assumes
the content
type of the response to be "text/html". That's if a content type has not
already been set.
This is one of those todo items.
Although, I think you could set the response's content
type to "application/pdf" in a view controllers prerender event. Or,
create a JSP page
that sets the content type, has a f:view tag and a single clay component.
You can change the render kit per view using the f:view tag's
"renderKitId" attribute,
but it applies to the entire page - all components in the view. Clay
allows you to do
this using the "f:view". It just needs to be some place in the page -
unlike the jsp tag
that has to be a root. <span view="f:view"
renderKitId="org.acme.mypdfkit"/>
If you created a html markup renderer for your component and also a PDF
renderer,
you would need to register them in the faces config under different render
kits.
<render-kit>
<render-kit-id>org.acme.mypdfkit</render-kit-id>
<renderer>
<component-family>org.acme.mycomponent</component-family>
<renderer-type>org.acme.mycomponent</renderer-type>
<renderer-class>org.acme.mycomponentPdfRenderer</renderer-class>
</renderer>
<render-kit>
<render-kit>
<!-- default -->
<renderer>
<component-family>org.acme.mycomponent</component-family>
<renderer-type>org.acme.mycomponent</renderer-type>
<renderer-class>org.acme.mycomponentRenderer</renderer-class>
</renderer>
<render-kit>
I've always liked to see the PDF documents embeded in html. If you are
able to embed the
document, you could make a component attribute for documentType (html or
pdf). The renderer
could generate an html embed tag with a src that pointed to a servlet.
The render could save
the document to a map in session scope. The key used to store the
document in the session
map could be added as a query parameter to the src of the embed tag. So,
the servlet only
needs to look for the query parameter and use it as the key into the
document's cache. Next,
push the cached document to the response and set the content type.
<EMBED width="672" height="500" border="2"
src="/contextRoot/embedDoc;jsessionid=xxx?token=123"
type=application/pdf >
Another approach would be to use the Trinidad internal view handler versus
a servlet.
With the internal view handler, you can map a custom view hander to a view
id.
So, if your view id was "/embedDoc", you could delegate to an internal
view handler
that could create a component tree specifically addressing your needs.
They use this
to complement some of the trinidad components that need popup dialogs. I
have an
example of this in the shale sandbox.
Properties file to register the mapping between viewId and internal view
handler:
http://svn.apache.org/viewvc/shale/sandbox/shale-clay-trinidad/src/main/resources/META-INF/org.apache.myfaces.trinidad.render.InternalView.properties?view=log
View handler:
http://svn.apache.org/viewvc/shale/sandbox/shale-clay-trinidad/src/main/java/org/apache/shale/clay/PageHandler.java?view=log
Your popup idea would also work nicely with this library. They make it
very
easy to attach script files. Here's an example of sending script to the
browser
(@ "loadHtmlFragment" method):
http://svn.apache.org/viewvc/shale/sandbox/shale-clay-trinidad/src/main/java/org/apache/myfaces/trinidad/blank/CatalogBacking.java?view=markup
Sounds like a fun project. Hope that gives you some ideas.
Gary