Jon
Jon

Reputation: 4045

PDFKit on Heroku with Rails 3.2.13 and Bootstrap

I'm having a very hard time getting PDFKit to work on Heroku. I have read tutorials found here, here, and here, but still cannot figure out how to get the pdf to show up correctly. I am having the same issue described in the previous links where the application works fine in development and hangs in production on Heroku. I have tried adding the following (gotten from the tutorials).

application_helper.rb

def request_from_pdfkit?
  # when generating a PDF, PDFKit::Middleware will set this flag
  request.env["Rack-Middleware-PDFKit"] == "true"
end

# We have to reference the actual output of the assets pipeline, which according
# to http://guides.rubyonrails.org/asset_pipeline.html is application-<md5>.css and
# application-<md5>.js.  We have to dynamically find these file names and correctly
# reference them.
def get_mdf5_file(base_file)
  stripped_name = base_file.basename.to_s.gsub(base_file.extname, "")
  Dir.glob("#{base_file.parent}/*#{base_file.extname}").each do |file|
    return file if file.match(/#{stripped_name}-[\d\w]+#{base_file.extname}/)
  end
  return base_file
end

application.html.erb

<% if request_from_pdfkit? %>
  <style type="text/css" media="all">
    <%= File.read(get_mdf5_file(Rails.root.join("public","assets","application.css")) %>
  </style>
  <script type="text/javascript">
    <%= File.read(get_mdf5_file(Rails.root.join("public","assets","application.js"))) %>
  </style>
<% else %>
  <%= stylesheet_link_tag "application", :media => "all" %>
  <%= javascript_include_tag "application" %>
<% end %>

When I do this the PDFs generated have minimal styling and no content generated from javascript. It would appear (based on my hunch) that none of the Bootstrap scss is getting precompiled into application.css. Right now, here are the contents of

application.css

/*
 *= require_self
 *= require dataTables/jquery.dataTables
 *= require dataTables/jquery.dataTables.bootstrap
 *= require dataTables/src/demo_table_jui
 *= require jquery.ui.all
 *= require jquery.jqplot
 *= require_tree .
 */

application.js

//= require jquery
//= require jquery_ujs
//= require jquery-ui
//= require bootstrap
//= require bootstrap-multiselect
//= require dataTables/jquery.dataTables
//= require dataTables/jquery.dataTables.bootstrap
//= require jquery.jqplot
//= require plugins/jqplot.cursor
//= require plugins/jqplot.BezierCurveRenderer
//= require plugins/jqplot.bubbleRenderer
//= require plugins/jqplot.barRenderer
//= require plugins/jqplot.categoryAxisRenderer
//= require plugins/jqplot.canvasTextRenderer
//= require plugins/jqplot.canvasAxisLabelRenderer
//= require plugins/jqplot.highlighter
//= require plugins/jqplot.canvasOverlay
//= require plugins/jqplot.cursor
//= require plugins/jqplot.enhancedLegendRenderer
//= require plugins/jqplot.dateAxisRenderer
//= require plugins/jqplot.canvasAxisTickRenderer
//= require_tree .

I tried adding some Bootstrap scss components manually to the application.css assets pipeline but got the error referenced here.

I'm at a loss how to get this to work, so any help would be appreciated.

EDIT

I've been playing with this a lot and noticed that when the Javascript and CSS are inserted inline, all of the quotation marks " are replaced with " according to the source as displayed on Chrome. I have tried adding .gsub(/"/, /"/) but that did not work. Does anyone know why I'm seeing " instead of ", or if this is even an issue.

EDIT 2

I was able to get the display to look a little better by implementing the following changes

<script type="text/javascript">
  <%= raw(File.read(get_mdf5_file(Rails.root.join("public", "assets", "application.js"))).gsub("</script>", "")) %>
</script>
<style type="text/css" media="all">
  <%= raw File.read(get_mdf5_file(Rails.root.join("public", "assets", "application.css"))) %>
</style>

however the styling is still messed up so I'm still hunting for the solution.

Upvotes: 4

Views: 1406

Answers (2)

stevo
stevo

Reputation: 468

I think you can simplify a lot by doing (Rails4, YMMV):

<%= Rails.application.assets.find_asset('pdfs.css').to_s.html_safe %>

Works using wkhtmltox-0.12.0.

Some details: https://github.com/sstephenson/sprockets#accessing-assets-programmatically

Credit to: https://stackoverflow.com/a/11767185/1869825
also: Rails 3 command to embed text of my CSS stylesheets in head of my HTML

Upvotes: 1

Jon
Jon

Reputation: 4045

I figured this out. I had to downgrade to wkhtmltopdf 0.10 rc2. After I did this I was able to modify the styling to get the PDF to look decent.

Upvotes: 2

Related Questions