rabl 0.5.5.b → 0.5.5.c
Sign up to get free protection for your applications and to get access to all the features.
- 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
|