I'm using the PDFkit in my controller to build out a series of PDFs, zip them up, and then send them to the user.
In order to control the output styles, I tell PDFKit which stylesheets to use during content generation. I need to pass along the file reference of the CSS file. Since Rails is now compiling and renaming my stylesheets, I'm not sure how to reference the compiled CSS asset inside my controller.
Here's what I used to do:
InvoicesController < ApplicationController
def download
kit = PDFKit.new(render_to_string(:show, :layout => false))
kit.stylesheets << "#{Sass::Plugin.options[:css_location]}/application.css"
kit.to_file("#{file_date_string}.pdf")
# snip
end
end
Sass::Plugin.options[:css_location] now returns the incorrect location, not to mention the fact that application.css is no longer the valid name of the file. I should mention that I have an app/assets/application.css file that serves as a manifest for my SCSS files, and it is working correctly in my views via the stylesheet_link_tag() method.
Basically what I'm looking for is a controller equivalent of asset_path() in order to do something like this:
kit = PDFKit.new(render_to_string(:show, :layout => false))
kit.stylesheets << asset_path('application.css')
kit.to_file("#{file_date_string}.pdf")
Can anyone help?
You should use app/assets for files that must undergo some pre-processing before they are served. In production, Rails precompiles these files to public/assets by default. The precompiled copies are then served as static assets by the web server. The files in app/assets are never served directly in production.
Start adding @import directives to application. scss . If you are using twitters bootstrap and a few css sheets of your own, you have to import bootstrap first, because it has a sheet to reset styles. So you add @import "bootstrap/bootstrap.
To compile your assets locally, run the assets:precompile task locally on your app. Make sure to use the production environment so that the production version of your assets are generated. A public/assets directory will be created. Inside this directory you'll find a manifest.
The clean it removes the old versions of the precompiled assets while leaving the new assets in place. Show activity on this post. rake assets:clean removes compiled assets. It is run by cap deploy:assets:clean to remove compiled assets, generally from a remote server.
Rails.application.assets
is poorly documented but it provides access to Rails' hook into Sprockets, as a Sprockets::Environment
object. Rails uses Sprockets to basically run the whole asset pipeline, and this is where you should hook in for things like this:
kit.stylesheets << Rails.application.assets['application.css'].pathname
https://github.com/sstephenson/sprockets says of it:
Accessing Assets Programmatically
You can use the find_asset
method (aliased as []
) to retrieve an asset from a Sprockets environment. Pass it a logical path and you'll get a Sprockets::BundledAsset
instance back:
environment['application.js'] # => #<Sprockets::BundledAsset ...>
Call to_s
on the resulting asset to access its contents, length
to get its length in bytes, mtime
to query its last-modified time, and pathname
to get its full path on the filesystem.
view_context.asset_path 'application.css'
should do the trick.
Rails.application.assets['application.css'].pathname
always returns the original path of the raw asset, not the precompiled file, so the top answer did not work for me.
However, calling to_s
on the bundled asset instead of pathname
does seem to correctly return the body of the precompiled asset, so you can just use an inline style instead of using kit.stylesheets <<
:
<style>
<%= Rails.application.assets["application.css"].to_s %>
</style>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With