rabl 0.11.1 → 0.11.2
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.
- checksums.yaml +8 -8
- data/CHANGELOG.md +4 -0
- data/README.md +7 -1
- data/lib/rabl.rb +5 -7
- data/lib/rabl/builder.rb +209 -215
- data/lib/rabl/cache_engine.rb +1 -1
- data/lib/rabl/configuration.rb +1 -1
- data/lib/rabl/engine.rb +242 -210
- data/lib/rabl/helpers.rb +39 -8
- data/lib/rabl/multi_builder.rb +24 -14
- data/lib/rabl/partials.rb +10 -105
- data/lib/rabl/railtie.rb +0 -2
- data/lib/rabl/renderer.rb +52 -42
- data/lib/rabl/sources.rb +87 -0
- data/lib/rabl/template.rb +2 -2
- data/lib/rabl/version.rb +1 -1
- data/test/builder_test.rb +59 -69
- data/test/engine_test.rb +4 -3
- data/test/models/user.rb +1 -1
- data/test/multi_builder_test.rb +1 -2
- metadata +3 -2
data/lib/rabl/helpers.rb
CHANGED
@@ -10,8 +10,9 @@ module Rabl
|
|
10
10
|
# data_object(@user => :person) => @user
|
11
11
|
# data_object(:user => :person) => @_object.send(:user)
|
12
12
|
def data_object(data)
|
13
|
-
data =
|
14
|
-
data.is_a?(Symbol) && defined?(@_object) && @_object && @_object.respond_to?(data)
|
13
|
+
data = data.keys.first if data.is_a?(Hash) && data.keys.size == 1
|
14
|
+
data = @_object.__send__(data) if data.is_a?(Symbol) && defined?(@_object) && @_object && @_object.respond_to?(data)
|
15
|
+
data
|
15
16
|
end
|
16
17
|
|
17
18
|
# data_object_attribute(data) => @_object.send(data)
|
@@ -28,14 +29,19 @@ module Rabl
|
|
28
29
|
# data_name([]) => "array"
|
29
30
|
def data_name(data_token)
|
30
31
|
return unless data_token # nil or false
|
32
|
+
|
31
33
|
return data_token.values.first if data_token.is_a?(Hash) # @user => :user
|
34
|
+
|
32
35
|
data = data_object(data_token)
|
36
|
+
|
33
37
|
if is_collection?(data) # data is a collection
|
34
38
|
object_name = data.table_name if data.respond_to?(:table_name)
|
39
|
+
|
35
40
|
if object_name.nil? && data.respond_to?(:first)
|
36
41
|
first = data.first
|
37
42
|
object_name = data_name(first).to_s.pluralize if first.present?
|
38
43
|
end
|
44
|
+
|
39
45
|
object_name ||= data_token if data_token.is_a?(Symbol)
|
40
46
|
object_name
|
41
47
|
elsif is_object?(data) # data is an object
|
@@ -54,8 +60,9 @@ module Rabl
|
|
54
60
|
# determine_object_root(@user, :user, true) => "user"
|
55
61
|
# determine_object_root(@user, :person) => "person"
|
56
62
|
# determine_object_root([@user, @user]) => "user"
|
57
|
-
def determine_object_root(data_token, data_name=nil, include_root=true)
|
63
|
+
def determine_object_root(data_token, data_name = nil, include_root = true)
|
58
64
|
return if object_root_name == false
|
65
|
+
|
59
66
|
root_name = data_name.to_s if include_root
|
60
67
|
if is_object?(data_token) || data_token.nil?
|
61
68
|
root_name
|
@@ -78,13 +85,17 @@ module Rabl
|
|
78
85
|
def is_collection?(obj, follow_symbols = true)
|
79
86
|
data_obj = follow_symbols ? data_object(obj) : obj
|
80
87
|
data_obj && data_obj.respond_to?(:map) && data_obj.respond_to?(:each) &&
|
81
|
-
obj.class.ancestors.none? { |a| KNOWN_OBJECT_CLASSES.include?
|
88
|
+
obj.class.ancestors.none? { |a| KNOWN_OBJECT_CLASSES.include?(a.name) }
|
82
89
|
end
|
83
90
|
|
84
|
-
# Returns the
|
91
|
+
# Returns the context_scope wrapping this engine, used for retrieving data, invoking methods, etc
|
85
92
|
# In Rails, this is the controller and in Padrino this is the request context
|
86
93
|
def context_scope
|
87
|
-
defined?(@
|
94
|
+
defined?(@_context_scope) ? @_context_scope : nil
|
95
|
+
end
|
96
|
+
|
97
|
+
def view_path
|
98
|
+
defined?(@_view_path) ? @_view_path : nil
|
88
99
|
end
|
89
100
|
|
90
101
|
# Returns the root (if any) name for an object within a collection
|
@@ -106,14 +117,34 @@ module Rabl
|
|
106
117
|
val.is_a?(String) || val.is_a?(Symbol)
|
107
118
|
end
|
108
119
|
|
120
|
+
# Returns an Engine based representation of any data object given ejs template block
|
121
|
+
# object_to_hash(@user) { attribute :full_name } => { ... }
|
122
|
+
# object_to_hash(@user, :source => "...") { attribute :full_name } => { ... }
|
123
|
+
# object_to_hash([@user], :source => "...") { attribute :full_name } => { ... }
|
124
|
+
# options must have :source (rabl file contents)
|
125
|
+
# options can have :source_location (source filename)
|
126
|
+
def object_to_engine(object, options = {}, &block)
|
127
|
+
return if object.nil?
|
128
|
+
|
129
|
+
return [] if is_collection?(object) && object.blank? # empty collection
|
130
|
+
|
131
|
+
options = {
|
132
|
+
:format => "hash",
|
133
|
+
:view_path => view_path,
|
134
|
+
:root => (options[:root] || false)
|
135
|
+
}.merge(options)
|
136
|
+
|
137
|
+
Engine.new(options[:source], options).apply(context_scope, :object => object, :locals => options[:locals], &block)
|
138
|
+
end
|
139
|
+
|
109
140
|
# Fetches a key from the cache and stores rabl template result otherwise
|
110
141
|
# fetch_from_cache('some_key') { ...rabl template result... }
|
111
|
-
def fetch_result_from_cache(cache_key, cache_options=nil, &block)
|
142
|
+
def fetch_result_from_cache(cache_key, cache_options = nil, &block)
|
112
143
|
expanded_cache_key = ActiveSupport::Cache.expand_cache_key(cache_key, :rabl)
|
113
144
|
Rabl.configuration.cache_engine.fetch(expanded_cache_key, cache_options, &block)
|
114
145
|
end
|
115
146
|
|
116
|
-
def write_result_to_cache(cache_key, cache_options=nil, &block)
|
147
|
+
def write_result_to_cache(cache_key, cache_options = nil, &block)
|
117
148
|
expanded_cache_key = ActiveSupport::Cache.expand_cache_key(cache_key, :rabl)
|
118
149
|
result = yield
|
119
150
|
Rabl.configuration.cache_engine.write(expanded_cache_key, result, cache_options)
|
data/lib/rabl/multi_builder.rb
CHANGED
@@ -1,23 +1,32 @@
|
|
1
1
|
module Rabl
|
2
2
|
class MultiBuilder
|
3
|
+
include Helpers
|
4
|
+
|
3
5
|
# Constructs a new MultiBuilder given the data and options.
|
4
6
|
# The options will be re-used for all Rabl::Builders.
|
5
7
|
# Rabl::MultiBuilder.new([#<User ...>, #<User ...>, ...], { :format => 'json', :child_root => true })
|
6
|
-
def initialize(data, options={})
|
7
|
-
@data
|
8
|
-
@
|
9
|
-
@
|
10
|
-
@
|
11
|
-
@
|
8
|
+
def initialize(data, settings = {}, options = {})
|
9
|
+
@data = data
|
10
|
+
@settings = settings
|
11
|
+
@options = options
|
12
|
+
@builders = []
|
13
|
+
@engine_to_builder = {}
|
14
|
+
@cache_key_to_engine = {}
|
12
15
|
end
|
13
16
|
|
14
17
|
# Returns the result of all of the builders as an array
|
15
18
|
def to_a
|
16
19
|
generate_builders
|
17
|
-
read_cache_results
|
18
|
-
replace_engines_with_cache_results
|
19
20
|
|
20
|
-
|
21
|
+
if template_cache_configured? && Rabl.configuration.use_read_multi
|
22
|
+
map_engines_to_builders
|
23
|
+
read_cache_results
|
24
|
+
replace_engines_with_cache_results
|
25
|
+
end
|
26
|
+
|
27
|
+
result = @builders.map(&:to_hash)
|
28
|
+
result = result.map(&:presence).compact if Rabl.configuration.exclude_empty_values_in_collections
|
29
|
+
result
|
21
30
|
end
|
22
31
|
|
23
32
|
private
|
@@ -26,12 +35,13 @@ module Rabl
|
|
26
35
|
# and maps the cache keys for each of the engines
|
27
36
|
# the builders generated
|
28
37
|
def generate_builders
|
29
|
-
@data.
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
@builders << builder
|
38
|
+
@builders = @data.map do |object|
|
39
|
+
Builder.new(object, @settings, @options)
|
40
|
+
end
|
41
|
+
end
|
34
42
|
|
43
|
+
def map_engines_to_builders
|
44
|
+
@builders.each do |builder|
|
35
45
|
builder.engines.each do |engine|
|
36
46
|
@engine_to_builder[engine] = builder
|
37
47
|
|
data/lib/rabl/partials.rb
CHANGED
@@ -1,113 +1,18 @@
|
|
1
1
|
module Rabl
|
2
2
|
module Partials
|
3
|
-
include
|
3
|
+
include Helpers
|
4
|
+
include Sources
|
4
5
|
|
5
|
-
|
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
|
-
engine = self.partial_as_engine(file, options, &block)
|
11
|
-
engine.is_a?(Rabl::Engine) ? engine.render : engine
|
12
|
-
end
|
13
|
-
|
14
|
-
def partial_as_engine(file, options={}, &block)
|
6
|
+
def partial_as_engine(file, options = {}, &block)
|
15
7
|
raise ArgumentError, "Must provide an :object option to render a partial" unless options.has_key?(:object)
|
16
|
-
object, view_path = options.delete(:object), options[:view_path] || @_view_path
|
17
|
-
source, location = self.fetch_source(file, :view_path => view_path)
|
18
|
-
engine_options = options.merge(:source => source, :source_location => location, :template => file)
|
19
|
-
self.object_to_engine(object, engine_options, &block)
|
20
|
-
end
|
21
|
-
|
22
|
-
# Returns an Engine based representation of any data object given ejs template block
|
23
|
-
# object_to_hash(@user) { attribute :full_name } => { ... }
|
24
|
-
# object_to_hash(@user, :source => "...") { attribute :full_name } => { ... }
|
25
|
-
# object_to_hash([@user], :source => "...") { attribute :full_name } => { ... }
|
26
|
-
# options must have :source (rabl file contents)
|
27
|
-
# options can have :source_location (source filename)
|
28
|
-
def object_to_engine(object, options={}, &block)
|
29
|
-
return object unless !object.nil?
|
30
|
-
return [] if is_collection?(object) && object.blank? # empty collection
|
31
|
-
engine_options = options.reverse_merge(:format => "hash", :view_path => @_view_path, :root => (options[:root] || false))
|
32
|
-
Rabl::Engine.new(options[:source], engine_options).apply(@_scope, :object => object, :locals => options[:locals], &block)
|
33
|
-
end
|
34
8
|
|
35
|
-
|
36
|
-
|
37
|
-
def fetch_source(file, options={})
|
38
|
-
view_paths = Array(options[:view_path]) + Array(Rabl.configuration.view_paths)
|
39
|
-
Rabl.source_cache(file, view_paths) do
|
40
|
-
file_path = if defined?(Padrino) && context_scope.respond_to?(:settings) && context_scope.respond_to?(:resolve_template)
|
41
|
-
fetch_padrino_source(file, options)
|
42
|
-
elsif defined?(Rails) && context_scope.respond_to?(:view_paths)
|
43
|
-
_view_paths = view_paths + Array(context_scope.view_paths.to_a)
|
44
|
-
fetch_rails_source(file, options) || fetch_manual_template(_view_paths, file)
|
45
|
-
elsif defined?(Sinatra) && context_scope.respond_to?(:settings)
|
46
|
-
fetch_sinatra_source(file, options)
|
47
|
-
else # generic template resolution
|
48
|
-
fetch_manual_template(view_paths, file)
|
49
|
-
end
|
9
|
+
object = options.delete(:object)
|
10
|
+
view_path = options[:view_path] || view_path
|
50
11
|
|
51
|
-
|
52
|
-
raise "Cannot find rabl template '#{file}' within registered (#{view_paths.map(&:to_s).inspect}) view paths!"
|
53
|
-
end
|
12
|
+
source, location = fetch_source(file, :view_path => view_path)
|
54
13
|
|
55
|
-
|
56
|
-
|
14
|
+
options = options.merge(:source => source, :source_location => location, :template => file)
|
15
|
+
object_to_engine(object, options, &block)
|
57
16
|
end
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
# Returns the rabl template path for padrino views using configured views
|
62
|
-
def fetch_padrino_source(file, options={})
|
63
|
-
view_path = Array(options[:view_path] || context_scope.settings.views)
|
64
|
-
# use Padrino's own template resolution mechanism
|
65
|
-
file_path, _ = context_scope.instance_eval { resolve_template(file) }
|
66
|
-
# Padrino chops the extension, stitch it back on
|
67
|
-
File.join(view_path.first.to_s, (file_path.to_s + ".rabl"))
|
68
|
-
end
|
69
|
-
|
70
|
-
# Returns the rabl template path for Rails, including special lookups for Rails 2 and 3
|
71
|
-
def fetch_rails_source(file, options={})
|
72
|
-
# use Rails template resolution mechanism if possible (find_template)
|
73
|
-
source_format = request_format if defined?(request_format)
|
74
|
-
if source_format && context_scope.respond_to?(:lookup_context) # Rails 3
|
75
|
-
lookup_proc = lambda { |partial|
|
76
|
-
if ActionPack::VERSION::MAJOR == 3 && ActionPack::VERSION::MINOR < 2
|
77
|
-
context_scope.lookup_context.find(file, [], partial)
|
78
|
-
else # Rails 3.2 and higher
|
79
|
-
# pull format directly from rails unless it is html
|
80
|
-
request_format = context_scope.request.format.to_sym
|
81
|
-
source_format = request_format unless request_format == :html
|
82
|
-
context_scope.lookup_context.find(file, [], partial, [], {:formats => [source_format]})
|
83
|
-
end }
|
84
|
-
template = lookup_proc.call(false) rescue nil
|
85
|
-
template ||= lookup_proc.call(true) rescue nil
|
86
|
-
template.identifier if template
|
87
|
-
elsif source_format && context_scope.respond_to?(:view_paths) # Rails 2
|
88
|
-
template = context_scope.view_paths.find_template(file, source_format, false)
|
89
|
-
template.filename if template
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
# Returns the rabl template path for sinatra views using configured views
|
94
|
-
def fetch_sinatra_source(file, options={})
|
95
|
-
view_path = Array(options[:view_path] || context_scope.settings.views)
|
96
|
-
fetch_manual_template(view_path, file)
|
97
|
-
end
|
98
|
-
|
99
|
-
# Returns the rabl template by looking up files within the view_path and specified file path
|
100
|
-
def fetch_manual_template(view_path, file)
|
101
|
-
Dir[File.join("{#{view_path.join(",")}}", "{#{file},#{partialized(file)}}" + ".{*.,}rabl")].first
|
102
|
-
end
|
103
|
-
|
104
|
-
# Returns a partialized version of a file path
|
105
|
-
# partialized("v1/variants/variant") => "v1/variants/_variant"
|
106
|
-
def partialized(file)
|
107
|
-
partial_file = file.split(File::SEPARATOR)
|
108
|
-
partial_file[-1] = "_#{partial_file[-1]}" unless partial_file[-1].start_with?("_")
|
109
|
-
partial_file.join(File::SEPARATOR)
|
110
|
-
end
|
111
|
-
|
112
|
-
end # Partials
|
113
|
-
end # Rabl
|
17
|
+
end
|
18
|
+
end
|
data/lib/rabl/railtie.rb
CHANGED
data/lib/rabl/renderer.rb
CHANGED
@@ -11,6 +11,8 @@ module Rabl
|
|
11
11
|
CODE
|
12
12
|
end
|
13
13
|
|
14
|
+
attr_reader :object, :options
|
15
|
+
|
14
16
|
# Public: Instantiate a new renderer
|
15
17
|
# This is a standalone class used for rendering rabl templates
|
16
18
|
# outside of a framework like Rails. You may want to use
|
@@ -21,69 +23,77 @@ module Rabl
|
|
21
23
|
# renderer = Rabl::Renderer.new('template_name', user, { :format => 'json', :view_path => 'app/views' })
|
22
24
|
# renderer.render # => '{"user":{"name": "ivan" }}'
|
23
25
|
#
|
24
|
-
attr_reader :object, :options
|
25
26
|
def initialize(source, object = nil, options = {})
|
26
27
|
options = {
|
27
|
-
:format
|
28
|
-
:scope
|
29
|
-
:view_path
|
30
|
-
:template
|
31
|
-
}.
|
28
|
+
:format => :json,
|
29
|
+
:scope => self,
|
30
|
+
:view_path => [],
|
31
|
+
:template => source
|
32
|
+
}.merge(options)
|
32
33
|
|
33
|
-
@options
|
34
|
-
@object
|
34
|
+
@options = options
|
35
|
+
@object = object
|
35
36
|
|
36
|
-
engine.source =
|
37
|
+
engine.source = process_source(source)
|
37
38
|
end
|
38
39
|
|
39
40
|
# Public: Actually render the template to the requested output format.
|
40
41
|
#
|
41
42
|
# - context_scope:
|
42
|
-
# Override the render
|
43
|
+
# Override the render context_scope to the 'context_scope' object. Defaults to self.
|
43
44
|
#
|
44
45
|
# Returns: And object representing the tranformed object in the requested format.
|
45
46
|
# e.g. json, xml, bson, plist
|
46
47
|
def render(context_scope = nil)
|
47
|
-
context_scope
|
48
|
-
|
49
|
-
|
48
|
+
context_scope ||= options[:scope] || self
|
49
|
+
|
50
|
+
set_object_instance_variable if context_scope == self
|
51
|
+
|
52
|
+
locals = { :object => object }.merge(options.fetch(:locals, {}))
|
53
|
+
|
50
54
|
engine.apply(context_scope, locals).render
|
51
55
|
end
|
52
56
|
|
53
57
|
protected
|
58
|
+
def engine
|
59
|
+
@engine ||= Rabl::Engine.new(nil, options)
|
60
|
+
end
|
54
61
|
|
55
|
-
|
56
|
-
|
57
|
-
|
62
|
+
# Returns the source given a relative template path
|
63
|
+
def process_source(source)
|
64
|
+
return source if source.is_a?(String) && source =~ /\n/
|
58
65
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
source, _ = engine.fetch_source(source, { :view_path => options[:view_path] })
|
63
|
-
source
|
64
|
-
end
|
66
|
+
source, _ = engine.fetch_source(source, { :view_path => options[:view_path] })
|
67
|
+
source
|
68
|
+
end
|
65
69
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
end
|
70
|
+
# Internal: Sets an instance variable named after the class of `object`
|
71
|
+
#
|
72
|
+
# Example:
|
73
|
+
# object.class.name # => User
|
74
|
+
# set_object_instance_variable # => @user == object
|
75
|
+
#
|
76
|
+
def set_object_instance_variable
|
77
|
+
instance_variable_set(:"@#{object_model_name}", object)
|
78
|
+
end
|
76
79
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
80
|
+
# Internal: Returns the model name for an object
|
81
|
+
#
|
82
|
+
# Example:
|
83
|
+
# object.class.name # => User
|
84
|
+
# object_model_name => "user"
|
85
|
+
#
|
86
|
+
def object_model_name
|
87
|
+
item = object
|
88
|
+
|
89
|
+
is_collection = item.is_a?(Array)
|
90
|
+
item = item.first if is_collection
|
91
|
+
|
92
|
+
name = item.class.name.underscore
|
87
93
|
|
94
|
+
name = name.pluralize if is_collection
|
95
|
+
|
96
|
+
name.split("/").last
|
97
|
+
end
|
88
98
|
end
|
89
99
|
end
|
data/lib/rabl/sources.rb
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
module Rabl
|
2
|
+
module Sources
|
3
|
+
include Helpers
|
4
|
+
|
5
|
+
# Returns source for a given relative file
|
6
|
+
# fetch_source("show", :view_path => "...") => "...contents..."
|
7
|
+
def fetch_source(file, options = {})
|
8
|
+
view_paths = Array(options[:view_path]) + Array(Rabl.configuration.view_paths)
|
9
|
+
|
10
|
+
Rabl.source_cache(file, view_paths) do
|
11
|
+
file_path = \
|
12
|
+
if defined?(Padrino) && context_scope.respond_to?(:settings) && context_scope.respond_to?(:resolve_template)
|
13
|
+
fetch_padrino_source(file, options)
|
14
|
+
elsif defined?(Rails) && context_scope.respond_to?(:view_paths)
|
15
|
+
_view_paths = view_paths + Array(context_scope.view_paths.to_a)
|
16
|
+
fetch_rails_source(file, options) || fetch_manual_template(_view_paths, file)
|
17
|
+
elsif defined?(Sinatra) && context_scope.respond_to?(:settings)
|
18
|
+
fetch_sinatra_source(file, options)
|
19
|
+
else # generic template resolution
|
20
|
+
fetch_manual_template(view_paths, file)
|
21
|
+
end
|
22
|
+
|
23
|
+
unless File.exist?(file_path.to_s)
|
24
|
+
raise "Cannot find rabl template '#{file}' within registered (#{view_paths.map(&:to_s).inspect}) view paths!"
|
25
|
+
end
|
26
|
+
|
27
|
+
[File.read(file_path.to_s), file_path.to_s]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
# Returns the rabl template path for padrino views using configured views
|
33
|
+
def fetch_padrino_source(file, options = {})
|
34
|
+
view_path = Array(options[:view_path] || context_scope.settings.views)
|
35
|
+
|
36
|
+
# use Padrino's own template resolution mechanism
|
37
|
+
file_path, _ = context_scope.instance_eval { resolve_template(file) }
|
38
|
+
|
39
|
+
# Padrino chops the extension, stitch it back on
|
40
|
+
File.join(view_path.first.to_s, (file_path.to_s + ".rabl"))
|
41
|
+
end
|
42
|
+
|
43
|
+
# Returns the rabl template path for Rails, including special lookups for Rails 2 and 3
|
44
|
+
def fetch_rails_source(file, options = {})
|
45
|
+
# use Rails template resolution mechanism if possible (find_template)
|
46
|
+
source_format = request_format if defined?(request_format)
|
47
|
+
|
48
|
+
if source_format && context_scope.respond_to?(:lookup_context) # Rails 3
|
49
|
+
lookup_proc = lambda do |partial|
|
50
|
+
if ActionPack::VERSION::MAJOR == 3 && ActionPack::VERSION::MINOR < 2
|
51
|
+
context_scope.lookup_context.find(file, [], partial)
|
52
|
+
else # Rails 3.2 and higher
|
53
|
+
# pull format directly from rails unless it is html
|
54
|
+
request_format = context_scope.request.format.to_sym
|
55
|
+
source_format = request_format unless request_format == :html
|
56
|
+
context_scope.lookup_context.find(file, [], partial, [], { :formats => [source_format] })
|
57
|
+
end
|
58
|
+
end
|
59
|
+
template = lookup_proc.call(false) rescue nil
|
60
|
+
template ||= lookup_proc.call(true) rescue nil
|
61
|
+
template.identifier if template
|
62
|
+
elsif source_format && context_scope.respond_to?(:view_paths) # Rails 2
|
63
|
+
template = context_scope.view_paths.find_template(file, source_format, false)
|
64
|
+
template.filename if template
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# Returns the rabl template path for sinatra views using configured views
|
69
|
+
def fetch_sinatra_source(file, options = {})
|
70
|
+
view_path = Array(options[:view_path] || context_scope.settings.views)
|
71
|
+
fetch_manual_template(view_path, file)
|
72
|
+
end
|
73
|
+
|
74
|
+
# Returns the rabl template by looking up files within the view_path and specified file path
|
75
|
+
def fetch_manual_template(view_path, file)
|
76
|
+
Dir[File.join("{#{view_path.join(",")}}", "{#{file},#{partialized(file)}}" + ".{*.,}rabl")].first
|
77
|
+
end
|
78
|
+
|
79
|
+
# Returns a partialized version of a file path
|
80
|
+
# partialized("v1/variants/variant") => "v1/variants/_variant"
|
81
|
+
def partialized(file)
|
82
|
+
partial_file = file.split(File::SEPARATOR)
|
83
|
+
partial_file[-1] = "_#{partial_file[-1]}" unless partial_file[-1].start_with?("_")
|
84
|
+
partial_file.join(File::SEPARATOR)
|
85
|
+
end
|
86
|
+
end # Partials
|
87
|
+
end # Rabl
|