I've done the data processing part of a task and am now coming up how
best to capture the output. In this particular scenario, the output
will be a pdf that will then get saved to the file system and sent out
via an email. I'm planning on creating html that I'll then use
cfdocument to convert to a pdf. Since this is fundamentally output,
I'm thinking that I ought to put the html generation in a view then
use RenderView to capture the output in my controller as a content
variable, then feed it to cfdocument and save to the file system.
What are people's thoughts on that approach? Better ideas?
Hi Judahh, look at the Utilities plugin, it has some methods that do that already for you.
I'm not quite sure which methods you mean Luis. You mean for the
"saving to the file system" part?
Look at the sendFile() method.
This is what I did:
Create an handler which sets vars in request collection scope (e.g.
vars from your services).
This handler has a method event.setView(''myPDF",true)
The second argument disables the layout to render.
Create a view with CFdocument tag and you're done.
Sure you can also create a PDF file, store it on disk, send it as
email and stream it to the browser using the utilities plugin.
It's up to you.
Ah, I see. Sorry, I wasn't clear on what I was going to do with it
then. I'm actually going to email the document off and a bunch of
other processing, I won't be rendering the pdf to the browswer. The
sendFile() method is cool though.
My question was wondering about capturing the data to create the pdf,
not what to do with the pdf data. I went ahead and used the
renderView() function which was fine but then I realized that it
didn't have any style info associated with it because it didn't
include my layout. Hmmm.
So how would I best capture the combination of layout and view to put
into a content variable?
You can use style links in your PDF, or you can create a special
layout for your PDF.
See custom layouts in the docs.
Thanks, I am using a special layout the issue is grabbing the content
of the layout + the view which I just realized is what the
renderLayout() function seems to do. But I can't seem to invoke it
properly. Is it not bound off of event the same way that renderView()
I.E., I was running myvar = event.renderView(); but I need the
layout as well so I was trying myvar = event.renderLayout()
I see the spec for it in coldbox_2_6_2.coldbox.system.plugins which is
where renderView() is also defined, but when I call renderLayout() it
throws an error about not finding that function.
You can use RenderView because it's an facade in the frameWorkSuperType class.
RenderLayout isn't, because it's part of the core of ColdBox.
Can you please explain again what you want...
Ah, thanks Ernst, I figured it was something like that that I missed
in the documentation.
As for what I am trying to do, I have a layout set up with my css to
format content nicely in a way that will hopefully be happy with
cfdocument. Then that layout calls renderview() as you would expect.
Browse to something like index.cfm?event=statement.pdf and it will
show up in html fine. Now, I want to capture the same content (layout
+ view) into a content variable that I can put into cfdocument and
save to a system file. It would be the equivalent of doing an http
call to http://localhost/index.cfm?event=statement.pdf
That any more clear?
Okay, that makes sense....
There are two options:
1. Forget the layout stuff and just create 3 views: 1 for the header,
1 for the footer and 1 with the cfdocument tag.
In the last one you call the header and the footer using renderView.
Do not forget to disable layout rendering in your handler.
2. Create an interceptor which has an function PreRender.
In this function you have access to the interceptor data structure,
which has a key 'renderedContent'.
Do your stuff there and cfabort.
Does PreRender happen before or after the execution of the controller?
After rendering the pdf and saving it to the file system, I still need
to look up an emaill address, create an email and send off the pdf as
an attachment. I'd like to keep all that logic in the controller if I
can and not move it out to an interceptor. But I would guess that the
renderedContent variable wouldn't be available until after the event
handler has finished running in the controller.