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
-
In your layouts insert Paloma hook.
application.html.erb
<html> <head> </head> <body> <%= yield %> <%= insert_paloma_hook %> </body> </html>
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
Hook
insert_paloma_hook
is a helper method that you can use in your views to insert Paloma's HTML hook.
Inside this HTML hook is where the magic happens. This is the reason why Paloma can magically know what Javascript controller/action to execute. To further understand how Paloma works, you can inspect the HTML hook, by checking the generated HTML (inspect element) and locate the div
element that has the class js-paloma-hook
.
Ideally, you just need to call insert_paloma_hook
in your layouts, since the layout will always be included in every rendered view. But if you are rendering a view without a layout, make sure to call insert_paloma_hook
in that view.
AJAX
-
Make sure that the AJAX response contains the html hook. (use
insert_paloma_hook
) -
Execute the hook and start Paloma's engine on complete/success.
$.get('http://example.com', function(response){ $('#result').html(response); // Execute Paloma hook and start the engine. Paloma.executeHook(); Paloma.engine.start(); });
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
-
Make sure that the rendered view has the paloma hook (use
insert_paloma_hook
) for Paloma to 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.