rabl 0.2.1 → 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. data/README.md +136 -76
  2. data/lib/rabl/engine.rb +13 -0
  3. data/lib/rabl/version.rb +1 -1
  4. metadata +3 -5
data/README.md CHANGED
@@ -17,12 +17,16 @@ Anyone who has tried the 'to_json' method used in ActiveRecord for generating a
17
17
 
18
18
  Install RABL as a gem:
19
19
 
20
- gem install rabl
20
+ ```
21
+ gem install rabl
22
+ ```
21
23
 
22
24
  or add to your Gemfile:
23
25
 
24
- # Gemfile
25
- gem 'rabl'
26
+ ```ruby
27
+ # Gemfile
28
+ gem 'rabl'
29
+ ```
26
30
 
27
31
  and run `bundle install` to install the dependency.
28
32
 
@@ -78,13 +82,15 @@ That's the basic overview but there is a lot more (partials, inheritance, custom
78
82
 
79
83
  RABL is intended to require little to no configuration to get working. This is the case in most scenarios, but depending on your needs you may want to set the following global configurations in your application (this block is completely optional):
80
84
 
81
- # config/initializers/rabl_init.rb
82
- Rabl.configure do |config|
83
- # Commented as these are the defaults
84
- # config.include_json_root = true
85
- # config.include_xml_root = false
86
- # config.enable_json_callbacks = false
87
- end
85
+ ```ruby
86
+ # config/initializers/rabl_init.rb
87
+ Rabl.configure do |config|
88
+ # Commented as these are the defaults
89
+ # config.include_json_root = true
90
+ # config.include_xml_root = false
91
+ # config.enable_json_callbacks = false
92
+ end
93
+ ```
88
94
 
89
95
  Each option specifies behavior related to RABL's output. If `include_json_root` is disabled that removes the root node for each child in the output, and `enable_json_callbacks` enables support for 'jsonp' style callback output if the incoming request has a 'callback' parameter.
90
96
 
@@ -94,31 +100,41 @@ Each option specifies behavior related to RABL's output. If `include_json_root`
94
100
 
95
101
  To declare the data object for use in the template:
96
102
 
97
- # app/views/users/show.json.rabl
98
- object @user
103
+ ```ruby
104
+ # app/views/users/show.json.rabl
105
+ object @user
106
+ ```
99
107
 
100
108
  or specify an alias for the object:
101
109
 
102
- object @user => :person
103
- # => { "person" : { ... } }
110
+ ```ruby
111
+ object @user => :person
112
+ # => { "person" : { ... } }
113
+ ```
104
114
 
105
115
  or pass a collection of objects:
106
116
 
107
- collection @users
108
- # => [ { "user" : { ... } } ]
117
+ ```ruby
118
+ collection @users
119
+ # => [ { "user" : { ... } } ]
120
+ ```
109
121
 
110
122
  or even specify a root node label for the collection:
111
123
 
112
- collection @users => :people
113
- # => { "people" : [ { "person" : { ... } } ] }
124
+ ```ruby
125
+ collection @users => :people
126
+ # => { "people" : [ { "person" : { ... } } ] }
127
+ ```
114
128
 
115
129
  and this will be used as the default data for the rendering.
116
130
 
117
131
  There can also be odd cases where the root-level of the response doesn't map directly to any object:
118
132
 
119
- object false
120
- code(:some_count) { |m| @user.posts.count }
121
- child(@user) { attribute :name }
133
+ ```ruby
134
+ object false
135
+ code(:some_count) { |m| @user.posts.count }
136
+ child(@user) { attribute :name }
137
+ ```
122
138
 
123
139
  In those cases, object can be assigned to 'false' and child nodes can be constructed independently.
124
140
 
@@ -126,50 +142,64 @@ In those cases, object can be assigned to 'false' and child nodes can be constru
126
142
 
127
143
  Basic usage of the templater to define a few simple attributes for the response:
128
144
 
129
- # app/views/users/show.json.rabl
130
- attributes :id, :foo, :bar
145
+ ```ruby
146
+ # app/views/users/show.json.rabl
147
+ attributes :id, :foo, :bar
148
+ ```
131
149
 
132
150
  or use with aliased attributes:
133
151
 
134
- # Take the value of model attribute `foo` and name the node `bar`
135
- attribute :foo => :bar
136
- # => { bar : 5 }
152
+ ```ruby
153
+ # Take the value of model attribute `foo` and name the node `bar`
154
+ attribute :foo => :bar
155
+ # => { bar : 5 }
156
+ ```
137
157
 
138
158
  or even multiple aliased attributes:
139
159
 
140
- attributes :bar => :baz, :dog => :animal
141
- # => # { baz : <bar value>, animal : <dog value> }
160
+ ```ruby
161
+ attributes :bar => :baz, :dog => :animal
162
+ # => # { baz : <bar value>, animal : <dog value> }
163
+ ```
142
164
 
143
165
  ### Child Nodes ###
144
166
 
145
167
  Often a response requires including nested information from data associated with the parent model:
146
168
 
147
- child :address do
148
- attributes :street, :city, :zip, :state
149
- end
169
+ ```ruby
170
+ child :address do
171
+ attributes :street, :city, :zip, :state
172
+ end
173
+ ```
150
174
 
151
175
  You can also add child nodes from an arbitrary data source:
152
176
 
153
- child @posts => :foobar do
154
- attributes :id, :title
155
- end
177
+ ```ruby
178
+ child @posts => :foobar do
179
+ attributes :id, :title
180
+ end
181
+ ```
156
182
 
157
183
  or use model associations with an alias:
158
184
 
159
- # Renders all the 'posts' association
160
- # from the model into a node called 'foobar'
161
- child :posts => :foobar do
162
- attributes :id, :title
163
- end
185
+ ```ruby
186
+ # Renders all the 'posts' association
187
+ # from the model into a node called 'foobar'
188
+ child :posts => :foobar do
189
+ attributes :id, :title
190
+ end
191
+ ```
164
192
 
165
193
  ### Gluing Attributes ###
166
194
 
167
195
  You can also append child attributes back to the root node:
168
196
 
169
- # Appends post_id and post_name to parent json object
170
- glue @post do
171
- attributes :id => :post_id, :name => :post_name
172
- end
197
+ ```ruby
198
+ # Appends post_id and post_name to parent json object
199
+ glue @post do
200
+ attributes :id => :post_id, :name => :post_name
201
+ end
202
+ ```
173
203
 
174
204
  Use glue to add additional attributes to the parent object.
175
205
 
@@ -177,17 +207,21 @@ Use glue to add additional attributes to the parent object.
177
207
 
178
208
  This will generate a json response based on the result of the code block:
179
209
 
180
- # app/views/users/show.json.rabl
181
- code :full_name do |u|
182
- u.first_name + " " + u.last_name
183
- end
210
+ ```ruby
211
+ # app/views/users/show.json.rabl
212
+ code :full_name do |u|
213
+ u.first_name + " " + u.last_name
214
+ end
215
+ ```
184
216
 
185
217
  or a custom node that exists only if a condition is true:
186
218
 
187
- # m is the object being rendered, also supports :unless
188
- code(:foo, :if => lambda { |m| m.has_foo? }) do |m|
189
- m.foo
190
- end
219
+ ```ruby
220
+ # m is the object being rendered, also supports :unless
221
+ code(:foo, :if => lambda { |m| m.has_foo? }) do |m|
222
+ m.foo
223
+ end
224
+ ```
191
225
 
192
226
  You can use custom "code" nodes to create flexible representations of a value utilizing all the data from the model.
193
227
 
@@ -195,15 +229,19 @@ You can use custom "code" nodes to create flexible representations of a value ut
195
229
 
196
230
  Often you need to access sub-objects in order to construct your own custom nodes for more complex associations. You can get access to the rabl representation of another object with:
197
231
 
198
- code :location do
199
- { :city => @city, :address => partial("web/users/address", :object => @address) }
200
- end
232
+ ```ruby
233
+ code :location do
234
+ { :city => @city, :address => partial("web/users/address", :object => @address) }
235
+ end
236
+ ```
201
237
 
202
238
  or an object associated to the parent model:
203
239
 
204
- code :location do |m|
205
- { :city => m.city, :address => partial("web/users/address", :object => m.address) }
206
- end
240
+ ```ruby
241
+ code :location do |m|
242
+ { :city => m.city, :address => partial("web/users/address", :object => m.address) }
243
+ end
244
+ ```
207
245
 
208
246
  You can use this method to construct arbitrarily complex nodes for your APIs.
209
247
 
@@ -213,19 +251,23 @@ Another common issue of many template builders is unnecessary code redundancy. T
213
251
 
214
252
  RABL has the ability to extend other "base" rabl templates and additional attributes:
215
253
 
216
- # app/views/users/advanced.json.rabl
217
- extends "users/base" # another RABL template in "app/views/users/base.json.rabl"
254
+ ```ruby
255
+ # app/views/users/advanced.json.rabl
256
+ extends "users/base" # another RABL template in "app/views/users/base.json.rabl"
218
257
 
219
- code :can_drink do |m|
220
- m.age > 21
221
- end
258
+ code :can_drink do |m|
259
+ m.age > 21
260
+ end
261
+ ```
222
262
 
223
263
  You can also extend other rabl templates while constructing child nodes to reduce duplication:
224
264
 
225
- # app/views/users/show.json.rabl
226
- child @address do
227
- extends "address/item"
228
- end
265
+ ```ruby
266
+ # app/views/users/show.json.rabl
267
+ child @address do
268
+ extends "address/item"
269
+ end
270
+ ```
229
271
 
230
272
  Using partials and inheritance can significantly reduce code duplication in your templates.
231
273
 
@@ -234,20 +276,38 @@ Using partials and inheritance can significantly reduce code duplication in your
234
276
  In APIs, you can often need to construct 2nd or 3rd level nodes. Let's suppose we have a 'quiz' model that has many 'questions'
235
277
  and then each question has many 'answers'. We can display this hierarchy in RABL quite easily:
236
278
 
237
- # app/views/quizzes/show.json.rabl
238
- object @quiz
239
- attribute :title
240
- child :questions do
241
- attribute :caption
242
- child :answers do
243
- # Use inheritance to reduce duplication
244
- extends "answers/item"
245
- end
246
- end
279
+ ```ruby
280
+ # app/views/quizzes/show.json.rabl
281
+ object @quiz
282
+ attribute :title
283
+ child :questions do
284
+ attribute :caption
285
+ child :answers do
286
+ # Use inheritance to reduce duplication
287
+ extends "answers/item"
288
+ end
289
+ end
290
+ ```
247
291
 
248
292
  This will display the quiz object with nested questions and answers as you would expect with a quiz node, and embedded questions and answers.
249
293
  Note that RABL can be nested arbitrarily deep within child nodes to allow for these representations to be defined.
250
294
 
295
+ ## Template Scope ##
296
+
297
+ In RABL, you have access to everything you need to build an API response. Each RABL template has full access to the controllers
298
+ instance variables as well as all view helpers and routing urls.
299
+
300
+ ```ruby
301
+ # app/some/template.rabl
302
+ object @post
303
+ # Access instance variables
304
+ child(@user => :user) { ... }
305
+ # or Rails helpers
306
+ code(:formatted_body) { |post| simple_format(post.body) }
307
+ ```
308
+
309
+ There should be no problem fetching the appropriate data to construct a response.
310
+
251
311
  ## Issues ##
252
312
 
253
313
  Check out the [Issues](https://github.com/nesquena/rabl/issues) tab for a full list:
data/lib/rabl/engine.rb CHANGED
@@ -133,6 +133,9 @@ module Rabl
133
133
  # default_format => "xml"
134
134
  def default_format
135
135
  format = self.request_params.has_key?(:format) ? @_scope.params[:format] : nil
136
+ if request = @_scope.respond_to?(:request) && @_scope.request
137
+ format ||= request.format.to_sym.to_s if request.respond_to?(:format)
138
+ end
136
139
  format || "json"
137
140
  end
138
141
 
@@ -148,5 +151,15 @@ module Rabl
148
151
  use_callback = Rabl.configuration.enable_json_callbacks && request_params[:callback].present?
149
152
  use_callback ? "#{request_params[:callback]}(#{json_output})" : json_output
150
153
  end
154
+
155
+ # Augments respond to supporting scope methods
156
+ def respond_to?(name, include_private=false)
157
+ @_scope.respond_to?(name, include_private) ? true : super
158
+ end
159
+
160
+ # Supports calling helpers defined for the template scope using method_missing hook
161
+ def method_missing(name, *args, &block)
162
+ @_scope.respond_to?(name) ? @_scope.send(name, *args, &block) : super
163
+ end
151
164
  end
152
165
  end
data/lib/rabl/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Rabl
2
- VERSION = "0.2.1"
2
+ VERSION = "0.2.5"
3
3
  end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: rabl
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.2.1
5
+ version: 0.2.5
6
6
  platform: ruby
7
7
  authors:
8
8
  - Nathan Esquenazi
@@ -10,8 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-05-16 00:00:00 -07:00
14
- default_executable:
13
+ date: 2011-05-19 00:00:00 Z
15
14
  dependencies:
16
15
  - !ruby/object:Gem::Dependency
17
16
  name: riot
@@ -90,7 +89,6 @@ files:
90
89
  - test/models/user.rb
91
90
  - test/template_test.rb
92
91
  - test/teststrap.rb
93
- has_rdoc: true
94
92
  homepage: https://github.com/nesquena/rabl
95
93
  licenses: []
96
94
 
@@ -114,7 +112,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
114
112
  requirements: []
115
113
 
116
114
  rubyforge_project: rabl
117
- rubygems_version: 1.6.2
115
+ rubygems_version: 1.7.2
118
116
  signing_key:
119
117
  specification_version: 3
120
118
  summary: General ruby templating for json or xml