Footer in pdf_from_string #69

Closed
clod81 opened this Issue Dec 21, 2011 · 5 comments

2 participants

@clod81

I'm using wicked_pdf pdf_from_string inside an action mailer rails 3 model.
The pdf render perfectly doing this:

attachments["pdf.pdf"] = WickedPdf.new.pdf_from_string(
render_to_string(:pdf => "pdf.pdf",:template => 'documents/show.pdf.erb')
)

When I try to pass the option :footer, it does not work with these options:

attachments["pdf.pdf"] = WickedPdf.new.pdf_from_string(
render_to_string(:pdf => "pdf.pdf", :template => 'pdf/pdf.html.erb', :layout => 'pdfs/pdf',
:footer => {:html => {:template => 'pdf/pdf_footer.html.erb', :layout => 'pdfs/pdf'}, :spacing => -65})
)

Note that :footer option works sweet inside a controller, coming from a controller default 'render' :pdf method.

I ended up doing something like this, but I'd prefer not using gotchas.

File.open("/tmp/wicked_pdf_#{@model.number}.html", 'w+b', 0644) { |f|
f.write render_to_string({:template => 'pdf/pdf_footer.html.erb', :layout => 'pdfs/pdf'})
}
attachments["pdf.pdf"] = WickedPdf.new.pdf_from_string(
render_to_string(:pdf => "pdf.pdf", :template => 'pdf/pdf.html.erb', :layout => 'pdfs/pdf'),
:footer => {:html => {:url => "file:///tmp/wicked_pdf_#{@model.number}.html"}, :spacing => -65}

)

Any clue to have this working properly?

@clod81

looking at the code of pdf_helper.rb, I can see where the bug is:
the controller calls

def make_pdf(options = {})
  html_string = render_to_string(:template => options[:template], :layout => options[:layout])
  options = prerender_header_and_footer(options)
  w = WickedPdf.new(options[:wkhtmltopdf])
  w.pdf_from_string(html_string, options)
end

which calls:

def prerender_header_and_footer(options)
  [:header, :footer].each do |hf|
    if options[hf] && options[hf][:html] && options[hf][:html][:template]
      @hf_tempfiles = [] if ! defined?(@hf_tempfiles)
      @hf_tempfiles.push( tf=WickedPdfTempfile.new("wicked_#{hf}_pdf.html") )
      tf.write render_to_string(:template => options[hf][:html][:template], :layout => options[:layout], :locals => options[hf][:html][:locals])
      tf.flush
      options[hf][:html].delete(:template)
      options[hf][:html][:url] = "file://#{tf.path}"
    end
  end
  options
end

The second method generates the :url option for the footer temp file.

Calling the footer from pdf_from_string directly does not consider the template option for the footer or header, but only the :html :url option.

I might do a fix if I have sometimes, otherwise I leave under consideration

Thanks

@unixmonkey
Collaborator

In prerender_header_and_footer, I think you would be able to change the tf.write line's :layout => options[:layout] to read :layout => options[hf][:layout], to use a footer layout. It appears to be only using the main pdf layout here.

@clod81

I redefined the method inside wicked_pdf.rb like this:

def parse_header_footer(options)
  r=""
  [:header, :footer].collect do |hf|
    unless options[hf].blank?
      opt_hf = options[hf]
      r += make_options(opt_hf, [:center, :font_name, :left, :right], "#{hf.to_s}")
      r += make_options(opt_hf, [:font_size, :spacing], "#{hf.to_s}", :numeric)
      r += make_options(opt_hf, [:line], "#{hf.to_s}", :boolean)
      if options[hf] && options[hf][:content]
        @hf_tempfiles = [] if ! defined?(@hf_tempfiles)
        @hf_tempfiles.push( tf=WickedPdfTempfile.new("wicked_#{hf}_pdf.html") )
        tf.write options[hf][:content]
        tf.flush
        options[hf].delete(:content)
        options[hf][:html] = {}
        options[hf][:html][:url] = "file://#{tf.path}"
      end
      unless opt_hf[:html].blank?
        r += make_option("#{hf.to_s}-html", opt_hf[:html][:url]) unless opt_hf[:html][:url].blank?
      end
    end
  end unless options.blank?
  r
end

I can pass the option :content to the :footer, rendered outside the gem (in my case in action mailer)

@clod81

added a pull request:
#70

@unixmonkey
Collaborator

This pull request was merged. Closing

@unixmonkey unixmonkey closed this Apr 27, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment