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