paloma 3.0.2 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## Version 4.0.0
4
+ * https://github.com/kbparagua/paloma/issues/26 - Paloma requests are not saved on `session`.
5
+ * https://github.com/kbparagua/paloma/issues/26 - Chaining with redirect is removed.
6
+ * Routing from javascript is removed.
7
+ * Routing from Rails controller is added.
8
+ * Ability to have a controller-wide setting.
9
+ * https://github.com/kbparagua/paloma/issues/29 - Disable `console.log` and `console.warn` for non-development environments.
10
+
3
11
 
4
12
  ## Version 3.0.2
5
13
  * Bug Fix: Converting Rails controller name to singular form.
data/README.md CHANGED
@@ -1,18 +1,24 @@
1
1
  # Paloma
2
2
 
3
- **This README is for Paloma 3 only.
4
- For version 2 README please go [here](https://github.com/kbparagua/paloma/blob/2.0/README.md).**
3
+ **This README is for Paloma 4 only.**
5
4
 
5
+ **For version 3 README please go [here](https://github.com/kbparagua/paloma/blob/3.0/README.md).**
6
6
 
7
- ## What's New?
8
- Paloma 3 is almost a complete rewrite of the old version.
7
+ **For version 2 README please go [here](https://github.com/kbparagua/paloma/blob/2.0/README.md).**
9
8
 
10
- It is now simpler and more flexible. The old callback thingy paradigm is replaced by a `Router` and `Controller` layer for better abstraction. Generators are also removed, so programmers need not to follow specific directory structure, unlike in the old versions.
9
+
10
+ ## Paloma 4, why so sudden?
11
+ The last major version (v3) of Paloma introduced a major paradigm shift, and it took me a while to realize that some of the major changes introduced are not really that good and needed to be removed.
12
+
13
+
14
+ ## What's new?
15
+ *(compared to version 2)*
16
+ It is now simpler and more flexible. The old callback thingy paradigm is replaced by a `Controller` layer for better abstraction. Generators are also removed, so programmers need not to follow specific directory structure, unlike in the old versions.
11
17
 
12
18
  Previously, there are generators that create Paloma files, and these files are written in vanilla javascript. Because of that there are some users who are requesting for coffeescript setup. Now since there are no generated files programmers can write their code either by using vanilla javascript or **coffeescript**. Yay!
13
19
 
14
- ### Controller and Router
15
- The new paradigm is patterned after Rails Controller and Routes, so it is easier to grasp than the old callback paradigm. Basically, you have a Paloma Controller that is responsible for processing requests made from Rails Controller. While the Router is responsible for telling what Paloma Controller handles what Rails Controller, or what Paloma Controller's action handles what Rails Controller's action.
20
+ ### Controller
21
+ The new paradigm is patterned after Rails Controller, so it is easier to grasp than the old callback paradigm. Basically, you have a Paloma Controller counterpart for every Rails Controller.
16
22
 
17
23
 
18
24
  ### How about Model and View?
@@ -70,7 +76,7 @@ Controllers are just classes that handle requests made by Rails Controllers. Eac
70
76
 
71
77
  ### Creating a Controller
72
78
 
73
- A Controller constructor is created or accessed, if it already exists, using `Paloma.controller()` method.
79
+ A Controller constructor is created or accessed (if it already exists), using `Paloma.controller()` method.
74
80
 
75
81
  ```javascript
76
82
  var ArticlesController = Paloma.controller('Articles');
@@ -78,10 +84,12 @@ var ArticlesController = Paloma.controller('Articles');
78
84
 
79
85
  It will return the constructor function of your controller.
80
86
 
87
+ Note: Using `Paloma.controller` method, you can access the same controller constructor across different files.
88
+
81
89
 
82
90
  ### Handling Actions
83
91
 
84
- Every time a request to Paloma is made (A Rails Controller action is executed), an instance of a Paloma controller is created and a method responsible for the request will be invoked.
92
+ 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.
85
93
 
86
94
  ```javascript
87
95
  var ArticlesController = Paloma.controller('Articles');
@@ -95,32 +103,107 @@ ArticlesController.prototype.edit = function(){
95
103
  };
96
104
  ```
97
105
 
98
- ## Passing Parameters
99
106
 
100
- You can also pass parameters to a Paloma Controller by calling `js` **before** render in your Rails controller. You can access the parameters on your Paloma Controller using `this.params` object.
107
+ ## Advanced Usage
101
108
 
102
- **Example:**
109
+ You can manipulate what controller/action should Paloma execute by calling `js` method **before** rendering.
103
110
 
104
- `users_controller.rb`
105
- ```ruby
106
- def destroy
107
- user = User.find params[:id]
108
- user.destroy
109
-
110
- js :id => user.id
111
- end
112
- ```
111
+ 1. Changing controller
113
112
 
114
- Paloma controller.
113
+ ```ruby
114
+ class UsersController < ApplicationController
115
+ def new
116
+ @user = User.new
117
+ js 'Accounts' # will use Accounts controller instead of Users controller
118
+ end
119
+ end
120
+ ```
115
121
 
116
- ```javascript
117
- var UsersController = Paloma.controller('Users');
122
+ 2. Changing action
118
123
 
119
- UsersController.prototype.destroy = function(){
120
- alert('User ' + this.params['id'] + ' is deleted.');
121
- };
122
- ```
124
+ You can use the symbol syntax:
125
+ ```ruby
126
+ def new
127
+ @user = User.new
128
+ js :register # will execute register method instead of new
129
+ end
130
+ ```
131
+
132
+ Or the string syntax:
133
+ ```ruby
134
+ def new
135
+ @user = User.new
136
+ js '#register'
137
+ end
138
+ ```
139
+
140
+ 3. Changing controller and action.
141
+
142
+ ```ruby
143
+ def new
144
+ @user = User.new
145
+ js 'Accounts#register' # will execute Accounts#register instead of Users#new
146
+ end
147
+ ```
148
+
149
+ 4. Changing controller with namespace.
150
+
151
+ Paloma supports namespaces using '/' as delimiter.
152
+
153
+ ```ruby
154
+ def new
155
+ @user = User.new
156
+ js `Admin/Accounts` # will use Admin/Accounts controller instead of Users controller
157
+ end
158
+ ```
159
+
160
+ ```ruby
161
+ def new
162
+ @user = User.new
163
+ js 'Admin/Accounts#register' # will execute Admin/Accounts#register instead of Users#new
164
+ end
165
+ ```
166
+
123
167
 
168
+ ## Passing Parameters
169
+
170
+ You can access the parameters on your Paloma Controller using `this.params` object.
171
+
172
+
173
+ 1. Parameters only.
174
+
175
+ `users_controller.rb`
176
+ ```ruby
177
+ def destroy
178
+ user = User.find params[:id]
179
+ user.destroy
180
+
181
+ js :id => user.id
182
+ end
183
+ ```
184
+
185
+ Paloma controller.
186
+
187
+ ```javascript
188
+ var UsersController = Paloma.controller('Users');
189
+
190
+ UsersController.prototype.destroy = function(){
191
+ alert('User ' + this.params['id'] + ' is deleted.');
192
+ };
193
+ ```
194
+
195
+ 2. Path with parameters.
196
+
197
+ ```ruby
198
+ def destroy
199
+ user = User.find params[:id]
200
+ user.destroy
201
+
202
+ js 'Accounts#delete', :id => user.id
203
+ end
204
+ ```
205
+
206
+
124
207
  ## Preventing Paloma Execution
125
208
 
126
209
  If you want to Paloma not to execute in a specific Rails Controller action you need to pass `false` as the Paloma parameter.
@@ -132,60 +215,65 @@ def edit
132
215
  end
133
216
  ```
134
217
 
135
- ## Execution Chains
136
218
 
137
- A Paloma request is created every time a Rails Controller action is executed. All requests will be recorded until a render action is triggered, and all Paloma requests will be processed following FIFO (First In, First Out) method.
219
+ ## Controller-wide setup
220
+
221
+ You can call `js` outside Rails controller actions for global or controller-wide settings.
222
+
138
223
 
139
224
  **Example:**
140
225
 
141
226
  ```ruby
142
- def first_action
143
- # Paloma request will be created
144
- redirect_to second_action_path
145
- end
227
+ class UsersController < ApplicationController
228
+ js 'Accounts' # use Accounts controller instead of Users for all actions.
146
229
 
147
- def second_action
148
- # Paloma request will be created
149
- redirect_to third_action_path
150
- end
151
230
 
152
- def third_action
153
- # Paloma request will be created
154
- render :template => 'third_action_view'
231
+ def new
232
+ @user = User.new
233
+ end
234
+
235
+ def show
236
+ @user = User.find params[:id]
237
+ end
155
238
  end
156
239
  ```
157
240
 
158
- When the `third_action` renders its response, Paloma will process all the request starting from `first_action` up to `third_action`. So, Paloma Controller actions responsible for those 3 Rails actions will be executed.
159
-
160
- ## Router
241
+ Like `before_filter` you can also pass `only` and `except` options.
161
242
 
162
- Router is responsible for mapping Rails Controller/action to its equivalent Paloma Controller/action.
163
243
 
164
- By default all Rails Controller will be mapped with a Paloma Controller with the same resource name (controller name without the `Controller` suffix).
244
+ ```ruby
245
+ class UsersController < ApplicationController
165
246
 
166
- Example:
167
- * Requests from `UsersController#new` will be mapped to Paloma Controller named `Users` with its `new` method.
247
+ js 'Admin/Accounts', :except => :destroy # Use Admin/Accounts except for destroy method
168
248
 
169
- If you have no problem with the default behavior, you don't need to write Router stuff in your code.
249
+ end
250
+ ```
170
251
 
171
- ### Changing Controller
172
252
 
173
- If you want to use a different Paloma Controller for a specific Rails Controller, you can do the following:
253
+ **IMPORTANT NOTE:**
254
+ If you are going to pass parameters for Controller-wide settings, put them inside a `:params` hash.
174
255
 
175
- ```javascript
176
- // Instead of mapping Rails UsersController to Paloma Users Controller
177
- // it will be mapped to AdminUsers.
178
- Paloma.router.resource('Users', {controller: 'AdminUsers'});
256
+ ```ruby
257
+ class UsersController < ApplicationController
258
+ js 'Accounts', :params => {:x => 1, :y => 2, :z => 3}, :only => :show
259
+ end
179
260
  ```
180
261
 
181
- ### Redirecting
262
+ ### Overriding Controller-wide setup
182
263
 
183
- You can also redirect an action if you want it to be handled by a different method.
264
+ 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.
184
265
 
185
- ```javascript
186
- // Instead of executing Paloma's `Users#new` it will execute
187
- // `Registrations#signUp`.
188
- Paloma.router.redirect('Users#new', {to: 'Registrations#signUp');
266
+ ```ruby
267
+ class UsersController < ApplicationController
268
+
269
+ js 'Accounts', :params => {:x => 1}
270
+
271
+
272
+ def new
273
+ @user = User.new
274
+ js :register, :y => 2 # will execute Accounts#register with params {:x => 1, :y => 2}
275
+ end
276
+ end
189
277
  ```
190
278
 
191
279
  ## Gotchas
@@ -198,6 +286,6 @@ For example: `render "something.js.erb"`
198
286
  ## Where to put code?
199
287
 
200
288
  Again, Paloma is now flexible and doesn't force developers to follow specific directory structure.
201
- You have the freedom to create controllers and routes anywhere in your application.
289
+ You have the freedom to create controllers anywhere in your application.
202
290
 
203
- Personally, I prefer having a `routes.js` file to contain all the route declarations, and a javascript file for each controller.
291
+ Personally, I prefer having a javascript file for each controller.
@@ -10,21 +10,19 @@
10
10
  return true;
11
11
  }
12
12
 
13
+ Paloma.env = '<%= Rails.env %>';
14
+
13
15
  // Remove any callback details if any
14
16
  $('.js-paloma-hook[data-id!=' + <%= id %> + ']').remove();
15
17
 
16
- var requests = <%= requests.to_json.html_safe %>;
17
-
18
- for (var i = 0, len = requests.length; i < len; i++){
19
- var request = requests[i];
20
-
21
- Paloma.engine.request(request['resource'],
22
- request['action'],
23
- request['params']);
24
- }
25
-
18
+ var request = <%= request.to_json.html_safe %>;
26
19
 
27
- $(document).ready(function(){ Paloma.engine.start(); });
20
+ $(document).ready(function(){
21
+ Paloma.engine.request(
22
+ request['resource'],
23
+ request['action'],
24
+ request['params']);
25
+ });
28
26
 
29
27
  })();
30
28
  </script>
@@ -7,5 +7,7 @@ end
7
7
  # TODO: Rails version checking
8
8
 
9
9
  require 'action_controller/railtie'
10
+ require 'paloma/controller'
11
+ require 'paloma/utilities'
10
12
  require 'paloma/action_controller_extension'
11
13
  require 'paloma/rails/engine'
@@ -5,6 +5,8 @@ module Paloma
5
5
 
6
6
  def self.included base
7
7
  base.send :include, InstanceMethods
8
+ base.send :extend, ClassMethods
9
+
8
10
 
9
11
  base.module_eval do
10
12
  prepend_view_path "#{Paloma.root}/app/views/"
@@ -18,14 +20,78 @@ module Paloma
18
20
 
19
21
 
20
22
 
23
+ module ClassMethods
24
+
25
+ #
26
+ # Controller wide setting for Paloma.
27
+ #
28
+
29
+ def js path_or_options, options = {}
30
+ options ||= {}
31
+
32
+ scope = {}
33
+ scope[:only] = options[:only] if options[:only]
34
+ scope[:except] = options[:except] if options[:except]
35
+
36
+ self.before_filter(
37
+ Proc.new {
38
+ self.js path_or_options, options[:params]
39
+ },
40
+ scope)
41
+ end
42
+ end
43
+
44
+
45
+
46
+
47
+
21
48
  module InstanceMethods
22
49
 
23
50
  #
24
- # Use on controllers to pass variables to Paloma controller.
25
51
  #
26
- def js params = {}
27
- return session[:paloma_requests].pop if !params
28
- session[:paloma_requests].last[:params] = params
52
+ # Specify the behavior of Paloma. Call this manually to override the
53
+ # default Paloma controller/action to be executed.
54
+ #
55
+ # Can call a different Controller or execute a different action, and
56
+ # pass parameters.
57
+ #
58
+ # Usage:
59
+ #
60
+ # js 'Controller', {params}
61
+ # js 'Controller#action', {params}
62
+ # js 'Namespace/Controller', {params}
63
+ # js 'Namespace/Controller#action', {params}
64
+ # js '#action', {params}
65
+ # js :action, {params}
66
+ # js :param_1 => 1, :param_2 => 2
67
+ #
68
+ #
69
+ def js path_or_options, params = {}
70
+ return self.paloma.clear_request if !path_or_options
71
+
72
+ self.paloma.params.merge! params || {}
73
+
74
+ #
75
+ # 'Controller'
76
+ # 'Controller#action'
77
+ # 'Namespace/Controller'
78
+ # 'Namespace/Controller#action'
79
+ # '#action'
80
+ #
81
+ if path_or_options.is_a? String
82
+ route = ::Paloma::Utilities.interpret_route path_or_options
83
+ self.paloma.resource = route[:resource] unless route[:resource].blank?
84
+ self.paloma.action = route[:action] unless route[:action].blank?
85
+
86
+ # :action
87
+ elsif path_or_options.is_a? Symbol
88
+ self.paloma.action = path_or_options
89
+
90
+ # :param_1 => 1, :param_2 => 2
91
+ elsif path_or_options.is_a? Hash
92
+ self.paloma.params.merge! path_or_options || {}
93
+
94
+ end
29
95
  end
30
96
 
31
97
 
@@ -35,13 +101,8 @@ module Paloma
35
101
  # Keeps track of what Rails controller/action is executed.
36
102
  #
37
103
  def track_paloma_request
38
- resource = controller_path.split('/').map(&:titleize).join('/').gsub(' ', '')
39
-
40
- paloma_request = {:resource => resource,
41
- :action => self.action_name}
42
-
43
- session[:paloma_requests] ||= []
44
- session[:paloma_requests].push paloma_request
104
+ self.paloma.resource ||= ::Paloma::Utilities.get_resource controller_path
105
+ self.paloma.action ||= self.action_name
45
106
  end
46
107
 
47
108
 
@@ -53,11 +114,11 @@ module Paloma
53
114
  # will execute the tracked Paloma requests.
54
115
  #
55
116
  def append_paloma_hook
56
- return true if session[:paloma_requests].empty?
117
+ return true if self.paloma.has_no_request?
57
118
 
58
119
  hook = view_context.render(
59
120
  :partial => 'paloma/hook',
60
- :locals => {:requests => session[:paloma_requests]})
121
+ :locals => {:request => self.paloma.request})
61
122
 
62
123
  before_body_end_index = response_body[0].rindex('</body>')
63
124
 
@@ -72,7 +133,7 @@ module Paloma
72
133
  response.body += hook
73
134
  end
74
135
 
75
- session[:paloma_requests] = nil
136
+ self.paloma.clear_request
76
137
  end
77
138
  end
78
139
 
@@ -88,11 +149,19 @@ module Paloma
88
149
  #
89
150
  def render options = nil, extra_options = {}, &block
90
151
  [:json, :js, :xml, :file].each do |format|
91
- js false if options.has_key?(format)
152
+ self.paloma.clear_request if options.has_key?(format)
92
153
  end if options.is_a?(Hash)
93
154
 
94
155
  super
95
156
  end
157
+
158
+
159
+ protected
160
+
161
+ def paloma
162
+ @paloma ||= ::Paloma::Controller.new
163
+ end
164
+
96
165
  end
97
166
 
98
167