From 74b647af4b38bda8845c3f4f0fa1f8b011648a32 Mon Sep 17 00:00:00 2001 From: Reegan Viljoen Date: Tue, 20 Aug 2024 22:24:17 +0200 Subject: [PATCH] add controlelr implicit rendering --- lib/render_kit/engine.rb | 8 ++++++++ .../implicit_render_monkey_patch.rb | 19 +++++++++++++++++++ lib/render_kit/renderable_registry.rb | 18 +++++++++++++----- lib/render_kit/view_paths_monkey_patch.rb | 4 ++-- .../components/implicit_render_component.rb | 2 +- ...licit_controller_render_component.html.erb | 1 + ...st_implicit_controller_render_component.rb | 5 +++++ .../app/controllers/test_controller.rb | 3 +++ .../test/component_implicit_render.html.erb | 2 +- test/sandbox/config/routes.rb | 1 + .../test/view_component_compatability_test.rb | 7 +++++++ 11 files changed, 61 insertions(+), 9 deletions(-) create mode 100644 lib/render_kit/implicit_render_monkey_patch.rb create mode 100644 test/sandbox/app/components/test_implicit_controller_render_component.html.erb create mode 100644 test/sandbox/app/components/test_implicit_controller_render_component.rb diff --git a/lib/render_kit/engine.rb b/lib/render_kit/engine.rb index 6925523..4d8ffe2 100644 --- a/lib/render_kit/engine.rb +++ b/lib/render_kit/engine.rb @@ -4,6 +4,7 @@ require "render_kit/view_paths_monkey_patch" require "render_kit/rendering_helper_monkey_patch" +require "render_kit/implicit_render_monkey_patch" module RenderKit class Engine < ::Rails::Engine # :nodoc: @@ -14,5 +15,12 @@ class Engine < ::Rails::Engine # :nodoc: ActionView::Base.prepend RenderKit::RenderingHelperMonkeyPatch end end + + initializer "render_kit.action_controller" do |app| + ActiveSupport.on_load(:action_controller) do + ActionController::Base.prepend RenderKit::RenderingHelperMonkeyPatch + ActionController::Base.prepend RenderKit::ImplicitRenderMonkeyPatch + end + end end end diff --git a/lib/render_kit/implicit_render_monkey_patch.rb b/lib/render_kit/implicit_render_monkey_patch.rb new file mode 100644 index 0000000..a06a68e --- /dev/null +++ b/lib/render_kit/implicit_render_monkey_patch.rb @@ -0,0 +1,19 @@ +# frozen string literal: true + +require "active_support/concern" + +module RenderKit + module ImplicitRenderMonkeyPatch + def default_render + if renderable = find_renderable(action_name.to_s, _prefixes) + render(renderable.new) + else + super + end + end + + def find_renderable(action_name, prefixes) + RenderKit::RenderableRegistry.get_renderables([prefixes, action_name].join("_"), controller=true) + end + end +end diff --git a/lib/render_kit/renderable_registry.rb b/lib/render_kit/renderable_registry.rb index c6f5817..6a35def 100644 --- a/lib/render_kit/renderable_registry.rb +++ b/lib/render_kit/renderable_registry.rb @@ -2,14 +2,22 @@ module RenderKit module RenderableRegistry # :nodoc: - @renderables = Hash.new {} + @renderables = Hash.new { |h, k| h[k] = {} } - def self.get_renderables(path) - @renderables[path] + def self.get_renderables(path, controller=false) + if controller + renderable = @renderables[path] + renderable[:renderable_klass] if renderable&.[](:controller_render) + else + @renderables[path][:renderable_klass] + end end - def self.set_renderable(path, renderable_klass) - @renderables[path] = renderable_klass + def self.set_renderable(path, renderable_klass, controller_render=false) + @renderables[path] = { + renderable_klass: renderable_klass, + controller_render: controller_render + } end end end diff --git a/lib/render_kit/view_paths_monkey_patch.rb b/lib/render_kit/view_paths_monkey_patch.rb index fde83f7..7ead8bd 100644 --- a/lib/render_kit/view_paths_monkey_patch.rb +++ b/lib/render_kit/view_paths_monkey_patch.rb @@ -7,8 +7,8 @@ module ViewPathsMonkeyPatch extend ActiveSupport::Concern module ClassMethods - def register_renderable(path, renderable_klass) - RenderKit::RenderableRegistry.set_renderable(path, renderable_klass) + def register_renderable(path, renderable_klass, controller_render=false) + RenderKit::RenderableRegistry.set_renderable(path, renderable_klass, controller_render) end end end diff --git a/test/sandbox/app/components/implicit_render_component.rb b/test/sandbox/app/components/implicit_render_component.rb index 1d929ee..9131c7f 100644 --- a/test/sandbox/app/components/implicit_render_component.rb +++ b/test/sandbox/app/components/implicit_render_component.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true class ImplicitRenderComponent < ViewComponent::Base - ActionView::Base.register_renderable("implicit_render_component", ImplicitRenderComponent) + ActionView::Base.register_renderable("implicit_render", ImplicitRenderComponent) end diff --git a/test/sandbox/app/components/test_implicit_controller_render_component.html.erb b/test/sandbox/app/components/test_implicit_controller_render_component.html.erb new file mode 100644 index 0000000..acfce2a --- /dev/null +++ b/test/sandbox/app/components/test_implicit_controller_render_component.html.erb @@ -0,0 +1 @@ +
I have been implicity rendered by a controller
diff --git a/test/sandbox/app/components/test_implicit_controller_render_component.rb b/test/sandbox/app/components/test_implicit_controller_render_component.rb new file mode 100644 index 0000000..3f46156 --- /dev/null +++ b/test/sandbox/app/components/test_implicit_controller_render_component.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +class TestImplicitControllerRenderComponent < ViewComponent::Base + ActionView::Base.register_renderable("test_implicit_controller_render", TestImplicitControllerRenderComponent, controller_render=true) +end diff --git a/test/sandbox/app/controllers/test_controller.rb b/test/sandbox/app/controllers/test_controller.rb index bd70c9e..0cec83e 100644 --- a/test/sandbox/app/controllers/test_controller.rb +++ b/test/sandbox/app/controllers/test_controller.rb @@ -3,4 +3,7 @@ class TestController < ActionController::Base def component_implicit_render end + + def implicit_controller_render + end end diff --git a/test/sandbox/app/views/test/component_implicit_render.html.erb b/test/sandbox/app/views/test/component_implicit_render.html.erb index 59e6770..bb8791f 100644 --- a/test/sandbox/app/views/test/component_implicit_render.html.erb +++ b/test/sandbox/app/views/test/component_implicit_render.html.erb @@ -1,3 +1,3 @@
- <%= render "implicit_render_component" %> + <%= render "implicit_render" %>
diff --git a/test/sandbox/config/routes.rb b/test/sandbox/config/routes.rb index 826592d..26c609b 100644 --- a/test/sandbox/config/routes.rb +++ b/test/sandbox/config/routes.rb @@ -9,6 +9,7 @@ get "service-worker" => "rails/pwa#service_worker", :as => :pwa_service_worker get "manifest" => "rails/pwa#manifest", :as => :pwa_manifest get "component_implicit_render", to: "test#component_implicit_render" + get "implicit_controller_render", to: "test#implicit_controller_render" # Defines the root path route ("/") # root "posts#index" end diff --git a/test/sandbox/test/view_component_compatability_test.rb b/test/sandbox/test/view_component_compatability_test.rb index 4e16fdc..2e5a5f1 100644 --- a/test/sandbox/test/view_component_compatability_test.rb +++ b/test/sandbox/test/view_component_compatability_test.rb @@ -30,4 +30,11 @@ def test_rendering_view_component assert_response :success assert_match(/I have been implicity rendered/, @response.body) end + + def test_rendering_view_component_with_controller_render + get :implicit_controller_render + assert_response 200 + assert_response :success + assert_match(/I have been implicity rendered by a controller/, @response.body) + end end