TemplateHandler Changes from 2.1 to 2.2


#1

I’ve been attempting to get the prawnto (template wrapper around
“prawn”, a native ruby PDF generator) working under Rails 2.2.

Repo is here: http://github.com/thorny-sun/prawnto/tree/master

To start off, I set it up and it gives an “unknown method ‘compile’”
error.

So, as far as I can tell between Rails 2.1 -> 2.2, TemplateHandlers
have switched from outputting their template code in a “render”
method, to outputting code to be compiled in a “compile” method.

Prawnto as it stands now doesn’t support the compile method, but I’d
like to build that functionality in if possible.

Question is: does anyone know of any resources for Rails 2.2 on the
net that might speak to building a TemplateHandler, and/or updating
the output function from “render” to “compile”?

Thanks for your time,
Brady


#2

On 13 Nov 2008, at 21:10, brady8 removed_email_address@domain.invalid wrote:

have switched from outputting their template code in a “render”
method, to outputting code to be compiled in a “compile” method.

If you asked over on the rubyonrails-core mailing list I’d be
surprised if the people who made those changes didn’t chip in

Fred


#3

Hey,

I just checked out your source and it looks like your already on the
right track.

Right now you are handling the eval with “@view.instance_eval source,
template.filename, 1”. The compile method will actually handle this
for you and make sure the same template doesn’t need to be eval’d
twice.

Instead of returning a string from render, return your “source” string
and it will be taken care of for you.


#4

Here is a good example to get you started.

http://gist.github.com/25022


#5

Yes, you source will get compiled into a ruby method and it will just
run that instead. Its much faster.

Let me know if there are any other issues you run into. Just email me
“josh at joshpeek dot com”.


#6

Thanks Josh!

That’s great, and should definitely get me on track to getting this
working.
I’m wondering though why Rails has moved to using compiled code? Is
there really any performance benefit when the code being compiled is
ruby code itself?

Regards,
Brady


#7

On Dec 11, 8:46 am, thorny_sun removed_email_address@domain.invalid wrote:

so are you saying now that ruby source is somehow getting run faster
since it is getting “compiled”. I’m very confused. What if we take
the builder template as an example (since prawnto template handler
works very similarly in that it is just ruby code) – is there any
speed gain expected by “compiling” it? Or did I just misunderstand?

In most cases, you going to have to compile it no matter what. In your
prawnto template handler you directly call @view.instance_eval source, template.filename, 1. While this works, you are rebuilding
and reevaling the template ever run. This is really slow. You could
make this optimizations internally, but ActionView can take care of
all this for you if you just return the source from the handler
instead.


#8

Hey Josh,
Appologies for the late entry to this thread – finally getting around
to making prawnto template handler plugin work with 2.2.
But in this thread you seem to contradict what I thought you had told
me earlier in a github message:

josh said 3 months ago:

Your right! There is nothing to compile. However we
do wrap the template with some ActionController
helpers. We also need to convert it to a string so
we can eval it later with the proper local assigns.

you’ll be helping make prawnto even better :slight_smile:

-thorny_sun

so are you saying now that ruby source is somehow getting run faster
since it is getting “compiled”. I’m very confused. What if we take
the builder template as an example (since prawnto template handler
works very similarly in that it is just ruby code) – is there any
speed gain expected by “compiling” it? Or did I just misunderstand?

thanks for the help!
-thorny_sun


#9

This should work:

“pdf = Prawn::Document.new; pdf.instance_eval
do\n#{template.source}\nend”

This string will get eval’d into a method. Big difference between it
actually running. AV will create something like this for you:

def _pdf_app_views_docs_show
pdf = Prawn::Document.new
pdf.instance_eval do
# the actual template source will be here
text “Hello, World”
end
end

On Mon, Dec 15, 2008 at 5:45 AM, thorny_sun removed_email_address@domain.invalid
wrote:

Soooo-- I’m assuming that having the “pdf.instance_eval” in the eval’d

make this optimizations internally, but ActionView can take care of
all this for you if you just return the source from the handler
instead.


Joshua Peek


#10

I get it-- perfect-- thanks!

another minor question: It seems you prefer to have the source
surrounding the “template.source” be separated by semicolons rather
than newlines? I see you’ve also gotten rid of the line count
property. I assume that is to keep things simple and bug reported
line numbers accurate? But what if there is an issue with the first
line number-- wouldn’t that come back with a lot of extra stuff (in my
case the surrounding code is very long and would come back with a very
uselessly long string) – or am I missing something again?

-thorny_sun


#11

Correct, the line offset thing is gone. So I’d recommend you wrap your
block “pdf.instance_eval { … }” so the line numbers are correct.

On Mon, Dec 15, 2008 at 12:49 PM, thorny_sun removed_email_address@domain.invalid
wrote:

uselessly long string) – or am I missing something again?

On Mon, Dec 15, 2008 at 5:45 AM, thorny_sun removed_email_address@domain.invalid wrote:

Soooo-- I’m assuming that having the “pdf.instance_eval” in the eval’d

so are you saying now that ruby source is somehow getting run faster
all this for you if you just return the source from the handler
instead.


Joshua Peek


Joshua Peek


#12

Josh,

ah ok-- I get it now – thanks so much for helping me understand!

follow up question: I also have an option where the user can specify
a template to be run as if it were inside a pdf.instance_eval where
pdf is just the Prawn::Document object. This makes the template more
compact, since the user avoids having to type “pdf.” all the time.
(i.e. “pdf = Prawn::Document.new; pdf.instance_eval template.source;”)
Soooo-- I’m assuming that having the “pdf.instance_eval” in the eval’d
string kinda defeats the benefits of using compile? Could I get
around this by mimicking the compile paradigm and creating a method
and calling that method within the string to be eval’d?

thanks so much for the help!
-thorny_sun


#13

Hello,

I am wondering whether the template handler issue has been fixed for
Rails 2.2.X Is there a work around?

Greetings and thanks for the great plugin.

Michael K.