Using Rails 3.1, where do you put your "page specific" JavaScript code?
The Asset Pipeline docs suggest how to do controller-specific JS:
For example, if a
ProjectsController
is generated, there will be a new file atapp/assets/javascripts/projects.js.coffee
and another atapp/assets/stylesheets/projects.css.scss
. You should put any JavaScript or CSS unique to a controller inside their respective asset files, as these files can then be loaded just for these controllers with lines such as<%= javascript_include_tag params[:controller] %>
or<%= stylesheet_link_tag params[:controller] %>
.
Link to: asset_pipeline
For the page-specific js you can use Garber-Irish solution.
So your Rails javascripts folder might look like this for two controllers - cars and users:
javascripts/
├── application.js
├── init.js
├── markup_based_js_execution
├── cars
│ ├── init .js
│ ├── index.js
│ └── ...
└── users
└── ...
And javascripts will look like this:
// application.js
//=
//= require init.js
//= require_tree cars
//= require_tree users
// init.js
SITENAME = new Object();
SITENAME.cars = new Object;
SITENAME.users = new Object;
SITENAME.common.init = function (){
// Your js code for all pages here
}
// cars/init.js
SITENAME.cars.init = function (){
// Your js code for the cars controller here
}
// cars/index.js
SITENAME.cars.index = function (){
// Your js code for the index method of the cars controller
}
and markup_based_js_execution will contain code for UTIL object, and on DOM-ready UTIL.init execution.
And don't forget to put this to your layout file:
<body data-controller="<%= controller_name %>" data-action="<%= action_name %>">
I also think that it is better to use classes instead of data-*
attributes, for the better page-specific css. As Jason Garber have mentioned: page-specific CSS selectors can get really awkward (when you use data-*
attributes)
I hope this will help you.
I see that you've answered your own question, but here's another option:
Basically, you're making the assumption that
//= require_tree .
is required. It's not. Feel free to remove it. In my current application, the first I'm doing with 3.1.x honestly, I've made three different top level JS files. My application.js
file only has
//= require jquery
//= require jquery_ujs
//= require_directory .
//= require_directory ./api
//= require_directory ./admin
This way, I can create subdirectories, with their own top level JS files, that only include what I need.
The keys are:
- You can remove
require_tree
- Rails lets you change the assumptions it makes - There's nothing special about the name
application.js
- any file in theassets/javascript
subdirectory can include pre-processor directives with//=
Hope that helps and adds some details to ClosureCowboy's answer.
Sujal
Another option: to create page- or model-specific files, you could create directories inside your assets/javascripts/
folder.
assets/javascripts/global/
assets/javascripts/cupcakes
assets/javascripts/something_else_specific
Your main application.js
manifest file could be configured to load its files from global/
. Specific pages or groups of pages could have their own manifests which load files from their own specific directories. Sprockets will automatically combine the files loaded by application.js
with your page-specific files, which allows this solution to work.
This technique can be used for style_sheets/
as well.