ThiccPDF is a fork of Wicked PDF. It uses WeasyPrint instead of wkhtmltopdf.
WickedPDF supports CSS Flexbox. It does not support Javascript.
TODO: Gut all unsupported options and Javascript content. Fix tests.
Add this to your Gemfile and run bundle install:
gem 'thicc_pdf'Then create the initializer with
rails generate thicc_pdf
You may also need to add
Mime::Type.register "application/pdf", :pdfto config/initializers/mime_types.rb in older versions of Rails.
thicc_pdf wraps WeasyPrint, a Python library that renders HTML to PDFs.
It must be installed separately.
For more information about WeasyPrint, see the project's documentation.
class ThingsController < ApplicationController
def show
respond_to do |format|
format.html
format.pdf do
render pdf: "file_name" # Excluding ".pdf" extension.
end
end
end
endWeasyPrint is run outside of your Rails application; therefore, your normal layouts will not work. If you plan to use any CSS or image files, you must modify your layout so that you provide an absolute reference to these files. The best option for Rails without the asset pipeline is to use the following helpers:
thicc_pdf_stylesheet_link_tagthicc_pdf_image_tag
WeasyPrint does not support Javascript.
<!doctype html>
<html>
<head>
<meta charset='utf-8' />
<%= thicc_pdf_stylesheet_link_tag "pdf" -%>
</head>
<body onload='number_pages'>
<div id="header">
<%= thicc_pdf_image_tag 'mysite.jpg' %>
</div>
<div id="content">
<%= yield %>
</div>
</body>
</html>Using thicc_pdf_helpers with asset pipeline raises Asset names passed to helpers should not include the "/assets/" prefix. error. To work around this, you can use thicc_pdf_asset_base64 with the normal Rails helpers, but be aware that this will base64 encode your content and inline it in the page. This is very quick for small assets, but large ones can take a long time.
<!doctype html>
<html>
<head>
<meta charset='utf-8' />
<%= stylesheet_link_tag thicc_pdf_asset_base64("pdf") %>
</head>
<body onload='number_pages'>
<div id="header">
<%= image_tag thicc_pdf_asset_base64('mysite.jpg') %>
</div>
<div id="content">
<%= yield %>
</div>
</body>
</html>thicc_pdf supports webpack assets.
- Use
thicc_pdf_stylesheet_pack_tagfor stylesheets - Use
thicc_pdf_asset_pack_pathto access an asset directly, for example:image_tag thicc_pdf_asset_pack_path("media/images/foobar.png")
It is best to precompile assets used in PDF views. This will help avoid issues when it comes to deploying, as Rails serves asset files differently between development and production (config.assets.compile = false), which can make it look like your PDFs work in development, but fail to load assets in production.
config.assets.precompile += ['blueprint/screen.css', 'pdf.css', 'jquery.ui.datepicker.js', 'pdf.js', ...etc...]
NOTE: Many options from WickedPDF rely on wkhtmltopdf and will not work with ThiccPDF.
class ThingsController < ApplicationController
def show
respond_to do |format|
format.html
format.pdf do
render pdf: 'file_name',
disposition: 'attachment', # default 'inline'
template: 'things/show',
locals: {foo: @bar},
file: "#{Rails.root}/files/foo.erb",
inline: '<!doctype html><html><head></head><body>INLINE HTML</body></html>',
layout: 'pdf', # for a pdf.pdf.erb file
progress: proc { |output| puts output } # proc called when console output changes
end
end
end
endBy default, it will render without a layout (layout: false) and the template for the current controller and action.
Default configuration is set in initializers/thicc_pdf.rb.
If you would like to have ThiccPdf automatically generate PDF views for all (or nearly all) pages by appending .pdf to the URL, add the following to your Rails app:
# in application.rb (Rails3) or environment.rb (Rails2)
require 'thicc_pdf'
config.middleware.use ThiccPdf::MiddlewareIf you want to turn on or off the middleware for certain URLs, use the :only or :except conditions like so:
# conditions can be plain strings or regular expressions, and you can supply only one or an array
config.middleware.use ThiccPdf::Middleware, {}, only: '/invoice'
config.middleware.use ThiccPdf::Middleware, {}, except: [ %r[^/admin], '/secret', %r[^/people/\d] ]If you use the standard render pdf: 'some_pdf' in your app, you will want to exclude those actions from the middleware.
To include a rendered pdf file in an email you can do the following:
attachments['attachment.pdf'] = ThiccPdf.new.pdf_from_string(
render_to_string('link_to_view.pdf.erb', layout: 'pdf')
)This will render the pdf to a string and include it in the email. This is very slow so make sure you schedule your email delivery in a job.