I know that for every controller, there's a separate SASS and CoffeeScript file to keep things organized. But what about styling the application layout itself? How is it that there's no files to put all the styling and JS related to the whole layout?
I know there's application.css and application.js, but I Know these are not to be messed with because these files put everything together.
I hope someone could put me in the right track!
the application.css and application.js are manifest file and there you can see require_tree . that load all your js file for application.js and in same manner for application.css now on compiling assets pipeline make a minified version of that and create only one file that hold all the js in itself if you want to create two manifest file you can also do that .
Related
I am new to rails and I'm a bit confused about how assets are loaded. I can get things working but I would like to understand what really happens behind the scenes.
I have been reading the documentation but there are things that I don't understand completely.
MANIFEST FILE
First thing that confuses me is the usage of manifest files.
For instance if in my app/assets/javascripts/application.js file I have:
//= require_tree .
Rails documentation says:
tells Sprockets to recursively include all JavaScript files in the
specified directory into the output
What isn't clear to me is which directory? app/assets/javascripts/?
Does that mean that if I add a file in app/assets/javascripts/ it will be loaded and served?
If I add a gem that requires to add a file example.js I need to add to the manifest file:
//= require example.js
But why is this necessary if //= require_tree already loads and serve files in app/assets/javascripts/ which is the location where I have put my example.js? Ok that allows me to specify the order if later I add more requires. But other than that?
HTML FILE
And then the script to be included in application.html.erb
<%= javascript_include_tag ('application'), 'data-turbolinks-track' => true %>
I understand this loads the application.js file mentioned above and therefore the various //= require in it.
Sometimes happens that is required to script the particular file as:
<script src="js/example.js"></script>
Is this scenario wouldn't be <script src="js/example.js"></script> doing the exact same thing of //= require example.js?
PUBLIC VS APP ASSETS
I understand that if I place my example.js file on public/assets folder it won't be compiled but served separately. Why would I do that? Is it reasonable to do it in case a file is not served correctly when concatenated and compiled and works only if served separated? In other words, if I include a .js file on app/assest and it has problems to load or break things, is it worth to try to remove it from there and move it to public/assets or does this just not make sense?
APP ASSETS VS VENDOR ASSETS
On which scenario should I add a file to vendor assets instead of app assets? What is the difference between adding it to a place or another?
And in my vendor/assets/javascripts I have only an empty .keep file. So there'n so such thing as manifest file on app/assets. How are files in this folder referenced then?
For directives that take a path argument, you may specify either a
logical path or a relative path. Relative paths begin with ./ and
reference files relative to the location of the current file.
So //= require_tree . tells sprockets to load any files in app/assets/javascripts/ and concatenate them into application.js.
Is this scenario wouldn't be <script src="js/example.js"></script>
doing the exact same thing of //= require example.js?
No. Rails serves the assets as seperate files in development so that you get a meaningful line number and file reference when errors occur.
In production it concatenates and minifies the assets which is important for performance.
Sprockets does not check your views / layouts for script tags. So the the former would result in two requests.
I understand that if I place my example.js file on public/assets
folder it won't be compiled but served separately. Why would I do
that?
The public directory is placed under the servers web root. Since the files there are served without much intervention its a good place for things like error pages or where you need assets that have a static name without a cache busting fingerprint.
On which scenario should I add a file to vendor assets instead of app
assets? What is the difference between adding it to a place or
another?
/vendor/assets is the place to put assets that are not created by you or which are not part of the application. Both are added to the sprockets load paths so the results are identical. Its rather just a question of code organisation.
https://github.com/rails/sprockets
http://guides.rubyonrails.org/asset_pipeline.html
I am developing a rails application starting from webarch template. I know that adding the whole assets folder in the public/ folder will link the assets with my views, but it would not be taking advantage of the assets pipeline functions. The template has a lot of plugins and different options and one generally does not use all of it. The assets folder's size is 30MB.
I though about putting it inside vendor/assets and using it with the asset pipeline but this generates two problems:
I would be serving 30MB of minified code and using a small percentage of it in my app.
I would have to manually rewrite the whole assets folder to use links the way asset pipeline wants it (javascript_include_tag "file" to serve file.js). Of course, I would do this via a script but it still seems like a problem someone should have encountered first.
Since neither vendor/assets and public/ folders seem to be a proper location for these files I would like a better option (or a way to make the later options work better).
A solution to keep your files under asset pipeline when they are too big to reasonably be left in one single minimified asset file is to split your assets by categories, compile those categories in different minimified files, and include them in your views when needed.
I do it for an app that contains several "heavy" javascripts components that are located in different area of my app and are not often used.
1- Organize your file structure
In app/assets/javascrips and app/assets/stylesheets create one directory per category we are going to create. Examples:
app/assets/javascrips/common
app/assets/javascrips/admin
app/assets/javascrips/user_account
2- Create your manifests
In app/assets/javascrips and app/assets/stylesheets create one manifest file per category and have them included the related directory
File app/assets/javascrips/common.js
//= require jquery
//= require_tree ./common
File app/assets/javascrips/admin.js
//= require_tree ./admin
File app/assets/javascrips/user_account.js
//= require_tree ./user_account
3- Add your manifests to rails precompile list
You can do it in config/application.rb file, but when it gets big it is preferable to create an initializer file config/initializers/assets.rb
Rails.application.configure do
config.assets.precompile += %w[common.js admin.js user_account.js]
end
4- Include them in your views and layouts, and set-up your javascript libraries.
Import the assets files into layouts and views. It can be a good idea to create several layouts for different area of your application that would be using common assets files. The methods to use are
stylesheet_link_tag 'manifest_file' and javascript_include_tag 'manifest_file'
And keep in mind you may have to tell your javascript plug-ins they need to use the miniminied file when dynamically loading files. For them you can use a configuration .js.erb file. Example:
File app/assets/javascrips/admin/plug-in_config.js.erb
PLUGIN.config('dynamicFileName', '<%= javascript_path('manifest_file') %>');
If I have a home.scss file (associated with a home.html.erb view), does the CSS placed in there override the CSS in my application.scss or does the application.scss override any other css in the asset pipeline?
Actually, all the css files in your /assets directory get combined (along with application.css) to make one giant file which is applied to your application. The separate files are there to help you organize your code, but don't actually separate them in any substantive sense.
Between application.css and controller specific css files, the application.css file loads last, overriding whatever duplicate rules you might have specified in a controller specific version.
You actually shouldn't be putting anything other than directives in application.css.
I have a plugin with many types of files, and its own tree structure (html, css, js, documentation, images, etc)
Rather than going through the plugin folder, and splitting all the css and js files into the vendor/assets/js/ vendor/assets/css/ folders, I want to just keep the entire plugin folder as is. For example,
vendor/assets/multipurpose_bookshelf_slider/
How do I make sure the paths load properly, and reference them in my manifest files?
Currently, I have some files place as follows (not exhaustive)
/my_app/vendor/assets/multipurpose_bookshelf_slider/css/skin01.css
/my_app/vendor/assets/multipurpose_bookshelf_slider/js/jquery.easing.1.3.js
/my_app/vendor/assets/multipurpose_bookshelf_slider/
/my_app/vendor/assets/multipurpose_bookshelf_slider/
I'm referencing them in
application.js
//= require multipurpose_bookshelf_slider/js/jquery.easing.1.3.js
//= require multipurpose_bookshelf_slider/js/jquery.bookshelfslider.min.js
application.css.scss
#import "css/bookshelf_slider";
#import "css/skin01";
Any folder created directly under assets will be added to the load paths. Files in that folder can be referenced as usual like so:
If you have
vendor/assets/custom/js/file.js
vendor/assets/custom/css/file.css
then vendor/assets/custom/ will be added to the load paths.
Include your files in the following files by doing the following:
application.js
//= require js/file
application.css.scss
#import "css/file";
Once that's done, make sure to restart your local server, since it is upon starting your server that the load paths get recognized.
Note: to see a list of load paths, type in your terminal rails c, then type Rails.application.config.assets.paths.
If the application you're running has the assets-pipeline activated, it should find your assets after expanding the path in your application.rb
config.assets.paths << Rails.root.join("multipurpose_bookshelf_slider")
I prefer D7na's answer but with a bit of improvement in my opinion.
As long as this is related to assets, I think it is better to be placed in the assets.rb file.
assets.rb:
Rails.application.config.assets.paths << Rails.root.join("multipurpose_bookshelf_slider")
I am using rails 3.2.12 and created a css file in assets/stylesheets/equipment.css to go along with a controller called equipment_controller.rb. This stylesheet isn't working. What do I need to do to get this included in the pipeline?
The file needs to be loaded into your application.css.
In your application.css file, you will either need to load the file manually (by adding require equipment to the manifest at the top of the file), or it will also be included if you have a require_tree line.
See http://guides.rubyonrails.org/asset_pipeline.html#manifest-files-and-directives for more information.
Make sure you have the *= require_tree . in your application.css. It will be responsible to include all stylesheets from the current directory.
I cleared the contents and changed the extension from .css to .css.scss. And now it works.