rabl 0.0.9 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,21 +1,21 @@
1
1
  # RABL #
2
2
 
3
- RABL (Ruby API Builder Language) 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.
3
+ RABL (Ruby API Builder Language) is a Rails and [Padrino](http://padrinorb.com) ruby templating system for generating JSON and XML. When using the ActiveRecord 'to_json' method, I tend to quickly find myself wanting a more expressive and powerful system for generating APIs. This is especially frustrating when the json representation is complex or doesn't match the exact schema defined in the database itself.
4
4
 
5
- There were a few things in particular I wanted to do easily:
5
+ I wanted a simple, and flexible system for generating APIs. In particular, I wanted to easily:
6
6
 
7
7
  * Create arbitrary nodes named based on combining data in an object
8
- * Include nodes only if a certain condition is met
9
8
  * Pass arguments to methods and store the result as a child node
10
9
  * Partial templates and inheritance to reduce code duplication
11
10
  * Easily renaming attributes from their name in the model
12
11
  * Simple way to append attributes from a child into the parent
12
+ * Include nodes only if a certain condition is met
13
13
 
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
+ Anyone who has tried the 'to_json' method used in ActiveRecord for generating a json response has felt the pain of this restrictive approach. RABL is a general templating system created to solve all of those problems.
15
15
 
16
16
  ## Installation ##
17
17
 
18
- Install as a gem:
18
+ Install RABL as a gem:
19
19
 
20
20
  gem install rabl
21
21
 
@@ -26,7 +26,9 @@ or add to your Gemfile:
26
26
 
27
27
  and run `bundle install` to install the dependency.
28
28
 
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
+ If you are using **Rails 2.X, Rails 3 or Padrino**, RABL works without configuration.
30
+
31
+ With Sinatra, or any other tilt-based framework, simply register:
30
32
 
31
33
  Rabl.register!
32
34
 
@@ -153,11 +155,9 @@ Using partials and inheritance can significantly reduce code duplication in your
153
155
  Check out the [Issues](https://github.com/nesquena/rabl/issues) tab for a full list:
154
156
 
155
157
  * I am sloppy and failed to unit test this as I cobbled it together. Don't use it in production until I do, for now this is a fun experiment.
156
- * No support for Rails 3 yet, need a Railstie
157
158
  * No configuration options yet for how to create the json (root nodes) :(
158
159
  * Better Tilt template support (precompiling templates)
159
160
  * Benchmarks and performance optimizations
160
- * XML Support and potentially others
161
161
 
162
162
  ## Authors and Contributors ##
163
163
 
@@ -5,8 +5,7 @@ require 'rabl/builder'
5
5
  # Rabl.register!
6
6
  module Rabl
7
7
  def self.register!
8
- require 'rabl/template' if defined?(Rails)
9
- require 'rabl/register'
8
+ require 'rabl/template'
10
9
  end
11
10
  end
12
11
 
@@ -14,6 +13,8 @@ end
14
13
  if defined?(Padrino)
15
14
  require 'padrino-core'
16
15
  Padrino.after_load { Rabl.register! }
17
- else
16
+ elsif defined?(Rails) && Rails.version =~ /^2/
17
+ Rabl.register!
18
+ elsif defined?(Rails) && Rails.version =~ /^3/
18
19
  Rabl.register!
19
20
  end
@@ -31,7 +31,7 @@ module Rabl
31
31
  extends(settings[:file], settings[:options], &settings[:block])
32
32
  end if @options.has_key?(:extends)
33
33
 
34
- @_root_name ||= @_object.class.model_name.element
34
+ @_root_name ||= data_name(@_object)
35
35
  (@options[:root] || options[:root]) ? { @_root_name => @_result } : @_result
36
36
  end
37
37
 
@@ -106,8 +106,7 @@ module Rabl
106
106
  # data_name(@users) => :user
107
107
  def data_name(data)
108
108
  return data.values.first if data.is_a?(Hash)
109
- return data.first.class.model_name.element.pluralize if data.respond_to?(:first) && data.first.respond_to?(:valid?)
110
- data.class.model_name.element
109
+ @options[:engine].model_name(data)
111
110
  end
112
111
 
113
112
  # resolve_condition(:if => true) => true
@@ -17,7 +17,7 @@ module Rabl
17
17
  @_object = locals[:object] || self.default_object
18
18
  instance_eval(@_source) if @_source.present?
19
19
  instance_eval(&block) if block_given?
20
- self.send("to_" + @_options[:format])
20
+ self.send("to_" + @_options[:format].to_s)
21
21
  end
22
22
 
23
23
  # Sets the object to be used as the data source for this template
@@ -93,11 +93,11 @@ module Rabl
93
93
  to_hash(options).to_json
94
94
  end
95
95
 
96
- # Returns a hash based representation of any data object given ejs template block
97
- # object_to_hash(@user) { attribute :full_name } => { ... }
98
- def object_to_hash(object, source=nil, &block)
99
- return object unless is_record?(object) || is_record?(object.respond_to?(:first) && object.first)
100
- self.class.new(source, :format => "hash", :root => false).render(@_scope, :object => object, &block)
96
+ # Returns a json representation of the data object
97
+ # to_xml(:root => true)
98
+ def to_xml(options={})
99
+ options = options.reverse_merge(:root => false)
100
+ to_hash(options).to_xml(:root => model_name(@_object))
101
101
  end
102
102
 
103
103
  # Includes a helper module for RABL
@@ -107,6 +107,24 @@ module Rabl
107
107
  end
108
108
  alias_method :helpers, :helper
109
109
 
110
+ # Returns a hash based representation of any data object given ejs template block
111
+ # object_to_hash(@user) { attribute :full_name } => { ... }
112
+ def object_to_hash(object, source=nil, &block)
113
+ return object unless is_record?(object) || object.respond_to?(:each)
114
+ self.class.new(source, :format => "hash", :root => false).render(@_scope, :object => object, &block)
115
+ end
116
+
117
+ # model_name(@user) => "user"
118
+ # model_name([@user]) => "user"
119
+ # model_name([]) => "array"
120
+ def model_name(data)
121
+ if data.respond_to?(:first) && data.first.respond_to?(:valid?)
122
+ model_name(data.first).pluralize
123
+ else # actual data object
124
+ data.class.respond_to?(:model_name) ? data.class.model_name.element : data.class.to_s.downcase
125
+ end
126
+ end
127
+
110
128
  protected
111
129
 
112
130
  # Returns a guess at the default object for this template
@@ -1,19 +1,64 @@
1
- # Rails Template
1
+ # TILT Template
2
+ if defined?(Tilt)
3
+ class RablTemplate < Tilt::Template
4
+ def initialize_engine
5
+ return if defined?(::Rabl)
6
+ require_template_library 'rabl'
7
+ end
8
+
9
+ def prepare
10
+ options = @options.merge(:format => "json")
11
+ @engine = ::Rabl::Engine.new(data, options)
12
+ end
13
+
14
+ def evaluate(scope, locals, &block)
15
+ @engine.render(scope, locals, &block)
16
+ end
17
+ end
18
+
19
+ Tilt.register 'rabl', RablTemplate
20
+ end
2
21
 
3
- require 'action_view/base'
4
- require 'action_view/template'
22
+ # Rails 2.X Template
23
+ if defined?(Rails) && Rails.version =~ /^2/
24
+ require 'action_view/base'
25
+ require 'action_view/template'
5
26
 
6
- module ActionView
7
- module TemplateHandlers
8
- class RablHandler < TemplateHandler
9
- include Compilable
27
+ module ActionView
28
+ module TemplateHandlers
29
+ class RablHandler < TemplateHandler
30
+ include Compilable
10
31
 
11
- def compile(template) %{
12
- ::Rabl::Engine.new(#{template.source.inspect}, { :format => #{template.format.inspect} }).
13
- render(self, assigns.merge(local_assigns))
14
- } end
32
+ def compile(template) %{
33
+ ::Rabl::Engine.new(#{template.source.inspect}, { :format => #{template.format.inspect} }).
34
+ render(self, assigns.merge(local_assigns))
35
+ } end
36
+ end
15
37
  end
16
38
  end
39
+
40
+ ActionView::Template.register_template_handler :rabl, ActionView::TemplateHandlers::RablHandler
17
41
  end
18
42
 
19
- ActionView::Template.register_template_handler :rabl, ActionView::TemplateHandlers::RablHandler
43
+ # Rails 3.X Template
44
+ if defined?(Rails) && Rails.version =~ /^3/
45
+ require 'action_view/base'
46
+ require 'action_view/template'
47
+
48
+ module ActionView
49
+ module Template::Handlers
50
+ class RablHandler < Template::Handler
51
+ include Compilable
52
+
53
+ self.default_format = Mime::JSON
54
+
55
+ def compile(template) %{
56
+ ::Rabl::Engine.new(#{template.source.inspect}, { :format => #{template.formats.first.inspect} }).
57
+ render(self, assigns.merge(local_assigns))
58
+ } end
59
+ end
60
+ end
61
+ end
62
+
63
+ ActionView::Template.register_template_handler :rabl, ActionView::TemplateHandlers::RablHandler
64
+ end
@@ -1,3 +1,3 @@
1
1
  module Rabl
2
- VERSION = "0.0.9"
2
+ VERSION = "0.1.0"
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: 13
4
+ hash: 27
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
+ - 1
8
9
  - 0
9
- - 9
10
- version: 0.0.9
10
+ version: 0.1.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Nathan Esquenazi
@@ -70,7 +70,6 @@ files:
70
70
  - lib/rabl.rb
71
71
  - lib/rabl/builder.rb
72
72
  - lib/rabl/engine.rb
73
- - lib/rabl/register.rb
74
73
  - lib/rabl/template.rb
75
74
  - lib/rabl/version.rb
76
75
  - rabl.gemspec
@@ -1,20 +0,0 @@
1
- ## TILT ##
2
- if defined?(Tilt)
3
- class RablTemplate < Tilt::Template
4
- def initialize_engine
5
- return if defined?(::Rabl)
6
- require_template_library 'rabl'
7
- end
8
-
9
- def prepare
10
- options = @options.merge(:format => "json")
11
- @engine = ::Rabl::Engine.new(data, options)
12
- end
13
-
14
- def evaluate(scope, locals, &block)
15
- @engine.render(scope, locals, &block)
16
- end
17
- end
18
-
19
- Tilt.register 'rabl', RablTemplate
20
- end