rabl 0.5.5.b → 0.5.5.c
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/CHANGELOG.md +2 -1
- data/lib/rabl.rb +21 -0
- data/lib/rabl/builder.rb +14 -2
- data/lib/rabl/engine.rb +2 -1
- data/lib/rabl/helpers.rb +1 -56
- data/lib/rabl/partials.rb +51 -0
- data/lib/rabl/version.rb +1 -1
- data/test/helpers_test.rb +3 -60
- data/test/partials_test.rb +68 -0
- metadata +6 -3
data/CHANGELOG.md
CHANGED
data/lib/rabl.rb
CHANGED
@@ -6,6 +6,7 @@ require 'active_support/core_ext/hash/slice'
|
|
6
6
|
|
7
7
|
require 'rabl/version'
|
8
8
|
require 'rabl/helpers'
|
9
|
+
require 'rabl/partials'
|
9
10
|
require 'rabl/engine'
|
10
11
|
require 'rabl/builder'
|
11
12
|
require 'rabl/configuration'
|
@@ -14,6 +15,7 @@ require 'rabl/railtie' if defined?(Rails) && Rails.version =~ /^3/
|
|
14
15
|
# Rabl.register!
|
15
16
|
module Rabl
|
16
17
|
class << self
|
18
|
+
|
17
19
|
def register!
|
18
20
|
require 'rabl/template'
|
19
21
|
end
|
@@ -38,6 +40,25 @@ module Rabl
|
|
38
40
|
def reset_configuration!
|
39
41
|
@_configuration = nil
|
40
42
|
end
|
43
|
+
|
44
|
+
# Fetches from the source_cache, stores block result in cache if nil
|
45
|
+
# Used to cache the contents and paths to various rabl templates
|
46
|
+
# source_cache("users/index", "path/to/view") { "/full/path/to/template/users/index" }
|
47
|
+
def source_cache(file, view_path, &block)
|
48
|
+
@_source_cache ||= {}
|
49
|
+
cache_key = [file, view_path].compact.join(":")
|
50
|
+
if cached_result = @_source_cache[cache_key]
|
51
|
+
cached_result
|
52
|
+
else # store result of block
|
53
|
+
@_source_cache[cache_key] = yield
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# Resets the RABL source cache
|
58
|
+
def reset_source_cache!
|
59
|
+
@_source_cache = {}
|
60
|
+
end
|
61
|
+
|
41
62
|
end
|
42
63
|
end
|
43
64
|
|
data/lib/rabl/builder.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Rabl
|
2
2
|
class Builder
|
3
|
-
include Rabl::
|
3
|
+
include Rabl::Partials
|
4
4
|
|
5
5
|
# Constructs a new rabl hash based on given object and options
|
6
6
|
# options = { :format => "json", :attributes, :root => true,
|
@@ -15,7 +15,6 @@ module Rabl
|
|
15
15
|
def build(data, options={})
|
16
16
|
@_data = data
|
17
17
|
@_object = data_object(data)
|
18
|
-
@_result = {}
|
19
18
|
compile_hash(options)
|
20
19
|
end
|
21
20
|
|
@@ -24,6 +23,7 @@ module Rabl
|
|
24
23
|
# Returns a hash representation of the data object
|
25
24
|
# compile_hash(:root => true)
|
26
25
|
def compile_hash(options={})
|
26
|
+
@_result = {}
|
27
27
|
# Extends
|
28
28
|
@options[:extends].each do |settings|
|
29
29
|
extends(settings[:file], settings[:options], &settings[:block])
|
@@ -107,5 +107,17 @@ module Rabl
|
|
107
107
|
result = self.partial(file, options, &block)
|
108
108
|
@_result.merge!(result) if result
|
109
109
|
end
|
110
|
+
|
111
|
+
protected
|
112
|
+
|
113
|
+
# resolve_condition(:if => true) => true
|
114
|
+
# resolve_condition(:if => lambda { |m| false }) => false
|
115
|
+
# resolve_condition(:unless => lambda { |m| true }) => true
|
116
|
+
def resolve_condition(options)
|
117
|
+
return true if options[:if].nil? && options[:unless].nil?
|
118
|
+
result = options[:if] == true || (options[:if].respond_to?(:call) && options[:if].call(@_object)) if options.has_key?(:if)
|
119
|
+
result = options[:unless] == false || (options[:unless].respond_to?(:call) && !options[:unless].call(@_object)) if options.has_key?(:unless)
|
120
|
+
result
|
121
|
+
end
|
110
122
|
end
|
111
123
|
end
|
data/lib/rabl/engine.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Rabl
|
2
2
|
class Engine
|
3
|
-
include Rabl::
|
3
|
+
include Rabl::Partials
|
4
4
|
|
5
5
|
# Constructs a new ejs engine based on given vars, handler and declarations
|
6
6
|
# Rabl::Engine.new("...source...", { :format => "xml", :root => true, :view_path => "/path/to/views" })
|
@@ -193,6 +193,7 @@ module Rabl
|
|
193
193
|
end
|
194
194
|
|
195
195
|
private
|
196
|
+
|
196
197
|
def clear_compile_state
|
197
198
|
@_options.delete(:extends)
|
198
199
|
@_options.delete(:attributes)
|
data/lib/rabl/helpers.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
module Rabl
|
2
2
|
module Helpers
|
3
|
+
|
3
4
|
# data_object(data) => <AR Object>
|
4
5
|
# data_object(@user => :person) => @user
|
5
6
|
# data_object(:user => :person) => @_object.send(:user)
|
@@ -26,38 +27,6 @@ module Rabl
|
|
26
27
|
end
|
27
28
|
end
|
28
29
|
|
29
|
-
# Renders a partial hash based on another rabl template
|
30
|
-
# partial("users/show", :object => @user)
|
31
|
-
# options must have :object
|
32
|
-
# options can have :view_path, :child_root, :root
|
33
|
-
def partial(file, options={}, &block)
|
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)
|
38
|
-
end
|
39
|
-
|
40
|
-
# Returns a hash based representation of any data object given ejs template block
|
41
|
-
# object_to_hash(@user) { attribute :full_name } => { ... }
|
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)
|
45
|
-
def object_to_hash(object, options={}, &block)
|
46
|
-
return object unless is_object?(object) || is_collection?(object)
|
47
|
-
engine_options = options.merge(:format => "hash", :root => (options[:root] || false))
|
48
|
-
Rabl::Engine.new(options[:source], engine_options).render(@_scope, :object => object, &block)
|
49
|
-
end
|
50
|
-
|
51
|
-
# resolve_condition(:if => true) => true
|
52
|
-
# resolve_condition(:if => lambda { |m| false }) => false
|
53
|
-
# resolve_condition(:unless => lambda { |m| true }) => true
|
54
|
-
def resolve_condition(options)
|
55
|
-
return true if options[:if].nil? && options[:unless].nil?
|
56
|
-
result = options[:if] == true || (options[:if].respond_to?(:call) && options[:if].call(@_object)) if options.has_key?(:if)
|
57
|
-
result = options[:unless] == false || (options[:unless].respond_to?(:call) && !options[:unless].call(@_object)) if options.has_key?(:unless)
|
58
|
-
result
|
59
|
-
end
|
60
|
-
|
61
30
|
# Returns true if obj is not enumerable
|
62
31
|
# is_object?(@user) => true
|
63
32
|
# is_object?([]) => false
|
@@ -71,29 +40,5 @@ module Rabl
|
|
71
40
|
obj && data_object(obj).respond_to?(:each)
|
72
41
|
end
|
73
42
|
|
74
|
-
# Returns source for a given relative file
|
75
|
-
# fetch_source("show", :view_path => "...") => "...contents..."
|
76
|
-
def fetch_source(file, options={})
|
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
|
97
|
-
end
|
98
43
|
end
|
99
44
|
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Rabl
|
2
|
+
module Partials
|
3
|
+
include Rabl::Helpers
|
4
|
+
|
5
|
+
# Renders a partial hash based on another rabl template
|
6
|
+
# partial("users/show", :object => @user)
|
7
|
+
# options must have :object
|
8
|
+
# options can have :view_path, :child_root, :root
|
9
|
+
def partial(file, options={}, &block)
|
10
|
+
object, view_path = options.delete(:object), options.delete(:view_path)
|
11
|
+
source, location = self.fetch_source(file, :view_path => view_path)
|
12
|
+
engine_options = options.merge(:source => source, :source_location => location)
|
13
|
+
self.object_to_hash(object, engine_options, &block)
|
14
|
+
end
|
15
|
+
|
16
|
+
# Returns a hash based representation of any data object given ejs template block
|
17
|
+
# object_to_hash(@user) { attribute :full_name } => { ... }
|
18
|
+
# object_to_hash(@user, :source => "...") { attribute :full_name } => { ... }
|
19
|
+
# options must have :source (rabl file contents)
|
20
|
+
# options can have :source_location (source filename)
|
21
|
+
def object_to_hash(object, options={}, &block)
|
22
|
+
return object unless is_object?(object) || is_collection?(object)
|
23
|
+
engine_options = options.merge(:format => "hash", :root => (options[:root] || false))
|
24
|
+
Rabl::Engine.new(options[:source], engine_options).render(@_scope, :object => object, &block)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Returns source for a given relative file
|
28
|
+
# fetch_source("show", :view_path => "...") => "...contents..."
|
29
|
+
def fetch_source(file, options={})
|
30
|
+
Rabl.source_cache(file, options[:view_path]) do
|
31
|
+
if defined? Padrino
|
32
|
+
root_path = Padrino.root
|
33
|
+
# use Padrino's own template resolution mechanism
|
34
|
+
file_path, _ = @_scope.instance_eval { resolve_template(file) }
|
35
|
+
# Padrino chops the extension, stitch it back on
|
36
|
+
file_path = File.join(@_scope.settings.views, (file_path.to_s + ".rabl"))
|
37
|
+
elsif defined? Rails
|
38
|
+
root_path = Rails.root
|
39
|
+
view_path = options[:view_path] || File.join(root_path, "app/views/")
|
40
|
+
file_path = Dir[File.join(view_path, file + ".{*.,}rabl")].first
|
41
|
+
elsif defined? Sinatra
|
42
|
+
view_path = options[:view_path] || @_scope.settings.views
|
43
|
+
file_path = Dir[File.join(view_path, file + ".{*.,}rabl")].first
|
44
|
+
end
|
45
|
+
|
46
|
+
[File.read(file_path.to_s), file_path.to_s] if file_path
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end # Partials
|
51
|
+
end # Rabl
|
data/lib/rabl/version.rb
CHANGED
data/test/helpers_test.rb
CHANGED
@@ -2,67 +2,10 @@ require 'tmpdir'
|
|
2
2
|
require 'pathname'
|
3
3
|
require File.expand_path('../../lib/rabl', __FILE__)
|
4
4
|
|
5
|
-
class
|
5
|
+
class TestPartial
|
6
6
|
include Rabl::Helpers
|
7
7
|
end
|
8
8
|
|
9
9
|
context "Rabl::Helpers" do
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
setup do
|
14
|
-
::Rails = stub(Class.new)
|
15
|
-
::Rails.root.returns(tmp_path)
|
16
|
-
File.open(tmp_path + "test.json.rabl", "w") do |f|
|
17
|
-
f.puts "content"
|
18
|
-
end
|
19
|
-
File.open(tmp_path + "test_v1.json.rabl", "w") do |f|
|
20
|
-
f.puts "content_v1"
|
21
|
-
end
|
22
|
-
FileUtils.touch tmp_path + "test_v2.json.rabl"
|
23
|
-
[TestHelper.new.fetch_source('test', :view_path => tmp_path.to_s),
|
24
|
-
TestHelper.new.fetch_source('test_v1', :view_path => tmp_path.to_s)]
|
25
|
-
end
|
26
|
-
|
27
|
-
asserts(:first).equals {["content\n", (tmp_path + "test.json.rabl").to_s ]}
|
28
|
-
asserts(:last).equals {["content_v1\n", (tmp_path + "test_v1.json.rabl").to_s ]}
|
29
|
-
teardown { Object.send(:remove_const, :Rails) }
|
30
|
-
end
|
31
|
-
|
32
|
-
context "fetch_source" do
|
33
|
-
helper(:tmp_path) { @tmp_path ||= Pathname.new(Dir.mktmpdir) }
|
34
|
-
|
35
|
-
setup do
|
36
|
-
::Rails = stub(Class.new)
|
37
|
-
::Rails.root.returns(tmp_path)
|
38
|
-
File.open(tmp_path + "test.rabl", "w") do |f|
|
39
|
-
f.puts "content"
|
40
|
-
end
|
41
|
-
TestHelper.new.fetch_source('test', :view_path => tmp_path.to_s)
|
42
|
-
end
|
43
|
-
asserts('detects file.rabl') { topic }.equals do
|
44
|
-
["content\n", (tmp_path + 'test.rabl').to_s]
|
45
|
-
end
|
46
|
-
teardown { Object.send(:remove_const, :Rails) }
|
47
|
-
end
|
48
|
-
|
49
|
-
context "fetch_source" do
|
50
|
-
helper(:tmp_path) { @tmp_path ||= Pathname.new(Dir.mktmpdir) }
|
51
|
-
|
52
|
-
setup do
|
53
|
-
::Rails = stub(Class.new)
|
54
|
-
::Rails.root.returns(tmp_path)
|
55
|
-
File.open(tmp_path + "test.rabl", "w") do |f|
|
56
|
-
f.puts "content"
|
57
|
-
end
|
58
|
-
File.open(tmp_path + "test.json.rabl", "w") do |f|
|
59
|
-
f.puts "content2"
|
60
|
-
end
|
61
|
-
TestHelper.new.fetch_source('test', :view_path => tmp_path.to_s)
|
62
|
-
end
|
63
|
-
asserts('detects file.json.rabl first') { topic }.equals do
|
64
|
-
["content2\n", (tmp_path + 'test.json.rabl').to_s]
|
65
|
-
end
|
66
|
-
teardown { Object.send(:remove_const, :Rails) }
|
67
|
-
end
|
68
|
-
end
|
10
|
+
# TODO needs tests
|
11
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'tmpdir'
|
2
|
+
require 'pathname'
|
3
|
+
require File.expand_path('../../lib/rabl', __FILE__)
|
4
|
+
|
5
|
+
class TestPartial
|
6
|
+
include Rabl::Partials
|
7
|
+
end
|
8
|
+
|
9
|
+
context "Rabl::Partials" do
|
10
|
+
context "fetch_source" do
|
11
|
+
helper(:tmp_path) { @tmp_path ||= Pathname.new(Dir.mktmpdir) }
|
12
|
+
|
13
|
+
setup do
|
14
|
+
::Rails = stub(Class.new)
|
15
|
+
::Rails.root.returns(tmp_path)
|
16
|
+
File.open(tmp_path + "test.json.rabl", "w") do |f|
|
17
|
+
f.puts "content"
|
18
|
+
end
|
19
|
+
File.open(tmp_path + "test_v1.json.rabl", "w") do |f|
|
20
|
+
f.puts "content_v1"
|
21
|
+
end
|
22
|
+
FileUtils.touch tmp_path + "test_v2.json.rabl"
|
23
|
+
[TestPartial.new.fetch_source('test', :view_path => tmp_path.to_s),
|
24
|
+
TestPartial.new.fetch_source('test_v1', :view_path => tmp_path.to_s)]
|
25
|
+
end
|
26
|
+
|
27
|
+
asserts(:first).equals {["content\n", (tmp_path + "test.json.rabl").to_s ]}
|
28
|
+
asserts(:last).equals {["content_v1\n", (tmp_path + "test_v1.json.rabl").to_s ]}
|
29
|
+
teardown { Object.send(:remove_const, :Rails) }
|
30
|
+
end
|
31
|
+
|
32
|
+
context "fetch_source" do
|
33
|
+
helper(:tmp_path) { @tmp_path ||= Pathname.new(Dir.mktmpdir) }
|
34
|
+
|
35
|
+
setup do
|
36
|
+
::Rails = stub(Class.new)
|
37
|
+
::Rails.root.returns(tmp_path)
|
38
|
+
File.open(tmp_path + "test.rabl", "w") do |f|
|
39
|
+
f.puts "content"
|
40
|
+
end
|
41
|
+
TestPartial.new.fetch_source('test', :view_path => tmp_path.to_s)
|
42
|
+
end
|
43
|
+
asserts('detects file.rabl') { topic }.equals do
|
44
|
+
["content\n", (tmp_path + 'test.rabl').to_s]
|
45
|
+
end
|
46
|
+
teardown { Object.send(:remove_const, :Rails) }
|
47
|
+
end
|
48
|
+
|
49
|
+
context "fetch_source" do
|
50
|
+
helper(:tmp_path) { @tmp_path ||= Pathname.new(Dir.mktmpdir) }
|
51
|
+
|
52
|
+
setup do
|
53
|
+
::Rails = stub(Class.new)
|
54
|
+
::Rails.root.returns(tmp_path)
|
55
|
+
File.open(tmp_path + "test.rabl", "w") do |f|
|
56
|
+
f.puts "content"
|
57
|
+
end
|
58
|
+
File.open(tmp_path + "test.json.rabl", "w") do |f|
|
59
|
+
f.puts "content2"
|
60
|
+
end
|
61
|
+
TestPartial.new.fetch_source('test', :view_path => tmp_path.to_s)
|
62
|
+
end
|
63
|
+
asserts('detects file.json.rabl first') { topic }.equals do
|
64
|
+
["content2\n", (tmp_path + 'test.json.rabl').to_s]
|
65
|
+
end
|
66
|
+
teardown { Object.send(:remove_const, :Rails) }
|
67
|
+
end
|
68
|
+
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: rabl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease: 6
|
5
|
-
version: 0.5.5.
|
5
|
+
version: 0.5.5.c
|
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: 2012-02-
|
13
|
+
date: 2012-02-11 00:00:00 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: multi_json
|
@@ -245,6 +245,7 @@ files:
|
|
245
245
|
- lib/rabl/configuration.rb
|
246
246
|
- lib/rabl/engine.rb
|
247
247
|
- lib/rabl/helpers.rb
|
248
|
+
- lib/rabl/partials.rb
|
248
249
|
- lib/rabl/railtie.rb
|
249
250
|
- lib/rabl/template.rb
|
250
251
|
- lib/rabl/version.rb
|
@@ -260,6 +261,7 @@ files:
|
|
260
261
|
- test/models/ormless.rb
|
261
262
|
- test/models/user.rb
|
262
263
|
- test/msgpack_engine_test.rb
|
264
|
+
- test/partials_test.rb
|
263
265
|
- test/silence.rb
|
264
266
|
- test/template_test.rb
|
265
267
|
- test/teststrap.rb
|
@@ -286,7 +288,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
286
288
|
requirements: []
|
287
289
|
|
288
290
|
rubyforge_project: rabl
|
289
|
-
rubygems_version: 1.8.
|
291
|
+
rubygems_version: 1.8.15
|
290
292
|
signing_key:
|
291
293
|
specification_version: 3
|
292
294
|
summary: General ruby templating for json or xml
|
@@ -301,6 +303,7 @@ test_files:
|
|
301
303
|
- test/models/ormless.rb
|
302
304
|
- test/models/user.rb
|
303
305
|
- test/msgpack_engine_test.rb
|
306
|
+
- test/partials_test.rb
|
304
307
|
- test/silence.rb
|
305
308
|
- test/template_test.rb
|
306
309
|
- test/teststrap.rb
|