app/views/paloma | ||
lib | ||
test_app | ||
vendor/assets/javascripts/paloma | ||
.gitignore | ||
Changelog.md | ||
DEVELOPMENT.md | ||
Gemfile | ||
License | ||
paloma.gemspec | ||
README.md | ||
TODO.md |
Important
master
branch contains the bleeding edge development code.- check
branches
ortags
for the latest stable release or specific versions.
Paloma
Page-specific javascript for Rails done right.
Advantages
- Choose what specific javascript code to run per page.
- Easily make ruby variables available on your javascript files.
- Can be written using vanilla javascript, coffeescript, and anything that compiles to js.
- Easy to understand (because it is patterned after Rails' controller module).
Quick Example
Paloma controller.
var UsersController = Paloma.controller('Users');
// Executes when Rails User#new is executed.
UsersController.prototype.new = function(){
alert('Hello Sexy User!' );
};
The Rails controller app/controllers/users_controller.rb
:
def UsersController < ApplicationController
def new
# a Paloma request will automatically be created.
@user = User.new
end
end
That's it! Simply Sexy!
Minimum Requirements
- jQuery 1.7 or higher
- Rails 3.1 or higher
Install
- Without bundler:
sudo gem install paloma
. - With bundler, add this to your Gemfile:
gem 'paloma'
- Require
paloma
in yourapplication.js
://= require paloma
Controllers
Controllers are just classes that handle requests made by Rails Controllers. Each Rails Controller's action will be mapped to a specific Paloma Controller's action.
Creating a Controller
A Controller constructor is created or accessed (if it already exists), using Paloma.controller()
method.
var ArticlesController = Paloma.controller('Articles');
It will return the constructor function of your controller.
Note: Using Paloma.controller
method, you can access the same controller constructor across different files.
Handling Actions
Every time a request to Paloma is made (A Rails Controller action is executed), an instance of a Paloma controller is created and the method responsible for the request will be invoked.
var ArticlesController = Paloma.controller('Articles');
ArticlesController.prototype.new = function(){
// Handle new articles
};
ArticlesController.prototype.edit = function(){
// Handle edit articles
};
Advanced Usage
You can manipulate what controller/action should Paloma execute by calling js
method before rendering.
-
Changing controller
class UsersController < ApplicationController def new @user = User.new js 'Accounts' # will use Accounts controller instead of Users controller end end
-
Changing action
You can use the symbol syntax:
def new @user = User.new js :register # will execute register method instead of new end
Or the string syntax:
def new @user = User.new js '#register' end
-
Changing controller and action.
def new @user = User.new js 'Accounts#register' # will execute Accounts#register instead of Users#new end
-
Changing controller with namespace.
Paloma supports namespaces using '/' as delimiter.
def new @user = User.new js `Admin/Accounts` # will use Admin/Accounts controller instead of Users controller end
def new @user = User.new js 'Admin/Accounts#register' # will execute Admin/Accounts#register instead of Users#new end
Passing Parameters
You can access the parameters on your Paloma Controller using this.params
object.
-
Parameters only.
users_controller.rb
def destroy user = User.find params[:id] user.destroy js :id => user.id end
Paloma controller.
var UsersController = Paloma.controller('Users'); UsersController.prototype.destroy = function(){ alert('User ' + this.params['id'] + ' is deleted.'); };
-
Path with parameters.
def destroy user = User.find params[:id] user.destroy js 'Accounts#delete', :id => user.id end
Preventing Paloma Execution
If you want to Paloma not to execute in a specific Rails Controller action you need to pass false
as the Paloma parameter.
def edit
@user = User.find params[:id]
js false
end
Controller-wide setup
You can call js
outside Rails controller actions for global or controller-wide settings.
Example:
class UsersController < ApplicationController
js 'Accounts' # use Accounts controller instead of Users for all actions.
def new
@user = User.new
end
def show
@user = User.find params[:id]
end
end
Like before_filter
you can also pass only
and except
options.
class UsersController < ApplicationController
js 'Admin/Accounts', :except => :destroy # Use Admin/Accounts except for destroy method
end
IMPORTANT NOTE:
If you are going to pass parameters for Controller-wide settings, put them inside a :params
hash.
class UsersController < ApplicationController
js 'Accounts', :params => {:x => 1, :y => 2, :z => 3}, :only => :show
end
Overriding Controller-wide setup
If you want to override the controller-wide setup, just call js
again inside a controller action. From there you can override the controller/action or pass additional parameters.
class UsersController < ApplicationController
js 'Accounts', :params => {:x => 1}
def new
@user = User.new
js :register, :y => 2 # will execute Accounts#register with params {:x => 1, :y => 2}
end
end
Turbolinks Support
As of version 4.1.0
, Paloma is compatible with Turbolinks without additional setup.
Execute Paloma when user hits Back
or Forward
button.
Paloma executes page-specific javascript by adding a <script>
tag to the response body. Turbolinks, by default, executes any inline javascript in the response body when you visit a page, so the <script>
tag appended by Paloma will automatically be executed. However, when Turbolinks restores a page from cache (this happens when a user hits Back
or Forward
button in his browser) any inline javascript will not be executed anymore. This is the intentional behavior of Turbolinks, and it is not a bug. If you want to execute Paloma again when Turbolinks restores a page, do something like this:
$(document).on('page:restore', function(){
// Manually evaluates the appended script tag.
Paloma.executeHook();
});
Turbolinks without jquery.turbolinks
gem
You need to manually run Paloma every page load if you are not using jquery.turbolinks
gem.
In your application.js
$(document).on('page:load', function(){
Paloma.executeHook();
Paloma.engine.start();
});
Gotchas
-
Paloma will execute on all
render
calls, except for calls with the following formats:js
,json
,xml
, andfile
.Example:
render :json => {:x => 1} # Paloma will not execute` render :partial => '/path/to/partial' # Paloma will execute
-
It will cause conflicts if you have a controller and a module that has the same name.
Example:
var AdminController = Paloma.controller('Admin'); // This will override the AdminController and replace it // with a module named 'Admin'. var UsersController = Paloma.controller('Admin/Users');
Where to put code?
Again, Paloma is now flexible and doesn't force developers to follow specific directory structure. You have the freedom to create controllers anywhere in your application.
Personally, I prefer having a javascript file for each controller.
Contribute
- Fork.
- Do awesome things.
- Submit Pull-Request to
master
branch. - Add short summary of changes on your PR.