Rails 5: Assets + Bower + Bootstrap Sass - ruby-on-rails

There are already similar questions on SO, but not enough clear responses to understand the following issue.
My goal is to setup Rails 5 with Bootstrap using Bower.
Using Bower I installed Bootstrap in the the folder:
vendor/assets/bower_components/bootstrap-sass
Then, I updated initializers/assets:
Rails.application.config.assets.paths << Rails.root.join('vendor', 'assets', 'bower_components')
Then I added the gem 'sass-rails' to Gemfile and updated application.js:
//= require jquery
//= require bootstrap-sass/assets/javascripts/bootstrap
//= require jquery_ujs
//= require turbolinks
//= require_tree .
The assets for JS seem to be working well: if I load http://localhost:3000/assets/application.js
I can see that the Bootstrap JS part has been added there.
The problem is about Sass (SCSS):
I added bootstrap-sass/assets/stylesheets/bootstrap into application.css.scss but with no success:
/*
*= require_tree .
*= require_self
#import "bootstrap-sass/assets/stylesheets/bootstrap";
*/
in fact if I load http://localhost:3000/assets/application.css I see:
/*
#import "bootstrap-sass/assets/stylesheets/bootstrap";
*/
(the folder specified on the #import is containing many _*.scss files and a mixins folder)
The questions are:
Do you have any ideas why this is not working?
should not I see on assets/application.css all the CSS precompiled?
PS:
Any resource to understand the issue would be much appreciated.

Move the import, so it's outside the /* .. */
/*
*= require_tree .
*= require_self
*/
#import "bootstrap-sass/assets/stylesheets/bootstrap";

[Removed misleading instructions to use require instead of import, as I was wrong.]
In addition to the accepted answer, if you look into the bootstrap-sass/assets/stylesheets directory, you'll notice that there is no file bootstrap.scss but rather one prefixed with an underscore.
Also, usually it's better to import only modules you actually need from the bootstrap-sass/assets/stylesheets/bootstrap/ directory instead of the main _bootstrap.scss file.

Related

proper Bootstrap loading in rails 6

I have an application in rails 6 that requires bootstrap.
Bootstrap is being loaded at application.css
/*
*
*= require bootstrap
*= require jquery-ui
*= require font-awesome
*= require_tree
*= require_self
*/
I created a folder /stylsheets/admin where I keep my admin css. There, unless I import bootstrap again, its does not apply to the admin layout
admin_layout.scss:
#import "font-awesome";
#import "bootstrap";
#import "admin";
However that causes bootstrap to appear twice when the page loads. My question here is: what is the proper way to do this? I've solved it in a few ways but none of then feel 'right'.
Solution 1: I removed the 'require bootstrap' from application.css. Since the 'require_tree' loads all files and folders inside stylesheets/ bootstrap applies to application. If I add more layouts that will be an issue however.
Solution 2: (even worse) to move admin_layout.css outside of stylesheets/ so that 'require_tree' does not load it.
I've looked about and didnt find the 'proper way' to do it. What am I missing?
You can try using the stub directive after require_tree
/*
*
*= require bootstrap
*= require jquery-ui
*= require font-awesome
*= require_tree
*= require_self
*= stub admin_layout
*/
https://github.com/rails/sprockets#stub
Similar question has been answered already Asset Pipeline: excluding an admin.css file

Dropdown Toggle Doesn't Work on Heroku ROR

I am working on using a bootstrap template to help a friend with a landing page. I am having a similar issue as others, but there solutions are not working for me. Everything works properly on my LocalHost, but when I push it to Heroku, the Bootstrap Dropdown toggle does NOT work...
I am a junior developer trying to learn and challenge myself here, so please explain your answer if applicable. Thank S.O
I have also ran these codes after I think I have a solution ...
heroku run rake assets:reset
heroku run rake assets:precompile
This is my Application.js file
//= require bootstrap
//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require_tree .
// Bootstrap core JavaScript
#import "jquery.min.js";
#import "bootstrap.bundle.min.js";
//Plugin JavaScript
#import "jquery.easing.min.js";
//Contact form JavaScript
#import "jqBootstrapValidation.js";
#import "contact_me.js";
//Custom scripts for this template
#import "js/agency.min.js";
Application.scss File.
*
*= require_self
*/
#import "bootstrap";
#import "font-awesome.css";
#import "bootstrap.min.css";
#import "agency.min.css";
#import "agency.css";
#import "font-awesome.css";
#import "font-awesome.min.css";
See this standard format, more explanation see the Rails Guide Asset Organization.
//= require jquery
//= require jquery_ujs
//= require bootstrap
//= require jquery.easing
//= require jqBootstrapValidation
//= require contact_me
//= require js/agency.min
//= require turbolinks
//= require_tree .
Without these lines remove all from application.js file, look here is jquery.easing for this you need to install jquery.easing gem and the jqBootstrapValidation you need to install jqBootstrapValidation gem or if you have those original files then just import to the directory like app/assets/javascripts/jqBootstrapValidation.js and application.js the same which is now.
You don't need
#import "jquery.min.js";
#import "bootstrap.bundle.min.js";
because these have already in the asset pipeline. It should work.

Bootstrap v4 Installing issues in Rails

Or they are? When I use inspect element on any bootstrap component it's taking CSS from application.css (not bootstrap itself). I'm pretty sure I did something wrong when installing even though I went through the guidelines a few times.
Forgot to add I'm using Rails 4.2.6 and using the gem from:
https://github.com/twbs/bootstrap-rubygem#a-ruby-on-rails
This is what I mean, for example the btn classes are working but they do not point to Bootstrap in inspect element but rather to application.css. Also the navbar (copy paste from getbootstrap.com) works as far as javascript dropdowns go but CSS is off.
Gemfile
#Bootstrap V4 Alpha
gem 'bootstrap', '~> 4.0.0.alpha6'
* sprockets-rails (3.2.0)
application.scss
/*
* This is a manifest file that'll be compiled into application.css, which will include all the files
* listed below.
*
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
*
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
* compiled file so the styles you add here take precedence over styles defined in any styles
* defined in the other CSS/SCSS files in this directory. It is generally better to create a new
* file per style scope.
*
*/
#import "bootstrap";
application.js
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require_tree .
//= require bootstrap
In your application.js file place //= require bootstrap after //= require jquery so the file will be look like this:
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require jquery
//= require bootstrap
//= require jquery_ujs
//= require turbolinks
//= require_tree .
Restart your rails server and the changing will take effect.
Look very closely at your application.css file's comments.
* This is a manifest file that'll be compiled into application.css, which will include all the files
* listed below.
This is why it appears as though all the css is coming from the application.css, but you are importing the bootstrap css at the bottom of the file..

Bootstrap Datepicker gem not formatting in rails

I know this type of question has come up before on SO, and I have tried every solution I could find, but nothing seems to work. The javascript is working fine, but for some reason, I can't get the datepicker window to go in the right spot or format correctly. After testing multiple gems, I keep getting this:
There are no errors in my console. Here is what my related gems look like in my Gemfile:
gem 'jquery-rails', "~> 2.3.0"
gem 'bootstrap-sass'
gem 'bootstrap-datepicker-rails'
And here is my application.js
//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require bootstrap
//= require bootstrap-datepicker
//= require_self
And my application.css has:
*= require bootstrap-datepicker
As for the actual html file, it looks like this (application#index.html)
<input type="text" data-behaviour='datepicker' >
<script type="text/javascript">
$(document).ready(function(){
$('[data-behaviour~=datepicker]').datepicker();
})
</script>
Any and all ideas are welcome.
UPDATE:
It seems like my bootstrap css files aren't loading at all. Do I need to use css.scss files? I can't seem to find a straightforward answer online. Manually inserting the css into my application.css file results in this:
Just for a sanity check give the standard jquery datepicker a shot. I generally use it with bootstrap.
app/assets/javascripts/application.js
//= require jquery
//= require jquery_ujs
//= require twitter/bootstrap
//= require jquery.ui.datepicker
//= require jquery.timepicker.js
//= require_tree .
app/assets/stylesheets/application.css
*= require jquery.ui.datepicker
*= require jquery.timepicker.css
*= require_self
*= require_tree .
app/assets/javascripts/your_model.js.coffee
jQuery ->
$("#div_id_here").datepicker dateFormat: "yy-mm-dd"
Since you're using bootstrap-sass, you can (and should) use #import statements instead of *= require statements for your css.scss files. This allows you to define and use variables, etc amongst all of your css.scss files, which allows for full customization of Bootstrap and its components. I'm not sure if there could be something else wrong with your configuration... but I'd suggest starting here anyway since none of your css is showing up. So your application.css.scss file would look like:
# #import any file that may contain variables you'd like to use in any libraries
# added below this point (e.g. `defines.css.css`)
#import "bootstrap_and_overrides";
#import "bootstrap-datepicker";
# #import "whatever other .css.scss files you have...";
Then in bootstrap.css.scss you'd individually import each of the desired bootstrap CSS components after "overriding" any variables. Here is what you need to start from:
variables (this is the basis your variable/style "overrides", placed at the tope of your bootstrap_and_overrides.css.scss file.)
bootstrap components (this is the core of your bootstrap_and_overrides.css.scss file.)

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