Reputation: 38792
I have several CSS files which make referece to images using relative paths like url( "../img/my_image.jpg" )
.
Everything works in development
but in production
environment, as all the CSS files are packed in one file and the structure is lost, also the relatives paths are lost, and the images are not found.
I have an assets structure like this:
/app
/assets
/plugins
/my_plugin
/img
my_image.jpg
/css
my_css.css
(/my_plugin
can be any plugin that is a groups of css
, js
and images
files like Twitter Bootstrap any any other)
Into the /app/assets/plugins/my_plugin/my_css.css
I have something like:
background-image: url("../img/my_image.jpg");
In the /app/assets/stylesheets/application.css
:
*= require css/my_css.css
And finally in the head
of my html
file:
<%= stylesheet_link_tag "application" %>
What should I do to fix the issue?
Mini application to reproduce the issue, in the README there are instruction to install and reproduce the issue.
Upvotes: 5
Views: 5170
Reputation: 15771
I don't see a problem with concatenating CSS files. And you don't have to include your deeply nested CSS files manually: by default, application.css already does this in the line *= require_tree .
And images will repeat your app/assets/images
structure. To deal with them correctly both in development and production environments you have the respective Guide. Check its section 2.2 Coding Links to Assets. There's explanation about coding paths to your image files:
CSS via ERb:
url(<%= asset_path 'image.png' %>)
CSS via Sass:
image-url("rails.png")
All these weird hex characters at the end of your precompiled images will be respected automatically.
UPD
I see you don't need the assets pipeline feature for your plugins at all. Your styles/scripts are already minified. You can move your plugins
folder into your public
folder (to become <APP_ROOT>/public/plugins/
).
Then delete the following line from your application.css
:
*= require bootstrap/css/bootstrap
Instead add the following lines to your template application.html.erb
:
<%= stylesheet_link_tag "/plugins/bootstrap/css/bootstrap.min.css", :media => "all" %>
<%= javascript_include_tag "/plugins/bootstrap/js/bootstrap.min.js" %>
Now you have to be able to switch between your themes easily by replacing your public/plugins/bootstrap
's content.
UPD 2
Probably you have to explicitly tell Rails to precompile
your plugin assets:
# /config/environments/production.rb
config.assets.precompile += %w( bootstrap/css/bootstrap.css )
Upvotes: 8
Reputation: 38792
I have been able to solve the issue moving my plugin assets to the /app/vendor/assets/plugins
where I think is better place due they are not assets directly related to my application but infact vendor assets.
Then we have:
/app
/vendor
/assets
/plugins
/my_plugin
/img
my_image.jpg
/css
my_css.css
And we load the main css
in another stylesheet_link_tag
call like this:
<%= stylesheet_link_tag "my_plugin/css/my_css", :media => "all" %>
At this moment everything looks right but Rails complains about my_css.css
is not compiled even if we run rake assets:precompile
.
The solution is to tell Rails explicitly to compile this file:
# /config/environments/production.rb
config.assets.precompile += %w( my_plugin/css/my_css.css )
Now the rake assets:precompile
will compile our plugin css and the production
environment works properly even with relative urls.
Check the diff changes those have resolved the issue
Upvotes: 2