Ruby on Rails: Using bootstrap without require_tree breaks my stylesheets - ruby-on-rails

I am trying to migrate to Bootstrap 4 in my Ruby on Rails project, following the github installation guide
It recommends that in my application.scss file, I remove *= require_tree
However, when I do this, none of my custom CSS files appear. If require_tree DOES tell the asset pipeline to include all of the specified files in the directory, how else would the asset pipeline know to do this?
I've been trying to find an answer to this problem and haven't found anything.

OK, you would try to work with css and scss at a time, Right? You can do this the several ways like if you need to use only one file like application.scss then you can rename the file again e.g application.css.scss then for scss you would follow this
#import "bootstrap";
...
then for custom css above in the #import variable
/*
*= require custom
*= require custom_another
*/
make sure this custom file is formatted with .css and it's inside assets/stylesheets folder.
For saas file will use #import & for css file will use *= require.
Now if you need to use separate files for css & scss then it would look like this application.css
/*
*= require custom
*= require_tree .
*= require_self
*/
you can leave that application.css and for scss you can create a custom file inside assets/stylesheets like custom.scss then
#import "bootstrap";

Related

MaterializeCss, Bower, Rails

I use materialize css with Bower in Rails project and have a problem:
I try to change color of my footer in assets/stylesheet/main.sass:
footer
background-color: #004d40
But on the page default color of materialize footer in vendor/assets/bower_components/materialize/sass/components/_global.scss
overwriting my style
application.scss
/*
*= require_self
*= require_tree .
*/
$roboto-font-path: 'materialize/font/roboto/';
#import "materialize/sass/materialize.scss";
Try to #import matrialize first, but then *= require_tree . not loaded
You need to use #import in scss files. https://github.com/mkhairi/materialize-sass might be easier to use instead of bower for rails.

What is the SASS equivalent to *= require_self and *= require_tree .?

I am trying to solve a problem in my Rails 4 + Spree app and a post suggested me to convert my all.css file to all.scss (sass).
How do I convert
*= require spree/frontend
*= require_self
*= require_tree .
to #imports?
I did the
#import "spree/frontend";
Which was pretty straightforward, but now my app is "unstyled" and I am positive it is because of the other two directives.
Thanks!
'require_tree' will tell asset pipeline to include all the files within the specified directory. By default it is set to current directory with . (i,e dot). Refer to http://guides.rubyonrails.org/asset_pipeline.html for more details.
After changing the filename of application.css to application.scss, \*=require_tree . can be replaced with #import "/\*" (Example:- on a mac the statement would be translated to a path something like /Users/user_name/app_name/app/assets/stylesheets/*) . The * here imports all the files within the stylesheets directory. Refer to Is it possible to import a whole directory in sass using #import? for more information.
This should solve your problem.
But, the suggested way to go about this is to create another file with a .scss extension that contains all the imports you want and use \*=require_self and \*=require_tree . within the application.scss file.

How should I go about managing sass code when using bootstrap-sass?

The documentation says:
Import Bootstrap styles in app/assets/stylesheets/application.scss:
// "bootstrap-sprockets" must be imported before "bootstrap" and "bootstrap/variables"
#import "bootstrap-sprockets";
#import "bootstrap";
bootstrap-sprockets must be imported before bootstrap for the icon fonts to work.
Make sure the file has .scss extension (or .sass for Sass syntax). If you have just generated a new Rails app, it may come with a .css file instead. If this file exists, it will be served instead of Sass, so rename it:
$ mv app/assets/stylesheets/application.css app/assets/stylesheets/application.scss
Then, remove all the //= require and //= require_tree statements from the file. Instead, use #import to import Sass files.
Do not use //= require in Sass or your other stylesheets will not be able to access the Bootstrap mixins or variables.
But if I do as they say, my other stylesheets won't be included automatically, as they did before that. Should I include every stylesheet explicitly in layout? AFAIU, that would also make me have separate stylesheets in production environment, instead of one as it would have been without bootstrap-sass.
There are several things here. First, by default each stylesheet is served in separate http request in development, and in one request in production (they are precompiled into one file). If we follow the docs, we'll end up having one request in development as well, which would negate performance benefit of compiling only the file that has changed. If we don't, we might end up having bootstrap several times in our stylesheets. In case we need some variables or mixins in several stylesheets.
So I suggest having it this way:
application.sass (do note that I put require_self before require_tree .):
/*
*= require_self
*= require_tree .
*/
// import bootstrap once
#import "bootstrap-sprockets"
#import "bootstrap"
.d1
text-align: center
welcome.sass:
// in other files import only some particular partials
#import "bootstrap/variables"
#import "bootstrap/mixins"
.d2
text-align: right
But if I do as they say, my other stylesheets won't be included automatically, as they did before that.
Yes, you a right.
1) You shouldn't remove your require directives from application.scss. They don't want to use require directives because in this case you don't have ability to use SASS variables and mixins inside of included files.
2) Just rename application.css to application.scss. They want it because in this case you will have ability to use #import directives inside application.scss file. This is mean that you will have ability to use SASS variables and mixins inside of included files.
Should I include every stylesheet explicitly from layout?
No, just leave them in application.scss
AFAIU, that would also make me have separate stylesheets in production environment, instead of one as it would have been without bootstrap-sass.
No, you will use one application.scss in different environments.

can I use variables defined in foundation's scss in my application.css

In my rails application's asset application.css I have the following line
/*
*= require foundation_and_overrides
*= require_self
*= require_tree .
*/
ul#mainmenu li {
background-color: $mainColor;
}
which includes the file foundation_and_overrides.scss where I defined the following variable
$mainColor: #eba10e;
But when I now try to use this variable directly in my application.css file, it is not translated to #eba10e, so I get lines like this one in the resulting css file:
background-color: $mainColor;
So my question, how can I use the variable in my application.css file?
No, pure CSS does not support variables.
But it will work, if you rename it to application.scss. After that it will be compiled with Sass. CSS is always valid SCSS, so this will work without problems.
Additionally you have to use the #import statement instead of require, so the other files will be imported the ”SASS way“.

Ruby on Rails 3.1 and jQuery UI images

I'm using Ruby on Rails (Edge, the development version), and Ruby rvm 1.9.2.
application.js is as follows.
//= require jquery
//= require jquery-ui
//= require jquery_ujs
//= require_tree
Where is the right place in Ruby on Rails 3.1 to put the jQuery UI theme?
According to Autocomplete fields in Ruby on Rails 3.1 with jQuery UI I should put a jQuery UI theme in vendor/assets/stylesheets folder. That sounds like a smart place to have it, but I don't get it to work :-(.
I managed to get the CSS loaded by putting it in the assets/stylesheets folder, but the images I havn't managed to get loaded.
I could of course be using the old way with just putting the theme in the public/stylesheets/ folder, and using:
<%= stylesheet_link_tag "jquery/ui-lightness/jquery-ui-1.8.11.custom" %>
in application.html.erb, but trying to be a modern man, I would rather use the new way of doing tings :-).
Now that we have Ruby on Rails 3.1.0, this is what worked for me:
app/assets/javascripts/application.js
//= require jquery
//= require jquery_ujs
//= require jquery-ui
//= require_tree .
This directly includes the jQuery UI provided by the jquery-rails gem. But the gem does not provide the theme files. For these, I added a theme directory under vendor/assets/stylesheets, containing:
the jquery.ui.theme.css file,
the jQuery UI theme's images directory.
Be sure to keep the theme's images directory with the CSS file! Do not put the image files under vendor/assets/images, or they won't be found by jQuery (which search them under /assets/images).
Finally, changed the app/assets/stylesheets/application.css file to:
/*
*= require_tree ../../../vendor/assets/stylesheets
*= require_tree .
*/
Example of a working setup:
$ cat app/assets/javascripts/application.js
//= require jquery
//= require jquery-ui
$ cat app/assets/stylesheets/application.css
/*
*= require vendor
*
*/
$ cat vendor/assets/stylesheets/vendor.css
/*
*= require_tree ./jquery_ui
*
*/
vendor/assets/ $ tree
stylesheets
vendor.css
jquery_ui
     jquery-ui-1.8.13.custom.css
...
images
   jquery_ui
   ui-bg_flat_0_aaaaaa_40x100.png
...
Finally run this command:
vendor/assets/images $ ln -s jquery_ui/ images
Enjoy your jQuery UI
I've fallen down to doing it the old way:
I put the jQuery folder, containing the theme (unchanged with both CSS and images folder) in the assets/stylesheets folder, and putting in: <%= stylesheet_link_tag "jquery/ui-lightness/jquery-ui-1.8.13.custom" %> in app/views/layouts/application.html.erb file. This solution is the one with less hazel when I will update jQuery later.
(Thanks for all suggestions on the solution. It is time to conclude.)
I like to selectively download jQuery UI JavaScript code so that I can easily upgrade to any future versions and have a light-weight jQuery UI (include needed files only, here progressbar.js).
I have the following setup for the "Dot Luv" jQuery UI theme.
Note:
The JavaScript and CSS files are uncompressed and taken from jquery-ui-1.8.16.custom/development-bundle/ui and jquery-ui-1.8.16.custom/development-bundle/themes/dot-luv respectively, and I rely on sprokets to minify and compress them.
The images are from jquery-ui-1.8.16.custom/development-bundle/themes/dot-luv/images.
Directory Structure:
app/assets/javascripts/application.js
//= require jquery
//= require jquery-ui/v1.8.16/Core/jquery.ui.core
//= require jquery-ui/v1.8.16/Core/jquery.ui.widget
//= require jquery-ui/v1.8.16/Widgets/jquery.ui.progressbar
//= require jquery_ujs
app/assets/stylesheets/application.css.scss
*= require_self
*= require jquery-ui/v1.8.16/dot-luv/jquery.ui.all
*= require jquery-ui/v1.8.16/dot-luv/jquery.ui.base
*= require jquery-ui/v1.8.16/dot-luv/jquery.ui.core
*= require jquery-ui/v1.8.16/dot-luv/jquery.ui.progressbar
*= require jquery-ui/v1.8.16/dot-luv/jquery.ui.theme
config/application.rb
config.assets.paths << File.join(Rails.root,'vendor/assets/images/jquery-ui/v1.8.16/dot-luv/')
I know this thread already has a lot of answers but I'm going to throw in what worked best for me.
There is a gem called jquery-ui-themes that includes the default jQuery UI themes already converted to sass using the image-path helper. So you can include the gem and get any of the default themes out of the box just by adding them to your application.css file
If you want to use your own custom theme (as I did) there is a rake task that will automatically convert the CSS file to SCSS and use the image-path helper to find the right path.
With Ruby on Rails 3.1.2 I did the following.
#app/assets/javascripts/application.js
//= require jquery
//= require jquery_ujs
//= require jquery-ui
//= require_tree .
For the CSS files, I like to do #import instead to have more control over the load order of CSS files. To do this, I have to add the .scss extension to the app/assets/stylesheets/application.css file, and also to all CSS files I want to import, like the jQuery UI CSS file.
#app/assets/stylesheets/application.css.scss
/*
* This is a manifest file that'll automatically include all the stylesheets available in this directory
* and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
* the top of the compiled file, but it's generally better to create a new file per style scope.
*= require_self
*/
#import "jquery-ui/ui-lightness/jquery-ui-1.8.16.custom.css.scss";
/* Other css files you want to import */
#import "layout.css.scss";
#import "home.css.scss";
#import "products.css.scss";
....
Then I put everything jQuery UI related in vendor/assets like this:
jQuery UI stylesheet:
vendor/assets/stylesheets/jquery-ui/ui-lightness/jquery-ui-1.8.16.custom.css.scss
jQuery UI images folder:
vendor/assets/images/images
Note that you can create additional folder in the stylesheets path like I did here with "jquery-ui/ui-lightness" path. That way you can keep multiple jQuery themes nicely separated in their own folders.
** Restart your server to load any newly created load paths **
Ryan Bates has some excellent screencasts about the asset pipeline and Sass in Ruby on Rails 3.1, where he shows how to use the #import function in Sass. Watch it here:
#279 Understanding the Asset Pipeline
#268 Sass Basics
Edit: I forgot to mention that this works both locally and on Heroku on the Cedar stack.
There is now a jquery-ui-rails gem (see announcement). It packages the images as assets (and correctly references them from the CSS files) so things Just Work. :-)
So, here's one way to do it that lacks the downsides of some of the others mentioned here -- it doesn't require you to take apart the theme and put parts of it in different places, it doesn't require symbolic links, and it still allows you to compile the theme css into the one main css as part of the asset pipeline. It does not require a monkey patch like Nash Bridges' suggestion.
However, it does require an additional kind of hacky configuration line. (a one-liner though, basically).
Okay, put your theme in vendor/assets/jquery/ui-lightness/, like you wanted to. (will also work in lib/assets or app/assets, same way).
And
/* =require ui-lightness */
in your application.css. So far so good. Now to get the images to show up right, just add this to config/application.rb:
initializer :add_jquery_ui_asset_base, :group => :all, :after => :append_assets_path do
config.assets.paths.unshift Rails.root.join("vendor", "assets", "stylesheets", "jquery-ui", "ui-lightness").to_s
end
For me, it now works in dev, production, and other non-standard asset configs I could think of (like dev with debug=false, which trips up some of the other attempted solutions).
More info at http://bibwild.wordpress.com/2011/12/08/jquery-ui-css-and-images-and-rails-asset-pipeline/
Building on a number of other suggestions here, I found a solution that works in my dev environment and in production on Heroku.
app/assets/javascripts/application.js
//= require jquery
//= require jquery_ujs
//= require jquery-ui
//= require_tree .
app/assets/stylesheets/application.css
/*
*= require_self
*= require vendor
*= require_tree .
*/
vendor/assets/stylesheets/vendor.css
/*
*= require_self
*= require_tree .
*/
I added jquery-ui-1.8.16.custom.css and the associated images folder to vendor/assets/stylesheets (I found that unless the images folder was in the same folder as vendor.css it didn't work).
No other changes were necessary for this to work in the Heroku production environment.
Thanks to #denysonique, #softRli and #Paul Cook for their previous answers which helped me.
To get this to work on both my local dev environment and on Heroku, I did almost the same thing as denysonique suggested, but with a couple of differences at the end:
First, my directory structure looked like this:
vendor/assets/images/
jquery_ui/
images/
ui-bg_flat_0_aaaaaa_40x100.png
...
And second, my symbolic link was:
vendor/assets/images $ ln -s jquery_ui/images images
This is what finally worked for me.
There's a proposed fix in Ruby on Rails that makes precompilation of jQuery UI's images work.
(As of 3.1.0rc6, the asset precompiler uses the regular expression /\w+\.(?!js|css).+/ to find things to compile. This misses all the jQuery UI images because their names include dashes and underscores.)
Combining suggestions here is what got things working for me:
Put the jQuery UI theme CSS folder in vendor/assets/stylesheets.
Put vendor.css in vendor/assets/stylesheets:
*= require_tree ./theme-css-name
In production.rb I added this:
config.assets.paths << File.join(Rails.root,'vendor/assets/stylesheets/theme-css-name
That is what it took to get the images to get precompiled and resolve without editing the jQuery UI theme CSS file or moving the images out of the theme CSS folder.
I think you can put ui styles in app/assets/stylesheets. Do something like this:
# app/stylesheets/application.css.scss
//= require_self
//= require libraries/jquery-ui
//= require_tree .
In 'jquery-ui' stylsheet, something like this:
.class{
background: url(/assets/jquery-ui/ui-icons_222222_256x240.png)
}
What I did to get everything to work properly is as follows.
1.) Added the CSS to the assets/stylesheets folder
2.) Added the images to the assets/images folder
3.) Removed the paths to all the images in the CSS using find "url(images/" and replace with "" leaving just the image file name.
/* Example: */ .ui-icon { background-image: url(images/ui-icons_222222_256x240.png) ; }
/* Becomes: */ .ui-icon { background-image: url(ui-icons_222222_256x240.png) ; }
Bingo! Everything should work correctly.
Using Ruby on Rails 3.1.1, I simply placed the files as follows. No other changes were required.
app/assets/stylesheets/jquery-ui-1.8.16.custom.css
app/assets/images/ui-bg_highlight-soft_75_cccccc_1x100.png
...
What worked for me was instead of having the jQuery theme CSS file in app/assets/stylesheets/ and the images in app/assets/images/. I placed them into app/assets/images/images/, and it worked. It's kind of a hack, but it seems to work at this point with minimal fudging and without modifying the CSS files.
Get the CDN hosted theme from Google:
= stylesheet_link_tag 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.17/themes/ui-lightness/jquery-ui.css'
For that moment, I found not a perfect but working a solution.
Assuming you have jQuery UI theme in the /vendor/assets/stylesheets/ folder. Then you have to modify application.css:
/* =require ui-lightness */
and create plugin_assets_monkey_patch.rb in the /config/initializers
Dir[File.join(Rails.root, 'vendor/assets/stylesheets/*/')].each do |dir|
AppName::Application.config.assets.paths << dir
index_content = '/*=require_tree .*/'
index = File.join(dir, 'index.css')
unless File.exist?(index)
File.open(index, 'w') { |f| f.puts index_content }
end
end
index.css in every /vendor/assets/stylesheets/ subfolder guarantees that stylesheets like jquery-ui-1.8.11.custom.css will be compiled (if you require that subfolder).
config.assets.paths ensures that folders like /vendor/assets/stylesheets/ui-lightness/images are visible at the application root scope.

Resources