rabl 0.5.1 → 0.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +24 -13
- data/lib/rabl/builder.rb +2 -2
- data/lib/rabl/engine.rb +12 -1
- data/lib/rabl/version.rb +1 -1
- data/test/engine_test.rb +14 -0
- metadata +3 -3
data/README.md
CHANGED
@@ -38,7 +38,8 @@ With Sinatra, or any other tilt-based framework, simply register:
|
|
38
38
|
|
39
39
|
Rabl.register!
|
40
40
|
|
41
|
-
and RABL will be initialized and ready for use.
|
41
|
+
and RABL will be initialized and ready for use. For usage with Sinatra, check out
|
42
|
+
the [Sinatra Usage](https://github.com/nesquena/rabl/wiki/Setup-for-Sinatra) guide.
|
42
43
|
|
43
44
|
## Overview ##
|
44
45
|
|
@@ -322,6 +323,22 @@ end
|
|
322
323
|
|
323
324
|
Using partials and inheritance can significantly reduce code duplication in your templates.
|
324
325
|
|
326
|
+
## Template Scope ##
|
327
|
+
|
328
|
+
In RABL, you have access to everything you need to build an API response. Each RABL template has full access to the controllers
|
329
|
+
instance variables as well as all view helpers and routing urls.
|
330
|
+
|
331
|
+
```ruby
|
332
|
+
# app/some/template.rabl
|
333
|
+
object @post
|
334
|
+
# Access instance variables
|
335
|
+
child(@user => :user) { ... }
|
336
|
+
# or Rails helpers
|
337
|
+
code(:formatted_body) { |post| simple_format(post.body) }
|
338
|
+
```
|
339
|
+
|
340
|
+
There should be no problem fetching the appropriate data to construct a response.
|
341
|
+
|
325
342
|
### Deep Nesting ###
|
326
343
|
|
327
344
|
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'
|
@@ -343,21 +360,15 @@ end
|
|
343
360
|
This will display the quiz object with nested questions and answers as you would expect with a quiz node, and embedded questions and answers.
|
344
361
|
Note that RABL can be nested arbitrarily deep within child nodes to allow for these representations to be defined.
|
345
362
|
|
346
|
-
|
363
|
+
### Advanced Usage ###
|
347
364
|
|
348
|
-
|
349
|
-
|
365
|
+
* Rendering JSON for a tree structure using RABL: https://github.com/nesquena/rabl/issues/70
|
366
|
+
* Layouts (erb, haml and rabl) in RABL: https://github.com/nesquena/rabl/wiki/Using-Layouts
|
367
|
+
* Backbone or [Ember.js](http://www.emberjs.com) Integration: https://github.com/nesquena/rabl/wiki/Backbone-Integration
|
350
368
|
|
351
|
-
|
352
|
-
# app/some/template.rabl
|
353
|
-
object @post
|
354
|
-
# Access instance variables
|
355
|
-
child(@user => :user) { ... }
|
356
|
-
# or Rails helpers
|
357
|
-
code(:formatted_body) { |post| simple_format(post.body) }
|
358
|
-
```
|
369
|
+
### Troubleshooting ###
|
359
370
|
|
360
|
-
|
371
|
+
* Redundant calls for a collection: https://github.com/nesquena/rabl/issues/142#issuecomment-2969107
|
361
372
|
|
362
373
|
## Issues ##
|
363
374
|
|
data/lib/rabl/builder.rb
CHANGED
@@ -76,12 +76,12 @@ module Rabl
|
|
76
76
|
# child(@user => :person) { ... }
|
77
77
|
# child(@users => :people) { ... }
|
78
78
|
def child(data, options={}, &block)
|
79
|
-
return false unless data.present?
|
79
|
+
return false unless data.present? && resolve_condition(options)
|
80
80
|
name, object = data_name(data), data_object(data)
|
81
81
|
include_root = is_collection?(object) && @options[:child_root] # child @users
|
82
82
|
engine_options = @options.slice(:child_root).merge(:root => include_root)
|
83
83
|
object = { object => name } if data.respond_to?(:each_pair) && object # child :users => :people
|
84
|
-
@_result[name] = self.object_to_hash(object, engine_options, &block)
|
84
|
+
@_result[name] = self.object_to_hash(object, engine_options, &block)
|
85
85
|
end
|
86
86
|
|
87
87
|
# Glues data from a child node to the json_output
|
data/lib/rabl/engine.rb
CHANGED
@@ -7,6 +7,7 @@ module Rabl
|
|
7
7
|
def initialize(source, options={})
|
8
8
|
@_source = source
|
9
9
|
@_options = options
|
10
|
+
@_compiled = false
|
10
11
|
end
|
11
12
|
|
12
13
|
# Renders the representation based on source, object, scope and locals
|
@@ -14,6 +15,7 @@ module Rabl
|
|
14
15
|
def render(scope, locals, &block)
|
15
16
|
@_locals, @_scope = locals, scope
|
16
17
|
self.copy_instance_variables_from(@_scope, [:@assigns, :@helpers])
|
18
|
+
clear_compile_state
|
17
19
|
@_options[:scope] = @_scope
|
18
20
|
@_options[:format] ||= self.request_format
|
19
21
|
@_data = locals[:object] || self.default_object
|
@@ -29,7 +31,7 @@ module Rabl
|
|
29
31
|
# Returns a hash representation of the data object
|
30
32
|
# to_hash(:root => true, :child_root => true)
|
31
33
|
def to_hash(options={})
|
32
|
-
options =
|
34
|
+
options = @_options.merge(options)
|
33
35
|
data = data_object(@_data)
|
34
36
|
if is_object?(data) || !data # object @user
|
35
37
|
Rabl::Builder.new(@_data, options).to_hash(options)
|
@@ -187,5 +189,14 @@ module Rabl
|
|
187
189
|
vars = object.instance_variables.map(&:to_s) - exclude.map(&:to_s)
|
188
190
|
vars.each { |name| instance_variable_set(name, object.instance_variable_get(name)) }
|
189
191
|
end
|
192
|
+
|
193
|
+
private
|
194
|
+
def clear_compile_state
|
195
|
+
@_options.delete(:extends)
|
196
|
+
@_options.delete(:attributes)
|
197
|
+
@_options.delete(:code)
|
198
|
+
@_options.delete(:child)
|
199
|
+
@_options.delete(:glue)
|
200
|
+
end
|
190
201
|
end
|
191
202
|
end
|
data/lib/rabl/version.rb
CHANGED
data/test/engine_test.rb
CHANGED
@@ -350,6 +350,20 @@ context "Rabl::Engine" do
|
|
350
350
|
template.render(scope).split('').sort
|
351
351
|
|
352
352
|
end.equals "{\"name\":\"leo\",\"person\":{\"city\":\"LA\"}}".split('').sort
|
353
|
+
|
354
|
+
|
355
|
+
asserts "that it can be passed conditionals" do
|
356
|
+
template = rabl %{
|
357
|
+
object @user
|
358
|
+
attribute :name
|
359
|
+
child({:children => :children}, {:if => lambda { |user| user.respond_to?('children') }}) { attribute :test }
|
360
|
+
}
|
361
|
+
scope = Object.new
|
362
|
+
scope.instance_variable_set :@user, User.new(:name => 'leo', :city => 'LA')
|
363
|
+
template.render(scope).split('').sort
|
364
|
+
|
365
|
+
end.equals "{\"name\":\"leo\"}".split('').sort
|
366
|
+
|
353
367
|
end
|
354
368
|
|
355
369
|
context "#glue" do
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: rabl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.5.
|
5
|
+
version: 0.5.3
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Nathan Esquenazi
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-
|
13
|
+
date: 2011-12-23 00:00:00 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: multi_json
|
@@ -286,7 +286,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
286
286
|
requirements: []
|
287
287
|
|
288
288
|
rubyforge_project: rabl
|
289
|
-
rubygems_version: 1.8.
|
289
|
+
rubygems_version: 1.8.12
|
290
290
|
signing_key:
|
291
291
|
specification_version: 3
|
292
292
|
summary: General ruby templating for json or xml
|