2015-04-24 11:21:13 -04:00
**Important**
- `master` branch contains the bleeding edge development code.
- check `branches` or `tags` for the latest stable release or specific versions.
2013-10-12 08:48:18 -04:00
# Paloma
2015-04-24 11:08:20 -04:00
Page-specific javascript for Rails done right.
2013-10-12 22:08:49 -04:00
2013-10-12 08:48:18 -04:00
## Advantages
* Choose what specific javascript code to run per page.
2013-01-25 22:08:50 -05:00
* Easily make ruby variables available on your javascript files.
2015-04-24 11:10:03 -04:00
* Can be written using vanilla javascript, coffeescript, and anything that compiles to js.
2016-03-07 00:18:49 -05:00
* No external library dependency.
2015-04-24 11:10:03 -04:00
* Easy to understand (*because it is patterned after Rails' controller module*).
2013-10-12 08:55:14 -04:00
2013-10-12 08:48:18 -04:00
## Quick Example
2012-12-19 02:56:52 -05:00
2013-10-12 08:55:14 -04:00
Paloma controller.
2012-12-19 02:56:52 -05:00
```javascript
2016-03-06 22:17:59 -05:00
Paloma.controller('Users', {
new: function(){
// Executes when Rails User#new is executed.
alert('Hello Sexy User!');
}
});
2012-12-19 02:56:52 -05:00
```
The Rails controller `app/controllers/users_controller.rb` :
```ruby
def UsersController < ApplicationController
def new
2016-03-01 22:52:54 -05:00
# nothing special
2013-10-12 09:24:40 -04:00
@user = User.new
2012-12-19 02:56:52 -05:00
end
end
```
That's it! Simply Sexy!
2013-10-12 22:39:27 -04:00
## Minimum Requirements
2012-12-19 02:56:52 -05:00
* Rails 3.1 or higher
2012-12-18 04:47:24 -05:00
2013-10-12 08:55:14 -04:00
## Install
2016-03-01 22:52:54 -05:00
1. Install gem.
- Without bundler: `sudo gem install paloma` .
- With bundler, add this to your Gemfile: `gem 'paloma'`
2015-04-25 05:30:33 -04:00
1. Require `paloma` in your `application.js` : `//= require paloma`
2016-03-01 22:52:54 -05:00
1. In your layouts insert Paloma's hook.
2015-04-25 05:30:33 -04:00
`application.html.erb`
```html
< html >
< head >
< / head >
< body >
< %= yield %>
< %= insert_paloma_hook %>
< / body >
< / html >
```
2013-10-12 09:12:10 -04:00
2016-03-01 22:52:54 -05:00
1. Start Paloma. *Most of the time this will be inside `document.ready`* .
```js
$(document).ready(function(){
2016-03-07 00:18:49 -05:00
// Execute Paloma's callback.
2016-03-01 22:52:54 -05:00
Paloma.start();
});
```
2013-10-12 22:39:27 -04:00
## Controllers
2013-10-12 09:05:06 -04:00
2016-03-07 00:18:49 -05:00
Controllers are classes that handle requests made by Rails Controllers. Each Rails Controller's action will be mapped to a specific Paloma Controller's action.
2013-10-12 09:24:40 -04:00
2013-10-12 22:39:27 -04:00
### Creating a Controller
2013-10-12 09:24:40 -04:00
2014-02-15 06:25:44 -05:00
A Controller constructor is created or accessed (if it already exists), using `Paloma.controller()` method.
2013-10-12 09:24:40 -04:00
```javascript
2013-10-13 06:25:12 -04:00
var ArticlesController = Paloma.controller('Articles');
2013-10-12 09:24:40 -04:00
```
2013-10-12 22:39:27 -04:00
It will return the constructor function of your controller.
2013-10-12 09:24:40 -04:00
2014-02-15 06:25:44 -05:00
Note: Using `Paloma.controller` method, you can access the same controller constructor across different files.
2013-10-12 09:24:40 -04:00
2013-10-12 22:39:27 -04:00
### Handling Actions
2013-10-12 09:24:40 -04:00
2014-02-15 06:34:15 -05:00
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.
2013-10-12 22:39:27 -04:00
2016-03-07 00:18:49 -05:00
Add actions directly to the constructor's prototype.
2013-10-12 09:24:40 -04:00
```javascript
2016-03-07 00:18:49 -05:00
var Articles = Paloma.controller('Articles');
Articles.prototype.edit = function(){
// Handle edit article
};
```
2016-03-07 00:36:59 -05:00
Or pass the prototype value directly as the 2nd argument of the `controller` method.
2016-03-07 00:18:49 -05:00
```js
2016-03-06 22:17:59 -05:00
Paloma.controller('Articles', {
edit: function(){
2016-03-07 00:18:49 -05:00
// Handle edit article
2016-03-06 22:17:59 -05:00
}
});
2013-10-12 09:24:40 -04:00
```
2013-10-12 09:05:06 -04:00
2016-03-07 00:27:30 -05:00
### Namespace
Namespaced controller should follow this format: `namespace/controller` .
Rails controller:
```ruby
class Admin::UsersController < ApplicationController
def new
@user = User.new
end
end
```
Paloma controller:
```js
Paloma.controller('Admin/Users', {
new: function(){
// Handle new admin user
}
});
```
### Controller Inheritance
It is also possible to create a controller that is a subclass of an existing controller, using the following syntax:
`Controller < ParentController`
```js
Paloma.controller('Application', {
index: function(){
alert('Application: Index');
},
new: function(){
alert('Application: New');
}
});
Paloma.controller('Users < Application ' , {
// Override Application's new action
new: function(){
alert('Users: New');
}
});
```
2014-02-15 06:34:15 -05:00
## Advanced Usage
2014-02-15 07:08:17 -05:00
You can manipulate what controller/action should Paloma execute by calling `js` method **before** rendering.
2014-02-15 06:34:15 -05:00
1. Changing controller
2014-02-15 07:08:17 -05:00
2014-02-15 06:40:22 -05:00
```ruby
class UsersController < ApplicationController
def new
@user = User.new
js 'Accounts' # will use Accounts controller instead of Users controller
end
end
```
2014-02-15 06:34:15 -05:00
2014-02-15 06:40:22 -05:00
2. Changing action
2014-02-15 07:08:17 -05:00
2014-02-15 06:40:22 -05:00
You can use the symbol syntax:
```ruby
2014-02-15 06:34:15 -05:00
def new
@user = User.new
2014-02-15 06:40:22 -05:00
js :register # will execute register method instead of new
2014-02-15 06:34:15 -05:00
end
2014-02-15 06:40:22 -05:00
```
Or the string syntax:
```ruby
def new
@user = User.new
js '#register'
end
```
2014-02-15 06:34:15 -05:00
2014-02-15 07:08:17 -05:00
3. Changing controller and action.
2014-02-15 06:40:22 -05:00
```ruby
def new
@user = User.new
js 'Accounts#register' # will execute Accounts#register instead of Users#new
end
```
2014-02-15 06:34:15 -05:00
2014-02-15 07:08:17 -05:00
4. Changing controller with namespace.
2014-02-15 06:40:22 -05:00
Paloma supports namespaces using '/' as delimiter.
2014-02-15 06:34:15 -05:00
2014-02-15 06:40:22 -05:00
```ruby
def new
@user = User.new
js `Admin/Accounts` # will use Admin/Accounts controller instead of Users controller
end
```
```ruby
def new
@user = User.new
js 'Admin/Accounts#register' # will execute Admin/Accounts#register instead of Users#new
end
```
2014-02-15 07:08:17 -05:00
## Passing Parameters
2016-03-07 00:36:59 -05:00
You can pass parameters to your Paloma Controller in two ways.
2014-02-15 07:08:17 -05:00
2016-03-07 00:36:59 -05:00
1. Passing a hash. (*parameters only*)
2014-02-15 07:08:17 -05:00
2016-03-07 00:36:59 -05:00
```ruby
def show
user = User.find params[:id]
2014-02-15 07:08:17 -05:00
2016-03-07 00:36:59 -05:00
js :id => user.id
end
```
2. Passing path and a hash.
```ruby
def show
user = User.find params[:id]
js 'Admin/Users', :id => user.id
end
```
2014-02-15 07:08:17 -05:00
2016-03-07 00:36:59 -05:00
Using both ways, you can access the passed params using the `params` property of your Paloma controller.
2014-02-15 07:08:17 -05:00
2016-03-07 00:36:59 -05:00
```javascript
Paloma.controller('Users', {
show: function(){
alert("User id: " + this.params.id);
}
});
```
2014-02-15 07:08:17 -05:00
2013-10-12 22:39:27 -04:00
## Preventing Paloma Execution
2013-03-02 11:15:44 -05:00
2013-10-12 22:39:27 -04:00
If you want to Paloma not to execute in a specific Rails Controller action you need to pass `false` as the Paloma parameter.
2013-03-02 11:15:44 -05:00
2013-10-12 09:36:38 -04:00
```ruby
def edit
@user = User.find params[:id]
js false
end
2013-03-02 11:36:36 -05:00
```
2013-03-02 11:33:26 -05:00
2012-12-19 05:39:30 -05:00
2014-02-15 07:08:17 -05:00
## Controller-wide setup
You can call `js` outside Rails controller actions for global or controller-wide settings.
**Example:**
```ruby
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.
```ruby
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.
```ruby
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.
```ruby
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
```
2015-04-25 05:52:53 -04:00
## Hook
`insert_paloma_hook` is a helper method that you can use in your views to insert Paloma's HTML hook.
2015-04-25 05:56:35 -04:00
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` .
2015-04-25 05:52:53 -04:00
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.
2014-06-07 07:47:00 -04:00
2015-05-01 01:06:56 -04:00
## AJAX
1. Make sure that the AJAX response contains the html hook. (use `insert_paloma_hook` )
2016-03-01 22:52:54 -05:00
2. Start Paloma on complete/success.
2015-05-01 01:06:56 -04:00
```js
$.get('http://example.com', function(response){
$('#result').html(response);
2016-03-01 22:52:54 -05:00
Paloma.start();
2015-05-01 01:06:56 -04:00
});
```
2014-06-07 07:47:00 -04:00
## Turbolinks Support
### 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:
```js
$(document).on('page:restore', function(){
2016-03-01 22:52:54 -05:00
Paloma.start();
2014-06-07 07:47:00 -04:00
});
```
2013-10-12 09:36:38 -04:00
## Gotchas
2012-12-19 05:39:30 -05:00
2015-04-25 05:30:33 -04:00
* Make sure that the rendered view has the paloma hook (*use `insert_paloma_hook` *) for Paloma to execute.
2013-10-12 09:36:38 -04:00
2013-10-12 10:09:02 -04:00
## Where to put code?
2013-10-12 22:39:27 -04:00
Again, Paloma is now flexible and doesn't force developers to follow specific directory structure.
2014-02-15 07:08:17 -05:00
You have the freedom to create controllers anywhere in your application.
2013-10-12 10:09:02 -04:00
2014-02-15 06:25:44 -05:00
Personally, I prefer having a javascript file for each controller.
2015-04-16 23:36:24 -04:00
## Contribute
1. Fork.
2. Do awesome things.
3. Submit Pull-Request to `master` branch.
4. Add short summary of changes on your PR.