rabl 0.3.0 → 0.5.0
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/.gitignore +2 -0
- data/.travis.yml +10 -0
- data/CHANGELOG.md +34 -0
- data/Gemfile +14 -1
- data/README.md +53 -4
- data/Rakefile +26 -1
- data/fixtures/ashared/NOTES +35 -0
- data/fixtures/ashared/README +35 -0
- data/fixtures/ashared/migrate/20111002092016_create_users.rb +15 -0
- data/fixtures/ashared/migrate/20111002092019_create_posts.rb +14 -0
- data/fixtures/ashared/migrate/20111002092024_create_phone_numbers.rb +16 -0
- data/fixtures/ashared/models/phone_number.rb +7 -0
- data/fixtures/ashared/models/post.rb +3 -0
- data/fixtures/ashared/models/user.rb +3 -0
- data/fixtures/ashared/views/layouts/application.html.erb +6 -0
- data/fixtures/ashared/views/posts/date.json.rabl +3 -0
- data/fixtures/ashared/views/posts/index.json.rabl +11 -0
- data/fixtures/ashared/views/posts/show.json.rabl +16 -0
- data/fixtures/ashared/views/users/index.rabl +3 -0
- data/fixtures/ashared/views/users/phone_number.rabl +6 -0
- data/fixtures/ashared/views/users/show.rabl +16 -0
- data/fixtures/padrino_test/.components +7 -0
- data/fixtures/padrino_test/.gitignore +7 -0
- data/fixtures/padrino_test/Gemfile +17 -0
- data/fixtures/padrino_test/Rakefile +3 -0
- data/fixtures/padrino_test/app/app.rb +59 -0
- data/fixtures/padrino_test/app/controllers/posts.rb +11 -0
- data/fixtures/padrino_test/app/controllers/users.rb +11 -0
- data/fixtures/padrino_test/app/helpers/posts_helper.rb +7 -0
- data/fixtures/padrino_test/app/helpers/users_helper.rb +7 -0
- data/fixtures/padrino_test/config.ru +9 -0
- data/fixtures/padrino_test/config/apps.rb +34 -0
- data/fixtures/padrino_test/config/boot.rb +29 -0
- data/fixtures/padrino_test/config/database.rb +43 -0
- data/fixtures/padrino_test/db/schema.rb +42 -0
- data/fixtures/padrino_test/public/favicon.ico +0 -0
- data/fixtures/padrino_test/test/app/controllers/posts_controller_test.rb +108 -0
- data/fixtures/padrino_test/test/app/controllers/users_controller_test.rb +87 -0
- data/fixtures/padrino_test/test/test.rake +18 -0
- data/fixtures/padrino_test/test/test_config.rb +18 -0
- data/fixtures/rails2/.gitignore +1 -0
- data/fixtures/rails2/Gemfile +8 -0
- data/fixtures/rails2/Rakefile +14 -0
- data/fixtures/rails2/app/controllers/application_controller.rb +10 -0
- data/fixtures/rails2/app/controllers/posts_controller.rb +15 -0
- data/fixtures/rails2/app/controllers/users_controller.rb +15 -0
- data/fixtures/rails2/config/boot.rb +129 -0
- data/fixtures/rails2/config/database.yml +16 -0
- data/fixtures/rails2/config/environment.rb +42 -0
- data/fixtures/rails2/config/environments/development.rb +17 -0
- data/fixtures/rails2/config/environments/production.rb +28 -0
- data/fixtures/rails2/config/environments/test.rb +28 -0
- data/fixtures/rails2/config/initializers/backtrace_silencers.rb +7 -0
- data/fixtures/rails2/config/initializers/cookie_verification_secret.rb +7 -0
- data/fixtures/rails2/config/initializers/inflections.rb +10 -0
- data/fixtures/rails2/config/initializers/mime_types.rb +5 -0
- data/fixtures/rails2/config/initializers/new_rails_defaults.rb +21 -0
- data/fixtures/rails2/config/initializers/session_store.rb +15 -0
- data/fixtures/rails2/config/locales/en.yml +5 -0
- data/fixtures/rails2/config/preinitializer.rb +20 -0
- data/fixtures/rails2/config/routes.rb +45 -0
- data/fixtures/rails2/db/schema.rb +40 -0
- data/fixtures/rails2/db/seeds.rb +7 -0
- data/fixtures/rails2/public/404.html +30 -0
- data/fixtures/rails2/public/422.html +30 -0
- data/fixtures/rails2/public/500.html +30 -0
- data/fixtures/rails2/public/favicon.ico +0 -0
- data/fixtures/rails2/public/images/rails.png +0 -0
- data/fixtures/rails2/public/index.html +275 -0
- data/fixtures/rails2/public/robots.txt +5 -0
- data/fixtures/rails2/script/about +4 -0
- data/fixtures/rails2/script/console +3 -0
- data/fixtures/rails2/script/dbconsole +3 -0
- data/fixtures/rails2/script/destroy +3 -0
- data/fixtures/rails2/script/generate +3 -0
- data/fixtures/rails2/script/performance/benchmarker +3 -0
- data/fixtures/rails2/script/performance/profiler +3 -0
- data/fixtures/rails2/script/plugin +3 -0
- data/fixtures/rails2/script/runner +3 -0
- data/fixtures/rails2/script/server +3 -0
- data/fixtures/rails2/test/functionals/posts_controller_test.rb +108 -0
- data/fixtures/rails2/test/functionals/users_controller_test.rb +87 -0
- data/fixtures/rails2/test/test_helper.rb +33 -0
- data/fixtures/rails3/.gitignore +4 -0
- data/fixtures/rails3/Gemfile +37 -0
- data/fixtures/rails3/Rakefile +12 -0
- data/fixtures/rails3/app/controllers/application_controller.rb +14 -0
- data/fixtures/rails3/app/controllers/posts_controller.rb +11 -0
- data/fixtures/rails3/app/controllers/users_controller.rb +11 -0
- data/fixtures/rails3/config.ru +4 -0
- data/fixtures/rails3/config/application.rb +42 -0
- data/fixtures/rails3/config/boot.rb +6 -0
- data/fixtures/rails3/config/database.yml +22 -0
- data/fixtures/rails3/config/environment.rb +5 -0
- data/fixtures/rails3/config/environments/development.rb +26 -0
- data/fixtures/rails3/config/environments/production.rb +49 -0
- data/fixtures/rails3/config/environments/test.rb +35 -0
- data/fixtures/rails3/config/initializers/backtrace_silencers.rb +7 -0
- data/fixtures/rails3/config/initializers/inflections.rb +10 -0
- data/fixtures/rails3/config/initializers/mime_types.rb +5 -0
- data/fixtures/rails3/config/initializers/secret_token.rb +7 -0
- data/fixtures/rails3/config/initializers/session_store.rb +8 -0
- data/fixtures/rails3/config/locales/en.yml +5 -0
- data/fixtures/rails3/config/routes.rb +61 -0
- data/fixtures/rails3/db/seeds.rb +7 -0
- data/fixtures/rails3/lib/tasks/.gitkeep +0 -0
- data/fixtures/rails3/public/404.html +26 -0
- data/fixtures/rails3/public/422.html +26 -0
- data/fixtures/rails3/public/500.html +26 -0
- data/fixtures/rails3/public/favicon.ico +0 -0
- data/fixtures/rails3/public/images/rails.png +0 -0
- data/fixtures/rails3/public/index.html +239 -0
- data/fixtures/rails3/public/robots.txt +5 -0
- data/fixtures/rails3/public/stylesheets/.gitkeep +0 -0
- data/fixtures/rails3/script/rails +6 -0
- data/fixtures/rails3/test/functional/posts_controller_test.rb +108 -0
- data/fixtures/rails3/test/functional/users_controller_test.rb +87 -0
- data/fixtures/rails3/test/test_helper.rb +26 -0
- data/fixtures/sinatra_test/Gemfile +13 -0
- data/fixtures/sinatra_test/Rakefile +6 -0
- data/fixtures/sinatra_test/app.rb +44 -0
- data/fixtures/sinatra_test/config.ru +7 -0
- data/fixtures/sinatra_test/test/functional/posts_controller_test.rb +108 -0
- data/fixtures/sinatra_test/test/functional/users_controller_test.rb +87 -0
- data/fixtures/sinatra_test/test/test_helper.rb +19 -0
- data/lib/rabl.rb +13 -1
- data/lib/rabl/builder.rb +14 -7
- data/lib/rabl/configuration.rb +41 -1
- data/lib/rabl/engine.rb +29 -19
- data/lib/rabl/helpers.rb +45 -18
- data/lib/rabl/template.rb +1 -1
- data/lib/rabl/version.rb +1 -1
- data/rabl.gemspec +6 -5
- data/test/builder_test.rb +4 -4
- data/test/configuration_test.rb +7 -22
- data/test/engine_test.rb +63 -44
- data/test/helpers_test.rb +68 -0
- data/test/integration/posts_controller_test.rb +108 -0
- data/test/integration/test_init.rb +35 -0
- data/test/integration/users_controller_test.rb +87 -0
- data/test/models/ormless.rb +2 -0
- data/test/models/user.rb +17 -6
- data/test/msgpack_engine_test.rb +332 -0
- data/test/silence.rb +21 -0
- data/test/teststrap.rb +22 -6
- metadata +160 -14
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Load Silence Functionality
|
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + "/../../../test/silence.rb")
|
|
3
|
+
|
|
4
|
+
silence_warnings do
|
|
5
|
+
PADRINO_ENV = 'test' unless defined?(PADRINO_ENV)
|
|
6
|
+
require 'bundler'
|
|
7
|
+
Bundler.require
|
|
8
|
+
require File.expand_path(File.dirname(__FILE__) + "/../app.rb")
|
|
9
|
+
silence_stream(STDOUT) { ActiveRecord::Migrator.up('db/migrate') } # Load up test migrations
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Load Riot Test Environment
|
|
13
|
+
require File.expand_path(File.dirname(__FILE__) + "/../../../test/integration/test_init.rb")
|
|
14
|
+
|
|
15
|
+
class Riot::Situation
|
|
16
|
+
def app
|
|
17
|
+
@app || SinatraTest
|
|
18
|
+
end
|
|
19
|
+
end
|
data/lib/rabl.rb
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
require 'active_support'
|
|
2
|
+
require 'active_support/core_ext/string/inflections'
|
|
3
|
+
require 'active_support/core_ext/object/blank'
|
|
4
|
+
require 'active_support/core_ext/hash/reverse_merge'
|
|
5
|
+
require 'active_support/core_ext/hash/slice'
|
|
6
|
+
|
|
1
7
|
require 'rabl/version'
|
|
2
8
|
require 'rabl/helpers'
|
|
3
9
|
require 'rabl/engine'
|
|
@@ -18,7 +24,8 @@ module Rabl
|
|
|
18
24
|
# config.enable_json_callbacks = true
|
|
19
25
|
# end
|
|
20
26
|
def configure(&block)
|
|
21
|
-
yield(
|
|
27
|
+
yield(configuration)
|
|
28
|
+
configuration
|
|
22
29
|
end
|
|
23
30
|
|
|
24
31
|
# Returns the configuration options set for RABL
|
|
@@ -26,6 +33,11 @@ module Rabl
|
|
|
26
33
|
def configuration
|
|
27
34
|
@_configuration ||= Configuration.new
|
|
28
35
|
end
|
|
36
|
+
|
|
37
|
+
# Resets the RABL configuration back to the defaults.
|
|
38
|
+
def reset_configuration!
|
|
39
|
+
@_configuration = nil
|
|
40
|
+
end
|
|
29
41
|
end
|
|
30
42
|
end
|
|
31
43
|
|
data/lib/rabl/builder.rb
CHANGED
|
@@ -25,8 +25,8 @@ module Rabl
|
|
|
25
25
|
attribute(attribute, :as => name)
|
|
26
26
|
end if @options.has_key?(:attributes)
|
|
27
27
|
# Code
|
|
28
|
-
@options[:code].
|
|
29
|
-
code(name, settings[:options], &settings[:block])
|
|
28
|
+
@options[:code].each do |settings|
|
|
29
|
+
code(settings[:name], settings[:options], &settings[:block])
|
|
30
30
|
end if @options.has_key?(:code)
|
|
31
31
|
# Children
|
|
32
32
|
@options[:child].each do |settings|
|
|
@@ -61,7 +61,13 @@ module Rabl
|
|
|
61
61
|
# code(:foo) { "bar" }
|
|
62
62
|
# code(:foo, :if => lambda { |m| m.foo.present? }) { "bar" }
|
|
63
63
|
def code(name, options={}, &block)
|
|
64
|
-
|
|
64
|
+
return unless resolve_condition(options)
|
|
65
|
+
result = block.call(@_object)
|
|
66
|
+
if name.present?
|
|
67
|
+
@_result[name] = result
|
|
68
|
+
else
|
|
69
|
+
@_result.merge!(result) if result
|
|
70
|
+
end
|
|
65
71
|
end
|
|
66
72
|
alias_method :node, :code
|
|
67
73
|
|
|
@@ -72,9 +78,10 @@ module Rabl
|
|
|
72
78
|
def child(data, options={}, &block)
|
|
73
79
|
return false unless data.present?
|
|
74
80
|
name, object = data_name(data), data_object(data)
|
|
75
|
-
include_root =
|
|
81
|
+
include_root = is_collection?(object) && @options[:child_root] # child @users
|
|
82
|
+
engine_options = @options.slice(:child_root).merge(:root => include_root)
|
|
76
83
|
object = { object => name } if data.respond_to?(:each_pair) && object # child :users => :people
|
|
77
|
-
@_result[name] = self.object_to_hash(object,
|
|
84
|
+
@_result[name] = self.object_to_hash(object, engine_options, &block) if resolve_condition(options)
|
|
78
85
|
end
|
|
79
86
|
|
|
80
87
|
# Glues data from a child node to the json_output
|
|
@@ -89,9 +96,9 @@ module Rabl
|
|
|
89
96
|
# Extends an existing rabl template with additional attributes in the block
|
|
90
97
|
# extends("users/show") { attribute :full_name }
|
|
91
98
|
def extends(file, options={}, &block)
|
|
92
|
-
options = options.merge(:object => @_object)
|
|
99
|
+
options = @options.slice(:child_root).merge(options).merge(:object => @_object)
|
|
93
100
|
result = self.partial(file, options, &block)
|
|
94
101
|
@_result.merge!(result) if result
|
|
95
102
|
end
|
|
96
103
|
end
|
|
97
|
-
end
|
|
104
|
+
end
|
data/lib/rabl/configuration.rb
CHANGED
|
@@ -1,22 +1,52 @@
|
|
|
1
|
+
# We load the msgpack library if it is available.
|
|
2
|
+
begin
|
|
3
|
+
require 'msgpack'
|
|
4
|
+
rescue LoadError
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
# Load MultiJSON
|
|
8
|
+
require 'multi_json'
|
|
9
|
+
|
|
1
10
|
module Rabl
|
|
2
11
|
# Rabl.host
|
|
3
12
|
class Configuration
|
|
4
13
|
attr_accessor :include_json_root
|
|
14
|
+
attr_accessor :include_msgpack_root
|
|
5
15
|
attr_accessor :include_xml_root
|
|
6
16
|
attr_accessor :enable_json_callbacks
|
|
7
|
-
|
|
17
|
+
attr_writer :msgpack_engine
|
|
8
18
|
attr_writer :xml_options
|
|
9
19
|
|
|
10
20
|
DEFAULT_XML_OPTIONS = { :dasherize => true, :skip_types => false }
|
|
11
21
|
|
|
12
22
|
def initialize
|
|
13
23
|
@include_json_root = true
|
|
24
|
+
@include_msgpack_root = true
|
|
14
25
|
@include_xml_root = false
|
|
15
26
|
@enable_json_callbacks = false
|
|
16
27
|
@json_engine = nil
|
|
28
|
+
@msgpack_engine = nil
|
|
17
29
|
@xml_options = {}
|
|
18
30
|
end
|
|
19
31
|
|
|
32
|
+
# @param [Symbol, String, #encode] engine_name The name of a JSON engine,
|
|
33
|
+
# or class that responds to `encode`, to use to encode Rabl templates
|
|
34
|
+
# into JSON. For more details, see the MultiJson gem.
|
|
35
|
+
def json_engine=(engine_name_or_class)
|
|
36
|
+
MultiJson.engine = @engine_name = engine_name_or_class
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# @return The JSON engine used to encode Rabl templates into JSON
|
|
40
|
+
def json_engine
|
|
41
|
+
get_json_engine
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
##
|
|
45
|
+
# @return the MessagePack encoder/engine to use.
|
|
46
|
+
def msgpack_engine
|
|
47
|
+
@msgpack_engine || ::MessagePack
|
|
48
|
+
end
|
|
49
|
+
|
|
20
50
|
# Allows config options to be read like a hash
|
|
21
51
|
#
|
|
22
52
|
# @param [Symbol] option Key for a given attribute
|
|
@@ -28,5 +58,15 @@ module Rabl
|
|
|
28
58
|
def default_xml_options
|
|
29
59
|
@_default_xml_options ||= @xml_options.reverse_merge(DEFAULT_XML_OPTIONS)
|
|
30
60
|
end
|
|
61
|
+
|
|
62
|
+
private
|
|
63
|
+
|
|
64
|
+
def get_json_engine
|
|
65
|
+
if !defined?(@engine_name) && defined?(Rails)
|
|
66
|
+
ActiveSupport::JSON
|
|
67
|
+
else
|
|
68
|
+
MultiJson.engine
|
|
69
|
+
end
|
|
70
|
+
end
|
|
31
71
|
end
|
|
32
72
|
end
|
data/lib/rabl/engine.rb
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
require 'multi_json'
|
|
2
|
-
|
|
3
1
|
module Rabl
|
|
4
2
|
class Engine
|
|
5
3
|
include Rabl::Helpers
|
|
@@ -9,10 +7,6 @@ module Rabl
|
|
|
9
7
|
def initialize(source, options={})
|
|
10
8
|
@_source = source
|
|
11
9
|
@_options = options
|
|
12
|
-
|
|
13
|
-
if Rabl.configuration.json_engine
|
|
14
|
-
MultiJson.engine = Rabl.configuration.json_engine
|
|
15
|
-
end
|
|
16
10
|
end
|
|
17
11
|
|
|
18
12
|
# Renders the representation based on source, object, scope and locals
|
|
@@ -23,7 +17,11 @@ module Rabl
|
|
|
23
17
|
@_options[:scope] = @_scope
|
|
24
18
|
@_options[:format] ||= self.request_format
|
|
25
19
|
@_data = locals[:object] || self.default_object
|
|
26
|
-
|
|
20
|
+
if @_options[:source_location]
|
|
21
|
+
instance_eval(@_source, @_options[:source_location]) if @_source.present?
|
|
22
|
+
else
|
|
23
|
+
instance_eval(@_source) if @_source.present?
|
|
24
|
+
end
|
|
27
25
|
instance_eval(&block) if block_given?
|
|
28
26
|
self.send("to_" + @_options[:format].to_s)
|
|
29
27
|
end
|
|
@@ -33,9 +31,9 @@ module Rabl
|
|
|
33
31
|
def to_hash(options={})
|
|
34
32
|
options = options.reverse_merge(@_options)
|
|
35
33
|
data = data_object(@_data)
|
|
36
|
-
if
|
|
34
|
+
if is_object?(data) || !data # object @user
|
|
37
35
|
Rabl::Builder.new(@_data, options).to_hash(options)
|
|
38
|
-
elsif
|
|
36
|
+
elsif is_collection?(data) # collection @users
|
|
39
37
|
object_name = data_name(@_data).to_s.singularize # @users => :users
|
|
40
38
|
data.map { |object| Rabl::Builder.new({ object => object_name }, options).to_hash(options) }
|
|
41
39
|
end
|
|
@@ -46,8 +44,17 @@ module Rabl
|
|
|
46
44
|
def to_json(options={})
|
|
47
45
|
include_root = Rabl.configuration.include_json_root
|
|
48
46
|
options = options.reverse_merge(:root => include_root, :child_root => include_root)
|
|
49
|
-
result = @_collection_name ? { @_collection_name => to_hash(options) } : to_hash(options)
|
|
50
|
-
format_json
|
|
47
|
+
result = defined?(@_collection_name) ? { @_collection_name => to_hash(options) } : to_hash(options)
|
|
48
|
+
format_json(result)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Returns a msgpack representation of the data object
|
|
52
|
+
# to_msgpack(:root => true)
|
|
53
|
+
def to_msgpack(options={})
|
|
54
|
+
include_root = Rabl.configuration.include_msgpack_root
|
|
55
|
+
options = options.reverse_merge(:root => include_root, :child_root => include_root)
|
|
56
|
+
result = defined?(@_collection_name) ? { @_collection_name => to_hash(options) } : to_hash(options)
|
|
57
|
+
Rabl.configuration.msgpack_engine.pack result
|
|
51
58
|
end
|
|
52
59
|
|
|
53
60
|
# Returns an xml representation of the data object
|
|
@@ -92,9 +99,9 @@ module Rabl
|
|
|
92
99
|
# Creates an arbitrary code node that is included in the json output
|
|
93
100
|
# code(:foo) { "bar" }
|
|
94
101
|
# code(:foo, :if => lambda { ... }) { "bar" }
|
|
95
|
-
def code(name, options={}, &block)
|
|
96
|
-
@_options[:code] ||=
|
|
97
|
-
@_options[:code]
|
|
102
|
+
def code(name = nil, options={}, &block)
|
|
103
|
+
@_options[:code] ||= []
|
|
104
|
+
@_options[:code] << { :name => name, :options => options, :block => block }
|
|
98
105
|
end
|
|
99
106
|
alias_method :node, :code
|
|
100
107
|
|
|
@@ -131,9 +138,10 @@ module Rabl
|
|
|
131
138
|
# Returns a guess at the default object for this template
|
|
132
139
|
# default_object => @user
|
|
133
140
|
def default_object
|
|
134
|
-
@_scope.respond_to?(:controller)
|
|
135
|
-
|
|
136
|
-
|
|
141
|
+
if @_scope.respond_to?(:controller)
|
|
142
|
+
full_name = @_scope.controller.controller_name
|
|
143
|
+
instance_variable_get("@#{ full_name.split("::").last }")
|
|
144
|
+
end
|
|
137
145
|
end
|
|
138
146
|
|
|
139
147
|
# Returns a guess at the format in this scope
|
|
@@ -152,9 +160,11 @@ module Rabl
|
|
|
152
160
|
@_scope.respond_to?(:params) ? @_scope.params : {}
|
|
153
161
|
end
|
|
154
162
|
|
|
155
|
-
# Returns json embraced with callback
|
|
156
|
-
#
|
|
163
|
+
# Returns data as json embraced with callback when detected
|
|
164
|
+
# format_json({ :foo => "bar" }) => "test({ foo : 'bar' })"
|
|
165
|
+
# format_json("{ foo : "bar" }") => "test({ foo : 'bar' })"
|
|
157
166
|
def format_json(json_output)
|
|
167
|
+
json_output = Rabl.configuration.json_engine.encode(json_output) unless json_output.is_a?(String)
|
|
158
168
|
use_callback = Rabl.configuration.enable_json_callbacks && request_params[:callback].present?
|
|
159
169
|
use_callback ? "#{request_params[:callback]}(#{json_output})" : json_output
|
|
160
170
|
end
|
data/lib/rabl/helpers.rb
CHANGED
|
@@ -17,10 +17,10 @@ module Rabl
|
|
|
17
17
|
return nil unless data # nil or false
|
|
18
18
|
return data.values.first if data.is_a?(Hash) # @user => :user
|
|
19
19
|
data = @_object.send(data) if data.is_a?(Symbol) && @_object # :address
|
|
20
|
-
if data.respond_to?(:first)
|
|
21
|
-
data_name(data.first).pluralize
|
|
20
|
+
if data.respond_to?(:first)
|
|
21
|
+
data_name(data.first).pluralize if data.first.present?
|
|
22
22
|
else # actual data object
|
|
23
|
-
object_name = @_collection_name.to_s.singularize if @_collection_name
|
|
23
|
+
object_name = @_collection_name.to_s.singularize if defined? @_collection_name
|
|
24
24
|
object_name ||= data.class.respond_to?(:model_name) ? data.class.model_name.element : data.class.to_s.downcase
|
|
25
25
|
object_name
|
|
26
26
|
end
|
|
@@ -28,17 +28,23 @@ module Rabl
|
|
|
28
28
|
|
|
29
29
|
# Renders a partial hash based on another rabl template
|
|
30
30
|
# partial("users/show", :object => @user)
|
|
31
|
+
# options must have :object
|
|
32
|
+
# options can have :view_path, :child_root, :root
|
|
31
33
|
def partial(file, options={}, &block)
|
|
32
|
-
|
|
33
|
-
self.
|
|
34
|
+
object, view_path = options.delete(:object), options.delete(:view_path)
|
|
35
|
+
source, location = self.fetch_source(file, :view_path => view_path)
|
|
36
|
+
engine_options = options.merge(:source => source, :source_location => location)
|
|
37
|
+
self.object_to_hash(object, engine_options, &block)
|
|
34
38
|
end
|
|
35
39
|
|
|
36
40
|
# Returns a hash based representation of any data object given ejs template block
|
|
37
41
|
# object_to_hash(@user) { attribute :full_name } => { ... }
|
|
38
42
|
# object_to_hash(@user, :source => "...") { attribute :full_name } => { ... }
|
|
43
|
+
# options must have :source (rabl file contents)
|
|
44
|
+
# options can have :source_location (source filename)
|
|
39
45
|
def object_to_hash(object, options={}, &block)
|
|
40
|
-
return object unless
|
|
41
|
-
engine_options =
|
|
46
|
+
return object unless is_object?(object) || is_collection?(object)
|
|
47
|
+
engine_options = options.merge(:format => "hash", :root => (options[:root] || false))
|
|
42
48
|
Rabl::Engine.new(options[:source], engine_options).render(@_scope, :object => object, &block)
|
|
43
49
|
end
|
|
44
50
|
|
|
@@ -52,21 +58,42 @@ module Rabl
|
|
|
52
58
|
result
|
|
53
59
|
end
|
|
54
60
|
|
|
55
|
-
# Returns true if
|
|
56
|
-
#
|
|
57
|
-
#
|
|
58
|
-
|
|
59
|
-
|
|
61
|
+
# Returns true if obj is not enumerable
|
|
62
|
+
# is_object?(@user) => true
|
|
63
|
+
# is_object?([]) => false
|
|
64
|
+
# is_object?({}) => false
|
|
65
|
+
def is_object?(obj)
|
|
66
|
+
obj && !data_object(obj).is_a?(Enumerable)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Returns true if the obj is a collection of items
|
|
70
|
+
def is_collection?(obj)
|
|
71
|
+
obj && data_object(obj).is_a?(Enumerable)
|
|
60
72
|
end
|
|
61
73
|
|
|
62
74
|
# Returns source for a given relative file
|
|
63
75
|
# fetch_source("show", :view_path => "...") => "...contents..."
|
|
64
76
|
def fetch_source(file, options={})
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
77
|
+
if defined? Rails
|
|
78
|
+
root_path = Rails.root
|
|
79
|
+
view_path = options[:view_path] || File.join(root_path, "app/views/")
|
|
80
|
+
file_path = Dir[File.join(view_path, file + ".{*.,}rabl")].first
|
|
81
|
+
elsif defined? Padrino
|
|
82
|
+
root_path = Padrino.root
|
|
83
|
+
# use Padrino's own template resolution mechanism
|
|
84
|
+
file_path, _ = @_scope.instance_eval { resolve_template(file) }
|
|
85
|
+
# Padrino chops the extension, stitch it back on
|
|
86
|
+
file_path = File.join(@_scope.settings.views, (file_path.to_s + ".rabl"))
|
|
87
|
+
elsif defined? Sinatra
|
|
88
|
+
view_path = options[:view_path] || @_scope.settings.views
|
|
89
|
+
file_path = Dir[File.join(view_path, file + ".{*.,}rabl")].first
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
if file_path
|
|
93
|
+
return File.read(file_path.to_s), file_path.to_s
|
|
94
|
+
else # no file path specified
|
|
95
|
+
nil
|
|
96
|
+
end
|
|
70
97
|
end
|
|
71
98
|
end
|
|
72
|
-
end
|
|
99
|
+
end
|
data/lib/rabl/template.rb
CHANGED
data/lib/rabl/version.rb
CHANGED
data/rabl.gemspec
CHANGED
|
@@ -19,12 +19,13 @@ Gem::Specification.new do |s|
|
|
|
19
19
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
|
20
20
|
s.require_paths = ["lib"]
|
|
21
21
|
|
|
22
|
-
s.add_dependency 'multi_json',
|
|
22
|
+
s.add_dependency 'multi_json', '~> 1.0.3'
|
|
23
|
+
s.add_dependency 'activesupport', '>= 2.3.14'
|
|
23
24
|
|
|
24
|
-
s.add_development_dependency 'riot',
|
|
25
|
-
s.add_development_dependency 'rr',
|
|
26
|
-
s.add_development_dependency '
|
|
25
|
+
s.add_development_dependency 'riot', '~> 0.12.3'
|
|
26
|
+
s.add_development_dependency 'rr', '~> 1.0.2'
|
|
27
|
+
s.add_development_dependency 'rake'
|
|
27
28
|
s.add_development_dependency 'tilt'
|
|
28
|
-
s.add_development_dependency 'bson_ext'
|
|
29
29
|
s.add_development_dependency 'yajl-ruby'
|
|
30
|
+
s.add_development_dependency 'msgpack', '~> 0.4.5'
|
|
30
31
|
end
|
data/test/builder_test.rb
CHANGED
|
@@ -62,10 +62,10 @@ context "Rabl::Builder" do
|
|
|
62
62
|
get_result(topic)
|
|
63
63
|
end.equivalent_to({:name => 'rabl', :city => 'irvine'})
|
|
64
64
|
|
|
65
|
-
|
|
65
|
+
asserts "that with a non-existent attribute the node" do
|
|
66
66
|
topic.attribute :fake
|
|
67
67
|
get_result(topic)[:fake]
|
|
68
|
-
end.
|
|
68
|
+
end.nil
|
|
69
69
|
|
|
70
70
|
end
|
|
71
71
|
|
|
@@ -131,7 +131,7 @@ context "Rabl::Builder" do
|
|
|
131
131
|
asserts "that it generates with an collection and child_root" do
|
|
132
132
|
b = builder @user, { :child_root => true }
|
|
133
133
|
mock(b).data_name(@users) { :users }
|
|
134
|
-
mock(b).object_to_hash(@users,{ :root => true }).returns('xyz').subject
|
|
134
|
+
mock(b).object_to_hash(@users,{ :root => true, :child_root => true }).returns('xyz').subject
|
|
135
135
|
|
|
136
136
|
b.child(@users) { attribute :name }
|
|
137
137
|
get_result(b)
|
|
@@ -140,7 +140,7 @@ context "Rabl::Builder" do
|
|
|
140
140
|
asserts "that it generates with an collection and no child root" do
|
|
141
141
|
b = builder @user, { :child_root => false }
|
|
142
142
|
mock(b).data_name(@users) { :users }
|
|
143
|
-
mock(b).object_to_hash(@users,{ :root => false }).returns('xyz').subject
|
|
143
|
+
mock(b).object_to_hash(@users,{ :root => false, :child_root => false }).returns('xyz').subject
|
|
144
144
|
|
|
145
145
|
b.child(@users) { attribute :name }
|
|
146
146
|
get_result(b)
|
data/test/configuration_test.rb
CHANGED
|
@@ -1,38 +1,23 @@
|
|
|
1
1
|
require File.expand_path('../teststrap', __FILE__)
|
|
2
2
|
require File.expand_path('../../lib/rabl', __FILE__)
|
|
3
3
|
|
|
4
|
-
context
|
|
5
|
-
|
|
6
|
-
context "with defaults" do
|
|
4
|
+
context 'Rabl::Configuration' do
|
|
5
|
+
context 'defaults' do
|
|
7
6
|
setup { Rabl.configuration }
|
|
8
7
|
|
|
9
8
|
asserts(:include_json_root).equals true
|
|
10
9
|
asserts(:include_xml_root).equals false
|
|
11
10
|
asserts(:enable_json_callbacks).equals false
|
|
12
|
-
asserts(:json_engine).equals
|
|
11
|
+
asserts(:json_engine).equals MultiJson.engine
|
|
13
12
|
end
|
|
14
13
|
|
|
15
|
-
context
|
|
14
|
+
context 'custom JSON engine' do
|
|
16
15
|
setup do
|
|
17
|
-
Rabl.configure do |
|
|
18
|
-
|
|
19
|
-
config.include_xml_root = true
|
|
20
|
-
config.enable_json_callbacks = true
|
|
21
|
-
config.json_engine = :yajl
|
|
16
|
+
Rabl.configure do |c|
|
|
17
|
+
c.json_engine = :yajl
|
|
22
18
|
end
|
|
23
|
-
Rabl.configuration
|
|
24
19
|
end
|
|
25
20
|
|
|
26
|
-
asserts(
|
|
27
|
-
asserts(:include_xml_root).equals true
|
|
28
|
-
asserts(:enable_json_callbacks).equals true
|
|
29
|
-
asserts(:json_engine).equals :yajl
|
|
30
|
-
|
|
31
|
-
teardown do
|
|
32
|
-
Rabl.configure do |config|
|
|
33
|
-
config.json_engine = MultiJson.default_engine
|
|
34
|
-
end
|
|
35
|
-
end
|
|
21
|
+
asserts('uses a custom JSON engine') { topic.json_engine == MultiJson::Engines::Yajl }
|
|
36
22
|
end
|
|
37
|
-
|
|
38
23
|
end
|