Class: Jets::Controller::Rendering::RackRenderer
- Inherits:
-
Object
- Object
- Jets::Controller::Rendering::RackRenderer
- Defined in:
- lib/jets/controller/rendering/rack_renderer.rb
Instance Attribute Summary collapse
-
#controller ⇒ Object
readonly
Returns the value of attribute controller.
Class Method Summary collapse
-
.find_app_helper_classes ⇒ Object
Does not include ApplicationHelper, will include ApplicationHelper explicitly first.
- .find_app_helper_classes_from(project_root) ⇒ Object
- .setup! ⇒ Object
- .setup_webpacker ⇒ Object
Instance Method Summary collapse
- #clear_view_cache ⇒ Object
-
#controller_instance_variables ⇒ Object
Pass controller instance variables from jets-based controller to ActionView scope.
-
#default_template_name ⇒ Object
Example: posts/index.
-
#initialize(controller, options = {}) ⇒ RackRenderer
constructor
A new instance of RackRenderer.
-
#rackify_headers(headers) ⇒ Object
Takes headers and adds HTTP_ to front of the keys because that is what rack does to the headers passed from a request.
-
#render ⇒ Object
Example response:.
- #render_options ⇒ Object
- #renderer_options ⇒ Object
-
#template_namespace ⇒ Object
PostsController => “posts” is the namespace.
Constructor Details
#initialize(controller, options = {}) ⇒ RackRenderer
Returns a new instance of RackRenderer.
8 9 10 11 |
# File 'lib/jets/controller/rendering/rack_renderer.rb', line 8 def initialize(controller, ={}) @controller = controller @options = end |
Instance Attribute Details
#controller ⇒ Object (readonly)
Returns the value of attribute controller.
7 8 9 |
# File 'lib/jets/controller/rendering/rack_renderer.rb', line 7 def controller @controller end |
Class Method Details
.find_app_helper_classes ⇒ Object
Does not include ApplicationHelper, will include ApplicationHelper explicitly first.
232 233 234 235 236 237 |
# File 'lib/jets/controller/rendering/rack_renderer.rb', line 232 def find_app_helper_classes internal_path = File.("../../internal", File.dirname(__FILE__)) internal_classes = find_app_helper_classes_from(internal_path) app_classes = find_app_helper_classes_from(Jets.root) (internal_classes + app_classes).uniq end |
.find_app_helper_classes_from(project_root) ⇒ Object
239 240 241 242 243 244 245 246 247 248 249 250 251 |
# File 'lib/jets/controller/rendering/rack_renderer.rb', line 239 def find_app_helper_classes_from(project_root) klasses = [] expression = "#{project_root}/app/helpers/**/*" Dir.glob(expression).each do |path| next unless File.file?(path) class_name = path.sub("#{project_root}/app/helpers/","").sub(/\.rb/,'') unless class_name == "application_helper" klasses << class_name.camelize.constantize # autoload end end klasses end |
.setup! ⇒ Object
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 |
# File 'lib/jets/controller/rendering/rack_renderer.rb', line 211 def setup! require "action_controller" require "jets/overrides/rails" # Load helpers # Assign local variable because scope in the `:action_view do` block changes app_helper_classes = find_app_helper_classes ActiveSupport.on_load :action_view do include Jets::Router::Helpers # internal routes helpers include ApplicationHelper # include first app_helper_classes.each do |helper_class| include helper_class end end ActionController::Base.append_view_path("#{Jets.root}/app/views") setup_webpacker if Jets.webpacker? end |
.setup_webpacker ⇒ Object
253 254 255 256 257 258 259 260 261 262 263 264 |
# File 'lib/jets/controller/rendering/rack_renderer.rb', line 253 def setup_webpacker require 'webpacker' require 'webpacker/helper' ActiveSupport.on_load :action_controller do ActionController::Base.helper Webpacker::Helper end ActiveSupport.on_load :action_view do include Webpacker::Helper end end |
Instance Method Details
#clear_view_cache ⇒ Object
160 161 162 |
# File 'lib/jets/controller/rendering/rack_renderer.rb', line 160 def clear_view_cache ActionView::LookupContext::DetailsKey.clear if Jets.env.development? end |
#controller_instance_variables ⇒ Object
Pass controller instance variables from jets-based controller to ActionView scope
147 148 149 150 151 152 153 154 155 156 157 158 |
# File 'lib/jets/controller/rendering/rack_renderer.rb', line 147 def controller_instance_variables instance_vars = @controller.instance_variables.inject({}) do |vars, v| k = v.to_s.sub(/^@/,'') # @var => var vars[k] = @controller.instance_variable_get(v) vars end instance_vars[:event] = event # jets internal variables # So ActionView has access back to the jets controller instance_vars[:_jets] = { controller: @controller } instance_vars end |
#default_template_name ⇒ Object
Example: posts/index
101 102 103 |
# File 'lib/jets/controller/rendering/rack_renderer.rb', line 101 def default_template_name "#{template_namespace}/#{@controller.meth}" end |
#rackify_headers(headers) ⇒ Object
Takes headers and adds HTTP_ to front of the keys because that is what rack does to the headers passed from a request. This seems to be the standard when testing with curl and inspecting the headers in a Rack app. Example: gist.github.com/tongueroo/94f22f6c261c8999e4f4f776547e2ee3
This is useful for:
ActionController::Base.renderer.new()
renderer_options are rack normalized headers.
Example input (from api gateway)
{"host"=>"localhost:8888",
"user-agent"=>"curl/7.53.1",
"accept"=>"*/*",
"version"=>"HTTP/1.1",
"x-amzn-trace-id"=>"Root=1-5bde5b19-61d0d4ab4659144f8f69e38f"}
Example output:
{"HTTP_HOST"=>"localhost:8888",
"HTTP_USER_AGENT"=>"curl/7.53.1",
"HTTP_ACCEPT"=>"*/*",
"HTTP_VERSION"=>"HTTP/1.1",
"HTTP_X_AMZN_TRACE_ID"=>"Root=1-5bde5b19-61d0d4ab4659144f8f69e38f"}
137 138 139 140 141 142 143 144 |
# File 'lib/jets/controller/rendering/rack_renderer.rb', line 137 def rackify_headers(headers) results = {} headers.each do |k,v| rack_key = 'HTTP_' + k.gsub('-','_').upcase results[rack_key] = v end results end |
#render ⇒ Object
Example response:
[200, {"my-header" = > "value" }, "my body" ]
Returns rack triplet
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 |
# File 'lib/jets/controller/rendering/rack_renderer.rb', line 18 def render # we do some normalization here status = normalize_status_code(@options[:status]) base64 = normalized_base64_option(@options) headers = @options[:headers] || {} set_content_type!(status, headers) # x-jets-base64 to convert this Rack triplet to a API Gateway hash structure later headers["x-jets-base64"] = base64 ? 'yes' : 'no' # headers values must be Strings if drop_content_info?(status) body = StringIO.new else # Rails rendering does heavy lifting # _prefixes provided by jets/overrides/rails/action_controller.rb ActionController::Base._prefixes = @controller.controller_paths renderer = ActionController::Base.renderer.new() clear_view_cache body = renderer.render() body = StringIO.new(body) end [status, headers, body] # triplet end |
#render_options ⇒ Object
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/jets/controller/rendering/rack_renderer.rb', line 75 def # normalize the template option template = @options[:template] if template and !template.include?('/') template = "#{template_namespace}/#{template}" end template ||= default_template_name # ready to override @options[:template] @options[:template] = template if @options[:template] = { template: template, # weird: template needs to be set no matter because it # sets the name which is used in lookup_context.rb:209:in `normalize_name' layout: @options[:layout], assigns: controller_instance_variables, # prefixes: ["posts"], } types = %w[json inline plain file xml body action].map(&:to_sym) types.each do |type| [type] = @options[type] if @options[type] end end |
#renderer_options ⇒ Object
default options:
https://github.com/rails/rails/blob/master/actionpack/lib/action_controller/renderer.rb#L41-L47
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 |
# File 'lib/jets/controller/rendering/rack_renderer.rb', line 46 def = { # script_name: "", # unfortunately doesnt seem to effect relative_url_root like desired # input: "" } origin = headers["origin"] if origin uri = URI.parse(origin) [:https] = uri.scheme == "https" end # Important to not use rack_headers as local variable instead of headers. # headers is a method that gets deleted to controller.headers and using it # seems to cause issues. rack_headers = rackify_headers(headers) .merge!(rack_headers) # Note @options[:method] uses @options vs options on purpose @options[:method] = event["httpMethod"].downcase if event["httpMethod"] # This is how we pass parameters to actionpack. IE: params to the view. # This is because renderer_options is actually the env that is passed to the rack request. .merge!("action_dispatch.request.path_parameters" => @controller.path_parameters) .merge!("action_dispatch.request.query_parameters" => @controller.query_parameters) .merge!("action_dispatch.request.request_parameters" => @controller.request_parameters) end |
#template_namespace ⇒ Object
PostsController => “posts” is the namespace
106 107 108 |
# File 'lib/jets/controller/rendering/rack_renderer.rb', line 106 def template_namespace @controller.class.to_s.sub('Controller','').underscore end |