How can I create Rails PDF-specific HTML for PDFKit?

I use PDFKit middleware to render PDF files. Here is what he does:

  • Inspect incoming requests in the application. If they are intended for PDF, hide this fact from the application, but be prepared to change the answer.
  • Allow application to display as HTML
  • Return the response and convert the HTML to PDF before sending it.

Generally, I want this behavior. But I have one case when I really need my application to render other content based on the fact that a PDF file was requested.

PDFKit provides me with a marker to detect that it plans to display my answer: it sets env["Rack-Middleware-PDFKit"] be true.

But I need to tell Rails that, based on this flag, I want it to show show.pdf.haml . How can i do this?

+4
source share
2 answers

Set request.format and response headers

Figured it out. According to Rails source , request.format = 'pdf' will manually set the response format in PDF format. This means that Rails will display, for example, show.pdf.haml .

However, now PDFKit will not convert the response to an actual PDF, because the Content-Type header says that it is already a PDF, when we actually only generate HTML. Therefore, we also need to override the Rails response header to say that it is still HTML.

This controller method processes it:

 # By default, when PDF format is requested, PDFKit middleware asks the app # to respond with HTML. If we actually need to generate different HTML based # on the fact that a PDF was requested, this method reverts us back to the # normal Rails `respond_to` for PDF. def use_pdf_specific_template return unless env['Rack-Middleware-PDFKit'] # Tell the controller that the request is for PDF so it # will use a PDF-specific template request.format = 'pdf' # Tell PDFKit that the response is HTML so it will convert to PDF response.headers['Content-Type'] = 'text/html' end 

This means that the action of the controller is as follows:

 def show @invoice = Finance::Invoice.get!(params[:id]) # Only call this if PDF responses should not use the same templates as HTML use_pdf_specific_template respond_to do |format| format.html format.pdf end end 
+5
source

You can also use PDFKit without middleware.

+1
source

All Articles