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.
@@ -1,9 +1,10 @@
1
1
  # CHANGELOG
2
2
 
3
- ## 0.5.5.a-b
3
+ ## 0.5.5.a-c
4
4
 
5
5
  * Change engine to only instantiate one builder when rendering a collection
6
6
  * Alias to\_msgpack to to\_mpac
7
+ * Cache template sources for faster partial lookups
7
8
 
8
9
  ## 0.5.4
9
10
 
@@ -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
 
@@ -1,6 +1,6 @@
1
1
  module Rabl
2
2
  class Builder
3
- include Rabl::Helpers
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
@@ -1,6 +1,6 @@
1
1
  module Rabl
2
2
  class Engine
3
- include Rabl::Helpers
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)
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Rabl
2
- VERSION = "0.5.5.b"
2
+ VERSION = "0.5.5.c"
3
3
  end
@@ -2,67 +2,10 @@ require 'tmpdir'
2
2
  require 'pathname'
3
3
  require File.expand_path('../../lib/rabl', __FILE__)
4
4
 
5
- class TestHelper
5
+ class TestPartial
6
6
  include Rabl::Helpers
7
7
  end
8
8
 
9
9
  context "Rabl::Helpers" 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
- [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.b
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-10 00:00:00 Z
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.12
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