PDF::Writer and Ruby on Rails 2.2.2

November 24, 2008 by Michael

If you followed the instructions here and used the method named PDF::Writer (Austin Ziegler), you we’re out of luck when Rails 2.1 appeared.

With Rails 2.2.2 once again the rendering mechanism seems to have changed big time and my previous post on how to make the pdf/writer gem work with a custom template handler doesn’t work anymore.

With the help of Josh Peek i was able to fix this. He gave me the following code to enable a rpdf template handler with pdf-writer:

module ActionView # :nodoc:
  require 'pdf/writer'
  class PDFRender < ActionView::TemplateHandler
    PAPER = 'A4'
    include ApplicationHelper                     
    include ActionView::Helpers::TranslationHelper
    include ActionView::Helpers::AssetTagHelper
    include ActionView::Helpers::TextHelper
    include ActionView::Helpers::TagHelper
    include ActionView::Helpers::UrlHelper
 
    def self.call(template)
      "ActionView::PDFRender.new(self).render(template, local_assigns)"
    end
 
    def initialize(action_view)
      @action_view = action_view
    end
 
    # Render the PDF
    def render(template, local_assigns = {})
      @action_view.controller.headers["Content-Type"] ||= 'application/pdf'
 
      # Retrieve controller variables
      @action_view.controller.instance_variables.each do |v|
        instance_variable_set(v,
        @action_view.controller.instance_variable_get(v))
      end
 
      pdf = ::PDF::Writer.new( :paper => PAPER )
      pdf.compressed = true if RAILS_ENV != 'development'
      eval template.source, nil, ''
 
      pdf.render
    end
  end
end
 
ActionView::Template.register_template_handler 'rpdf', ActionView::PDFRender

Just drop this under config/initializers and you’re fine.

8 comments

  1. Robert Wahler wrote:

    Thanks for posting this, it helped me update to 2.2.2. I could only get this to work in development however. If config.cache_classes is true as in production and test, the handler is never registered. I fixed this by moving your code to a plugin and out of lib and environment.rb.

    -robert

    Posted on December 2, 2008 at 3:10 PM | Permalink
  2. Michael wrote:

    You’re welcome.

    Strange, i’m using it in production and just double checked if cache_classes is turned on.

    It’s in a file config/initializers/PDFRender.rb

    Hm…

    Cheers,
    Michael.

    Posted on December 2, 2008 at 3:17 PM | Permalink
  3. Thanks for the patch.

    I got it to work, mostly, but I had to modify it.

    I replaced your render method with the original one from railspdf.rb, keeping the next-to-last line (eval template…) from your version of the method.

    # eval template, nil, “#{@action_view.base_path}/#{@action_view.first_render}.#{@action_view.pick_template_extension(@action_view.first_render)}”
    #2.1 eval template.source, nil, “#{@action_view.base_path}/#{@action_view.first_render}.#{@action_view.pick_template_extension(@action_view.first_render)}”
    eval template.source, nil, ”

    This allowed me to use @rails_pdf_name and “keep ie happy”.

    Before I added that code, Firefox displayed the PDF as text in the browser. IE wouldn’t allow it to be viewed, and opened a download dialog with a warning:

    “The file you are downloading cannot be opened by the default program. It is either corrupted or it has an incorrect file type. As a security precaution it is recommended that you cancel the download…”

    When I saved the downloaded file, I could open it normally with Acrobat Reader.

    After I restored most of the render method, IE worked normally, but Firefox did not recognize it as a PDF. I had to select Acrobat Reader manually to open the file, and when I did I saw that it had appended “.htm” to the file name.

    This was in my development environment, with Rails 2.2.2 under Windows XP, using the WEBrick server. It’s working fine (with the 2.1 patch) deployed on a Linux box running Mongrel and Rails 2.1.2. I’m going to try downgrading to 2.1.2 Rails on my workstation. I’m having a problem writing to Postgresql tables too.

    Posted on December 3, 2008 at 11:04 PM | Permalink
  4. Michael wrote:

    Hey John,
    you’re welcome.

    Is it the same plugin you’re using?

    For me its working with cygwin/win32 (using mongrel) and mac os x (mongrel as well).

    Also, works in FF and IE, PDF is displayed inline, not as dl.

    Cheers,
    Michael.

    Posted on December 4, 2008 at 4:11 PM | Permalink
  5. I’m using pdf-writer 1.1.8.

    My pdf might have displayed inline if I had the Adobe Reader browser plugin installed, but I didn’t want to require that of my users.

    Must be some subtle problem with the new Rails on native Windows OS. I’m not using Cygwin.

    Downgrading Rails on my workstation to 2.1.2 works (with the patch for Rails 2.1). That also fixed the problem I was having with writing to Postgresql tables.

    Posted on December 4, 2008 at 5:19 PM | Permalink
  6. Michael wrote:

    Weird, as said in the following post…

    Never got rmagick to work with native windows so i use cygwin.

    Windows dev: pdf-writer 1.1.7

    OS X dev + Debian prod: pdf-writer 1.1.8

    Posted on December 4, 2008 at 5:22 PM | Permalink
  7. Jonathan wrote:

    I don’t suppose you have some insight on how to get pdf-writer templates working on rails 3.1? I was getting the errors to change but not able to actually get PDFs to render.

    Thanks,
    -Jonathan

    Posted on July 19, 2011 at 9:00 AM | Permalink
  8. Michael wrote:

    Hi Jonathan,

    the short answer is now, sorry.

    The longer version:
    i’ve stopped using Rails with version 2.3.5. Rack and Rails have severe bugs that didn’t get fixed and with 3.x i wdidnould have to rewrite at last halve of my application. Pdf-Writer was one of the things that didn’t work anymore.

    Posted on July 19, 2011 at 9:21 AM | Permalink
Post a Comment

Your email is never published. We need your name and email address only for verifying a legitimate comment. For more information, a copy of your saved data or a request to delete any data under this address, please send a short notice to michael@simons.ac from the address you used to comment on this entry.
By entering and submitting a comment, wether with or without name or email address, you'll agree that all data you have entered including your IP address will be checked and stored for a limited time by Automattic Inc., 60 29th Street #343, San Francisco, CA 94110-4929, USA. only for the purpose of avoiding spam. You can deny further storage of your data by sending an email to support@wordpress.com, with subject “Deletion of Data stored by Akismet”.
Required fields are marked *