-
Notifications
You must be signed in to change notification settings - Fork 27
/
Copy pathformatter.rb
100 lines (84 loc) · 2.73 KB
/
formatter.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
require 'json'
module Grape
module Rabl
class Formatter
class << self
def tilt_cache
@tilt_cache ||= ::Tilt::Cache.new
end
end
attr_reader :env, :endpoint, :object
def initialize(object, env)
@env = env
@endpoint = env['api.endpoint']
@object = object
end
def render
if rablable?
rabl do |template|
engine = tilt_template(template)
output = engine.render endpoint, locals
if layout_template
layout_template.render(endpoint) { output }
else
output
end
end
else
fallback_formatter.call object, env
end
end
private
# Find a formatter to fallback to. `env[Grape::Env::API_FORMAT]` will always be a
# valid formatter, otherwise a HTTP 406 error would have already have been thrown
def fallback_formatter
Grape::Formatter.formatter_for(env[Grape::Env::API_FORMAT])
end
def view_path(template)
if template.split('.')[-1] == 'rabl'
File.join(env['api.tilt.root'], template)
else
File.join(env['api.tilt.root'], (template + '.rabl'))
end
end
def rablable?
!!rabl_template
end
def rabl
raise 'missing rabl template' unless rabl_template
set_view_root unless env['api.tilt.root']
yield rabl_template
end
def locals
env['api.tilt.rabl_locals'] || endpoint.options[:route_options][:rabl_locals] || {}
end
def rabl_template
env['api.tilt.rabl'] || endpoint.options[:route_options][:rabl]
end
def set_view_root
raise "Use Rack::Config to set 'api.tilt.root' in config.ru"
end
def tilt_template(template)
if Grape::Rabl.configuration.cache_template_loading
Grape::Rabl::Formatter.tilt_cache.fetch(tilt_cache_key(template)) { ::Tilt.new(view_path(template), tilt_options) }
else
::Tilt.new(view_path(template), tilt_options)
end
end
def tilt_options
{ format: env['api.format'], view_path: env['api.tilt.root'] }
end
def layout_template
layout_path = view_path(env['api.tilt.layout'] || 'layouts/application')
if Grape::Rabl.configuration.cache_template_loading
Grape::Rabl::Formatter.tilt_cache.fetch(tilt_cache_key(layout_path)) { ::Tilt.new(layout_path, tilt_options) if File.exist?(layout_path) }
else
::Tilt.new(layout_path, tilt_options) if File.exist?(layout_path)
end
end
def tilt_cache_key(path)
Digest::MD5.hexdigest("#{path}#{tilt_options}")
end
end
end
end