rabl 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,16 +1,17 @@
1
1
  # RABL #
2
2
 
3
- RABL is a ruby templating system for Rails that takes a different approach for generating JSON and other formats. Rather than using the ActiveRecord 'to_json', I generally find myself wanting to use a more expressive and flexible system for generating my Public APIs. This is especially true when I the json doesn't match to the exact schema defined in the database.
3
+ RABL is a ruby templating system for Rails and [Padrino](http://padrinorb.com) that takes a new approach to generating JSON and other formats. Rather than using the ActiveRecord 'to_json', I generally find myself wanting a more expressive and powerful system for generating my APIs. This is especially important when the json representation is complex or doesn't match the exact schema defined in the database itself.
4
4
 
5
5
  There were a few things in particular I wanted to do easily:
6
6
 
7
- * Create arbitrary nodes named based on combining data in the object
8
- * Include nodes only if a condition is met
9
- * Pass arguments to methods and store the result as a node
10
- * Include partial templates to reduce code duplication
11
- * Easily rename attributes from their name in the model
7
+ * Create arbitrary nodes named based on combining data in an object
8
+ * Include nodes only if a certain condition is met
9
+ * Pass arguments to methods and store the result as a child node
10
+ * Partial templates and inheritance to reduce code duplication
11
+ * Easily renaming attributes from their name in the model
12
+ * Simple way to append attributes from a child into the parent
12
13
 
13
- This general templating system solves all of those problems.
14
+ The list goes on. Anyone who has used the 'to_json' approach used in ActiveRecord for generating a json response has felt the pain of the extremely restrictive system. RABL is a general templating system created to solve all of those problems. When I created RABL, I wanted a simple, expressive DRY ruby DSL for defining JSON responses for my APIs.
14
15
 
15
16
  ## Installation ##
16
17
 
@@ -25,17 +26,17 @@ or add to your Gemfile:
25
26
 
26
27
  and run `bundle install` to install the dependency.
27
28
 
28
- If you are using Rails 2.X or Padrino, RABL works out of the box. With Sinatra, or any other tilt-based framework, simply register:
29
+ If you are using Rails 2.X or Padrino, RABL works without configuration. With Sinatra, or any other tilt-based framework, simply register:
29
30
 
30
31
  Rabl.register!
31
32
 
32
- and RABL will be initialized.
33
+ and RABL will be initialized and ready for use.
33
34
 
34
35
  ## Usage ##
35
36
 
36
37
  ### Object Assignment ###
37
38
 
38
- To declare the data object to use in the template:
39
+ To declare the data object for use in the template:
39
40
 
40
41
  # app/views/users/show.json.rabl
41
42
  object @user
@@ -48,40 +49,43 @@ and this will be used as the default data object for the rendering.
48
49
 
49
50
  ### Attributes ###
50
51
 
51
- Basic usage of the templater:
52
+ Basic usage of the templater to define a few simple attributes for the response:
52
53
 
53
54
  # app/views/users/show.json.rabl
54
55
  attributes :id, :foo, :bar
55
56
 
56
- or with aliased attributes:
57
+ or use with aliased attributes:
57
58
 
58
59
  # Take the value of model attribute `foo` and name the node `bar`
59
60
  # { bar : 5 }
60
61
  attribute :foo => :bar
61
62
 
62
- or multiple aliased attributes:
63
+ or even multiple aliased attributes:
63
64
 
64
65
  # { baz : <bar value>, animal : <dog value> }
65
66
  attributes :bar => :baz, :dog => :animal
66
67
 
67
68
  ### Child Nodes ###
68
69
 
69
- You can also add children nodes from an arbitrary object:
70
+ You can also add child nodes from an arbitrary source:
70
71
 
71
72
  child @posts => :foobar do
72
73
  attributes :id, :title
73
74
  end
74
75
 
75
- or use existing model associations:
76
+ or simply use existing model associations:
76
77
 
78
+ # Renders all the 'posts' association
79
+ # from the model into a node called 'foobar'
77
80
  child :posts => :foobar do
78
81
  attributes :id, :title
79
82
  end
80
83
 
81
- ### Glued Attributes ###
84
+ ### Gluing Attributes ###
82
85
 
83
- You can also append attributes to the root node:
86
+ You can also append child attributes back to the root node:
84
87
 
88
+ # Appends post_id and post_name to parent json object
85
89
  glue @post do
86
90
  attributes :id => :post_id, :name => :post_name
87
91
  end
@@ -90,18 +94,18 @@ Use glue to add additional attributes to the parent object.
90
94
 
91
95
  ### Custom Nodes ###
92
96
 
93
- This will generate a json response with the attributes specified. You can also include arbitrary code:
97
+ This will generate a json response based on the result of the code block:
94
98
 
95
99
  # app/views/users/show.json.rabl
96
100
  code :full_name do |u|
97
101
  u.first_name + " " + u.last_name
98
102
  end
99
103
 
100
- You can use custom "code" nodes to create flexible representations of a value utilizing data from the model.
104
+ You can use custom "code" nodes to create flexible representations of a value utilizing all the data from the model.
101
105
 
102
106
  ### Partials ###
103
107
 
104
- 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 hash representation of another object:
108
+ 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:
105
109
 
106
110
  code :location do
107
111
  { :city => @city, :address => partial("web/users/address", :object => @address) }
@@ -113,11 +117,11 @@ or an object associated to the parent model:
113
117
  { :city => m.city, :address => partial("web/users/address", :object => m.address) }
114
118
  end
115
119
 
116
- You can use these to construct arbitrarily complex nodes for APIs.
120
+ You can use this method to construct arbitrarily complex nodes for your APIs.
117
121
 
118
122
  ### Inheritance ###
119
123
 
120
- Another common limitation of many json builders is code redundancy. Typically every representation of an object across endpoints share common attributes or nodes. The nodes for a 'post' object are probably the same or similar in most references throughout the various endpoints.
124
+ Another common issue of many template builders is unnecessary code redundancy. Typically many representations of an object across multiple endpoints share common attributes or nodes. The nodes for a 'post' object are probably the same or similar in most references throughout the various endpoints.
121
125
 
122
126
  RABL has the ability to extend other "base" rabl templates and additional attributes:
123
127
 
@@ -128,7 +132,7 @@ RABL has the ability to extend other "base" rabl templates and additional attrib
128
132
  m.age > 21
129
133
  end
130
134
 
131
- You can also extend other rabl templates in constructing nodes to reduce duplication:
135
+ You can also extend other rabl templates while constructing child nodes to reduce duplication:
132
136
 
133
137
  # app/views/users/show.json.rabl
134
138
  child @address do
@@ -139,4 +143,20 @@ Using partials and inheritance can significantly reduce code duplication in your
139
143
 
140
144
  ## Issues ##
141
145
 
142
- * I am sloppy and once again failed to unit test this. Don't use it in production until I do obviously.
146
+ * I am sloppy and once again failed to unit test this. Don't use it in production until I do obviously.
147
+ * No support for Rails 3
148
+
149
+ ## Authors and Contributors ##
150
+
151
+ * [Nathan Esquenazi](https://github.com/nesquena) - Creator of the project
152
+ * [Arthur Chiu](https://github.com/achiu) - Core Maintainer, Riot Testing Guru
153
+
154
+ ## Inspirations ##
155
+
156
+ There are a few excellent libraries that helped inspire RABL and they are listed below:
157
+
158
+ * [Tequila](https://github.com/inem/tequila)
159
+ * [JSON Builder](https://github.com/dewski/json_builder)
160
+ * [Argonaut](https://github.com/jbr/argonaut)
161
+
162
+ Thanks again for all of these great projects.
data/TODO ADDED
@@ -0,0 +1,7 @@
1
+ = TODO
2
+
3
+ - Test the code, child and glue options
4
+ - Add support for child collection with "root" for each
5
+ - Child should support collections of children
6
+ - Child should support symbol associations inside object
7
+ - Add support for Rails 3
@@ -0,0 +1,8 @@
1
+ # See 'inherited' for an example of how to extend this template
2
+
3
+ # Include these three attributes
4
+ attributes :title, :kind, :id
5
+
6
+ child @users do
7
+ attributes :full_name, :first_name
8
+ end
@@ -0,0 +1,42 @@
1
+ # Use the @media object set in route
2
+ object @media
3
+
4
+ # Include these three attributes
5
+ attributes :title, :kind, :id
6
+ # Rename 'studio' to be the 'company' node
7
+ attributes :studio => :company
8
+
9
+ # Arbitrary code blocks can be defined
10
+ # Creates a 'release_year' node
11
+ code :release_year do |m|
12
+ date = m.release_date || m.series_start
13
+ date.try(:year)
14
+ end
15
+
16
+ # Creates a node 'users' with an array of the nested users for media
17
+ # Block is the same rabl syntax for the sub object
18
+ child @users do
19
+ attributes :full_name, :first_name
20
+ end
21
+
22
+ # Uses the associations of the parent media object
23
+ # Rename 'users' association to 'people' node
24
+ child :users => :people do
25
+ attributes :full_name, :first_name
26
+ end
27
+
28
+ # Creates the "actor" association as a 'user' node
29
+ # Use the information from another rabl template to describe the representation
30
+ child :actor => :user do
31
+ extends "users/simple"
32
+ end
33
+
34
+ # Append attributes to the root node with prefixed names
35
+ glue @users.first do
36
+ attributes :full_name => :user_full_name, :first_name => :user_first_name
37
+ end
38
+
39
+ # Render an arbitrary hash with a partial rabl json as one of the keys
40
+ code :topics do |m|
41
+ { :fake => partial("media/user", :object => @users.first), :raw => @users.first }
42
+ end
@@ -0,0 +1,11 @@
1
+ # Extends base.json.rabl and adds additional nodes
2
+
3
+ extends("base")
4
+
5
+ code :release_year do |m|
6
+ m.release_date.year
7
+ end
8
+
9
+ code :poster_image_url do |m|
10
+ m.poster_image_url(:large)
11
+ end
@@ -77,7 +77,7 @@ module Rabl
77
77
  # Extends an existing rabl template with additional attributes in the block
78
78
  # extends("users/show") { attribute :full_name }
79
79
  def extends(file, options={}, &block)
80
- options = options.merge!(:object => @_object)
80
+ options = options.merge(:object => @_object)
81
81
  result = @options[:engine].partial(file, options, &block)
82
82
  @_result.merge!(result)
83
83
  end
@@ -1,7 +1,7 @@
1
1
  module Rabl
2
2
  class Engine
3
3
  # Constructs a new ejs engine based on given vars, handler and declarations
4
- # Rabl::Engine.new("...source...", { :format => "xml" })
4
+ # Rabl::Engine.new("...source...", { :format => "xml", :root => true, :view_path => "/path/to/views" })
5
5
  def initialize(source, options={})
6
6
  @_source = source
7
7
  @_options = options.reverse_merge(:format => "json")
@@ -13,7 +13,7 @@ module Rabl
13
13
  @_locals = locals
14
14
  @_scope = scope
15
15
  @_options = @_options.merge(:scope => @_scope, :locals => @_locals, :engine => self)
16
- self.copy_instance_variables_from(@_scope, [:@assigns, :@helpers]);
16
+ self.copy_instance_variables_from(@_scope, [:@assigns, :@helpers])
17
17
  @_object = locals[:object] || self.default_object
18
18
  instance_eval(@_source) if @_source.present?
19
19
  instance_eval(&block) if block_given?
@@ -118,7 +118,7 @@ module Rabl
118
118
  def fetch_source(file)
119
119
  root_path = Rails.root if defined?(Rails)
120
120
  root_path = Padrino.root if defined?(Padrino)
121
- view_path = File.join(root_path, "app/views/")
121
+ view_path = @_options[:view_path] || File.join(root_path, "app/views/")
122
122
  file_path = Dir[File.join(view_path, file + "*.rabl")].first
123
123
  File.read(file_path) if file_path
124
124
  end
@@ -1,3 +1,3 @@
1
1
  module Rabl
2
- VERSION = "0.0.5"
2
+ VERSION = "0.0.6"
3
3
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rabl
3
3
  version: !ruby/object:Gem::Version
4
- hash: 21
5
- prerelease:
4
+ hash: 19
5
+ prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 5
10
- version: 0.0.5
9
+ - 6
10
+ version: 0.0.6
11
11
  platform: ruby
12
12
  authors:
13
13
  - Nathan Esquenazi
@@ -15,7 +15,8 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-04-12 00:00:00 Z
18
+ date: 2011-04-12 00:00:00 -07:00
19
+ default_executable:
19
20
  dependencies:
20
21
  - !ruby/object:Gem::Dependency
21
22
  name: riot
@@ -63,6 +64,10 @@ files:
63
64
  - Gemfile
64
65
  - README.md
65
66
  - Rakefile
67
+ - TODO
68
+ - examples/base.json.rabl
69
+ - examples/demo.json.rabl
70
+ - examples/inherited.json.rabl
66
71
  - lib/rabl.rb
67
72
  - lib/rabl/builder.rb
68
73
  - lib/rabl/engine.rb
@@ -75,6 +80,7 @@ files:
75
80
  - test/engine_test.rb
76
81
  - test/template_test.rb
77
82
  - test/teststrap.rb
83
+ has_rdoc: true
78
84
  homepage: https://github.com/nesquena/rabl
79
85
  licenses: []
80
86
 
@@ -104,7 +110,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
104
110
  requirements: []
105
111
 
106
112
  rubyforge_project: rabl
107
- rubygems_version: 1.7.2
113
+ rubygems_version: 1.3.7
108
114
  signing_key:
109
115
  specification_version: 3
110
116
  summary: General ruby templating for json or xml