TemplateHandler Changes from 2.1 to 2.2

I've been attempting to get 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'"

Looking through the code, as well as Rails...

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
someone's blog or otherwise, that speak to the changes made to
TemplateHandler in Rails, and how to update a plugin from "rendering"
to "compiling" to match?

Thanks for your time,


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

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

Here is a good example to get you started.


Thanks Josh!

That's great, and should definitely get me on track to getting this
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?


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".

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.

Hey Josh!
I’m trying to better understand rails compiled templates,
and I was hoping you might spare a minute to help. I
understand the point of compiling ERB, for instance,
cuz you can save time by not having to translate to
ruby code everytime. BUT I don’t understand why you
would want to make builder compiled? A builder template
would already be ruby code, so is there another
advantage here I’m missing? thanks for the help!
you’ll be helping make prawnto even better :slight_smile:


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!

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


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!

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"

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?


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


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 Kastner