rabl 0.1.6 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -34,6 +34,60 @@ With Sinatra, or any other tilt-based framework, simply register:
34
34
 
35
35
  and RABL will be initialized and ready for use.
36
36
 
37
+ ## Overview ##
38
+
39
+ The quick idea here is that you can use RABL to generate JSON and XML API based on any arbitrary data source. With RABL, the data is expected to come
40
+ primarily from a model (ORM-agnostic) and the representation of the API output is described in the view with a simple ruby DSL. This allows you to keep your data separate from the JSON or XML you wish to output.
41
+
42
+ Once you have installed RABL (explained above), you can construct a RABL view template and then render the template from your Sinatra, Padrino or Rails applications from the controller (or route) very easily. Using [Padrino](http://padrinorb.com) as an example, assuming you have a `Post` model filled with blog posts, you can render an API representation (both JSON and XML) by creating a route:
43
+
44
+ ```ruby
45
+ # app/app.rb
46
+ get "/posts", :provides => [:json, :xml] do
47
+ @user = current_user
48
+ @posts = Post.order("id DESC")
49
+ render "posts/index"
50
+ end
51
+ ```
52
+
53
+ Then we can create the following RABL template to express the API output of `@posts`:
54
+
55
+ ```ruby
56
+ # app/views/posts/index.rabl
57
+ collection @posts
58
+ attributes :id, :title, :subject
59
+ child(:user) { attributes :full_name }
60
+ node(:read) { |post| post.read_by?(@user) }
61
+ ```
62
+
63
+ Which would output the following JSON or XML when visiting `http://localhost:3000/posts.json`
64
+
65
+ ```json
66
+ [{ post :
67
+ {
68
+ id : 5, title: "...", subject: "...",
69
+ user : { full_name : "..." },
70
+ read : true
71
+ }
72
+ }]
73
+ ```
74
+
75
+ That's the basic overview but there is a lot more (partials, inheritance, custom nodes, etc). Read the full details below of RABL below.
76
+
77
+ ## Configuration ##
78
+
79
+ 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
+
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
88
+
89
+ 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
+
37
91
  ## Usage ##
38
92
 
39
93
  ### Object Assignment ###
@@ -198,7 +252,6 @@ Note that RABL can be nested arbitrarily deep within child nodes to allow for th
198
252
 
199
253
  Check out the [Issues](https://github.com/nesquena/rabl/issues) tab for a full list:
200
254
 
201
- * No configuration options yet for how to create the json (root nodes) :(
202
255
  * Better Tilt template support (precompiling templates)
203
256
  * Benchmarks and performance optimizations
204
257
 
data/lib/rabl.rb CHANGED
@@ -2,11 +2,29 @@ require 'rabl/version'
2
2
  require 'rabl/helpers'
3
3
  require 'rabl/engine'
4
4
  require 'rabl/builder'
5
+ require 'rabl/configuration'
5
6
 
6
7
  # Rabl.register!
7
8
  module Rabl
8
- def self.register!
9
- require 'rabl/template'
9
+ class << self
10
+ def register!
11
+ require 'rabl/template'
12
+ end
13
+
14
+ # Yields a RABL configuration block
15
+ # Rabl.configure do |config|
16
+ # config.include_json_root = false
17
+ # config.enable_json_callbacks = true
18
+ # end
19
+ def configure(&block)
20
+ yield(self.configuration)
21
+ end
22
+
23
+ # Returns the configuration options set for RABL
24
+ # Rabl.configuration.include_json_root => false
25
+ def configuration
26
+ @_configuration ||= Configuration.new
27
+ end
10
28
  end
11
29
  end
12
30
 
@@ -0,0 +1,21 @@
1
+ module Rabl
2
+ # Rabl.host
3
+ class Configuration
4
+ attr_accessor :include_json_root
5
+ attr_accessor :include_xml_root
6
+ attr_accessor :enable_json_callbacks
7
+
8
+ def initialize
9
+ @include_json_root = true
10
+ @include_xml_root = false
11
+ @enable_json_callbacks = false
12
+ end
13
+
14
+ # Allows config options to be read like a hash
15
+ #
16
+ # @param [Symbol] option Key for a given attribute
17
+ def [](option)
18
+ send(option)
19
+ end
20
+ end
21
+ end
data/lib/rabl/engine.rb CHANGED
@@ -38,15 +38,17 @@ module Rabl
38
38
  # Returns a json representation of the data object
39
39
  # to_json(:root => true)
40
40
  def to_json(options={})
41
- options = options.reverse_merge(:root => true, :child_root => true)
41
+ include_root = Rabl.configuration.include_json_root
42
+ options = options.reverse_merge(:root => include_root, :child_root => include_root)
42
43
  result = @_collection_name ? { @_collection_name => to_hash(options) } : to_hash(options)
43
- result.to_json
44
+ format_json(result.to_json)
44
45
  end
45
46
 
46
47
  # Returns an xml representation of the data object
47
48
  # to_xml(:root => true)
48
49
  def to_xml(options={})
49
- options = options.reverse_merge(:root => false, :child_root => false)
50
+ include_root = Rabl.configuration.include_xml_root
51
+ options = options.reverse_merge(:root => include_root, :child_root => include_root)
50
52
  to_hash(options).to_xml(:root => data_name(@_data))
51
53
  end
52
54
 
@@ -130,10 +132,21 @@ module Rabl
130
132
  # Returns a guess at the format in this scope
131
133
  # default_format => "xml"
132
134
  def default_format
133
- format = @_scope.respond_to?(:params) && @_scope.params.has_key?(:format) ?
134
- @_scope.params[:format] :
135
- nil
135
+ format = self.request_params.has_key?(:format) ? @_scope.params[:format] : nil
136
136
  format || "json"
137
137
  end
138
+
139
+ # Returns the request parameters if available in the scope
140
+ # request_params => { :foo => "bar" }
141
+ def request_params
142
+ @_scope.respond_to?(:params) ? @_scope.params : {}
143
+ end
144
+
145
+ # Returns json embraced with callback if appropriate or plain if not
146
+ # detect_jsonp({ foo : "bar" }) => "test({ foo : 'bar' })"
147
+ def format_json(json_output)
148
+ use_callback = Rabl.configuration.enable_json_callbacks && request_params[:callback].present?
149
+ use_callback ? "#{request_params[:callback]}(#{json_output})" : json_output
150
+ end
138
151
  end
139
152
  end
data/lib/rabl/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Rabl
2
- VERSION = "0.1.6"
2
+ VERSION = "0.2.0"
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.1.6
5
+ version: 0.2.0
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-04 00:00:00 -07:00
14
- default_executable:
13
+ date: 2011-05-12 00:00:00 Z
15
14
  dependencies:
16
15
  - !ruby/object:Gem::Dependency
17
16
  name: riot
@@ -78,6 +77,7 @@ files:
78
77
  - examples/inherited.json.rabl
79
78
  - lib/rabl.rb
80
79
  - lib/rabl/builder.rb
80
+ - lib/rabl/configuration.rb
81
81
  - lib/rabl/engine.rb
82
82
  - lib/rabl/helpers.rb
83
83
  - lib/rabl/template.rb
@@ -89,7 +89,6 @@ files:
89
89
  - test/models/user.rb
90
90
  - test/template_test.rb
91
91
  - test/teststrap.rb
92
- has_rdoc: true
93
92
  homepage: https://github.com/nesquena/rabl
94
93
  licenses: []
95
94
 
@@ -113,7 +112,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
113
112
  requirements: []
114
113
 
115
114
  rubyforge_project: rabl
116
- rubygems_version: 1.6.2
115
+ rubygems_version: 1.7.2
117
116
  signing_key:
118
117
  specification_version: 3
119
118
  summary: General ruby templating for json or xml