sprockets sass partial erb extension - ruby-on-rails

I have noticed that with the latest rails and sprockets versions (3.2.1 & 2.2.0) there seems to be a problem when the erb file extension is added to a sass partial.
e.g. if somestylefilename.css.sass is renamed to somestylefilename.css.sass.erb and the file contains a declaration of a sass variable that uses erb, vis:-
$background-colour: <%= '#fff' %>;
all is ok.
However if a sass partial is renamed from say _sharedpartial.css.sass to _sharedpartial.css.sass.erb then the same variable declaration is not recognised.
I am not sure if this is the right forum to report this behaviour or if it is a sass, rails or sprockets problem.
P.S. I know that the asset pipeline targets efficiency through pre-compiled assets, but I am trying to write a theeme controller that is capable of selecting the default colour/layout scheme for a site which will subsequently form the default pre-compiled css asset in production.
Best regards,
John Leake

This is a sass-rails error, as discussed here.
I had the same question and found out that the solution is by installing sass-rais-path.
This gets Rails to work SASS + ERB as expected.

This will sound a bit ridiculous, but have you tried to remove the .erb extension?
Normally you don't have to use it, even if you use erb tags.

Related

Rails 4.2: Custom Helper for SCSS Manifest in Engines

Our application is a collection of 3 engines that make up our base gem. Other plugin gems, written specifically for our base gem, can be used to add functionality to the base.
Currently we have 2 custom sprockets directives and 1 custom Sass importer that attempts to pull in SCSS files from these plugins dynamically into the base manifest. A contrived example looks something like:
//= depend_on_gemfile # mimics default "depend_on" functionality
//= depend_on_stylesheets # mimics default "depend_on" functionality
...
#import 'engine/namespace/settings/global';
#import 'engine/namespace/settings/colors';
#import 'engine/namespace/settings/fonts';
#import '[engine-plugins]/namespace/settings'; # mimics Sass Filesystem importer
...
To be clear, this works. We're having problems with the way Sass is caching the files, that is a bit too complicated to get into and not really my goal at the moment.
The point is that we realized that removing the custom Sprockets directives and Sass importer, in favor of using a Rails helper, would also solve our problem, since the ERB would be compiled before the SCSS, we'd be able to find and format all of the paths needed in all included plugins into a string and dump it out into the manifest. Something like:
#import 'engine/namespace/settings/global';
#import 'engine/namespace/settings/colors';
#import 'engine/namespace/settings/fonts';
<%= load_plugin_stylesheets_for('settings'); %>
...
This seems like a much more simple solution, since all we are doing is finding each path and converting those paths to strings.
The problem seems to be that Rails helpers are outside of domain of Sprockets entirely.
I've found some resources, but they all seem to pertain to Rails 3.
Add custom methods to Rails 3.1 asset pipeline?
https://github.com/rails/rails/issues/3282
I'm curious if anyone has had this problem with Rails 4, if they solved it and how. Or if I'm just thinking about this all wrong and there is a better way to approach the problem without a similar over-complication like we had before.
TL;DR
I'd like to use regular Rails helpers inside of a Sprockets manifest file. The Rails version is 4.2.4. We're running engines. Is this possible?
EDIT:
This comment answered my question.
After implementing this solution in an initializer within our engine.rb file, all of the Rails ActionView Helpers were available, including my custom written helper.
We had a similar issue a while ago.
application.scss (within gem) looks like this:
/*
*= require_tree .
*= require_self
*/
#import "c3.min";
#import "analytics";
and gemspec contains line for including all the code from app folder.
Gem::Specification.new do |s|
s.files = Dir['{app,config,db,lib}/**/*', 'MIT-LICENSE', 'Rakefile', 'README.rdoc']
end
Be sure to check that you don't have any caching enabled in env files as well.

Background images with asset pipeline

This should be a simple thing but for some reason it won't work.
I'm having trouble getting a background image displayed on my page. I'm using Rails 3.2 with the asset pipeline. I am trying to display it on pages related to my home controller.
The image location is: app/assets/images/dna.jpg
home.css.scss
background: url('/assets/images/dna.jpg');
I've also tried the following:
background: url('dna.jpg');
background: url('/assets/dna.jpg');
background-image: image-url("dna.jpg");
background-image:url(image_path('dna.jpg'));
Regardless of which approach I try, I get the same error:
Sass::SyntaxError at /
Invalid CSS after "background:": expected pseudoclass or pseudoelement, was " url('/assets/i..."
(in /Users/sean/Dropbox/bin/rails/assay/app/assets/stylesheets/home.css.scss)
See also this SO post: Adding a background image in Ruby on Rails 2 in CSS
EDIT
Referring to this post: sass-rails asset pipeline: generating image paths incorrectly; `url(/images/blah.png)` instead of `url(/assets/blah.png)`
I cleared the asset cache
rake tmp:cache:clear
And bundle updated my sass-rails gem. It's at 3.2.6 now.
None of that made any difference.
I suspect a very simple reason for your troubles: indentation. Most of the times in scss it happens that there is no space after the statement, in your case background:. Try also this in your scss prefixed file:
background: url(dna.jpg);
It always works for me.
I found a work-around: turned the scss file into a normal css file.
home.css
body {background-image:url('dna.jpg');
background-size:cover;}
Now it works fine. It doesn't seem like the right solution though.
I had the exact same issue and it was a result of me using Sass Indented Syntax in an SCSS file.
More info on the differences between Sass and SCSS: http://sass-lang.com/documentation/file.INDENTED_SYNTAX.html

CSS in Rails Asset Path not processed by ERB in development

I have a Rails app with the following in /app/assets/stylesheets/styles.css.erb:
...
#nestedbg {
background-position: left top;
background-image: url(<%= asset_path 'siteheader2.png' %>);
background-repeat: repeat-x;
background-attachment: fixed;
}
...
When I run rake assets:precompile and then run rails s -e production, everything works as expected. However, when I remove the precompiled assets and run rails s in development, the CSS file comes up as shown above instead of being properly substituted.
I tried putting config.assets.compile = true in /config/environments/development.rb and that did not help.
Any ideas?
Thanks.
I honestly cannot say why this is not interpreted correctly in your case, but I have a much better workaround to offer: skip erb interpreting altogether.
You can do this like so:
/* styles.css.scss */
background-image:url(image_path("siteheader2.png"));
If you did not have a chance to I would also suggest to have a look at SASS: it is integrated in the Rails asset pipeline and lets you do cool things like variable declarations, nesting, mixins, ...
I found that my css files wouldn't be processed by ERB unless SCSS processing was also added.
I changed my screen.css.erb to screen.css.scss.erb and now <%= asset_path 'file.png' %> is rendered correctly as /assets/file.png.
I'm on Rails 3.1.3.
I was using Rails 3.1.1 and when I switched the app to use Rails 3.1.3, the problem went away. I switched back to 3.1.1 to see if the issue came back and it did not.
I'm guessing that it was a problem with one of the gems and the update to 3.1.3 brought other gem updates with it.
Bizarrely, I found that changing asset_path to asset_data_uri and then back to asset_path worked for me. Was using Rails 3.1.3 all along.
Strange.
Sam Oliver's advice did the trick for me, simply renaming the extensions didn't update the timestamp on the files.
CSS and ERB
The asset pipeline automatically evaluates ERB. This means that if you add an erb extension to a CSS asset (for example, application.css.erb), then helpers like asset_path are available in your CSS rules:
.class { background-image: url(<%= asset_path 'image.png' %>) }
This writes the path to the particular asset being referenced. In this example, it would make sense to have an image in one of the asset load paths, such as app/assets/images/image.png, which would be referenced here. If this image is already available in public/assets as a fingerprinted file, then that path is referenced.
If you want to use a data URI — a method of embedding the image data directly into the CSS file — you can use the asset_data_uri helper.
CSS and Sass:
When using the asset pipeline, paths to assets must be re-written and sass-rails provides -url and -path helpers (hyphenated in Sass, underscored in Ruby) for the following asset classes: image, font, video, audio, JavaScript and stylesheet.
image-url("rails.png") becomes url(/assets/rails.png)
image-path("rails.png") becomes "/assets/rails.png".
The more generic form can also be used but the asset path and class must both be specified:
asset-url("rails.png", image) becomes url(/assets/rails.png)
asset-path("rails.png", image) becomes "/assets/rails.png"
Referenced By: Rails Guide Asset Pipe Line
Heading: 2.2.1 and 2.2.2 respectively.

How can I use haml within a coffeescript file?

Is it possible to use haml within a coffeescript file in a rails 3.1 project?
What is the correct order of the file extensions?
My last try was that:
home.js.haml.coffescript
$ ->
alert '#{#count}'
where #count is a ruby variable.
The correct order would be home.js.coffeescript.haml—you want the file to first be evaluated as Haml to give you your variables, then compiled as CoffeeScript, then finally served as JavaScript.
However, I strongly suspect that the Haml processor will choke on some CoffeeScript syntax. It would probably be safer to use ERB, which should work for your example.

How to make assets in SASS?

In Rails, when we include an image into the page we use image_tag helper, which generates <img> tag and adds ?nnnnn at the end of its url, so that every time an image is updated the old version would not be stuck in the cache on the client side. Same thing for SASS needed, but I can't find it in the documentation.
You should be using helpers provided by sass-rails gem https://github.com/rails/sass-rails, (scroll to Asset Helpers).
These helpers can be used from inside sass files any time you need to reference an asset (image/audio/video/font)
body{
background: asset_path($relative-asset-path, $asset-class);
}
Note: image_url("...") is not working on Rails 3.1.0.rc4 due to a bug, but you can still use asset_url and asset_path.
Using stylesheet_link_tag will do this for you, just the same as image_tag does. This also applies to JavaScript files linked in with javascript_include_tag.

Resources