diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index cae2fe1cf..55e55dcba 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -10,6 +10,9 @@ nav_order: 6 ## main +* Capture partial block in the components context + *23tux* + * Resolve deprecation warning for `ActiveSupport::Configurable`. *Simon Fish* diff --git a/lib/view_component/base.rb b/lib/view_component/base.rb index 8f8619c67..59cc3f5fe 100644 --- a/lib/view_component/base.rb +++ b/lib/view_component/base.rb @@ -260,6 +260,9 @@ def render(options = {}, args = {}, &block) @view_context.render(options, args, &block) elsif block __vc_original_view_context.render(options, args) do + # capture the block output in the view context of the component + output = capture(&block) + # Partials are rendered to their own buffer and do not append to the # original @output_buffer we retain a reference to in #render_in. This # is a problem since the block passed to us here in the #render method @@ -267,7 +270,7 @@ def render(options = {}, args = {}, &block) # appends to the original @output_buffer. To avoid this, we evaluate the # block in the view context instead, which will append to the output buffer # created for the partial. - __vc_original_view_context.instance_exec(&block) + __vc_original_view_context.capture { output } end else __vc_original_view_context.render(options, args) diff --git a/test/sandbox/app/components/partial_with_yield_and_method_call_component.html.erb b/test/sandbox/app/components/partial_with_yield_and_method_call_component.html.erb new file mode 100644 index 000000000..fd41a8fd1 --- /dev/null +++ b/test/sandbox/app/components/partial_with_yield_and_method_call_component.html.erb @@ -0,0 +1,3 @@ +<%= render "shared/yielding_partial" do %> + <%= world %> +<% end %> diff --git a/test/sandbox/app/components/partial_with_yield_and_method_call_component.rb b/test/sandbox/app/components/partial_with_yield_and_method_call_component.rb new file mode 100644 index 000000000..86d0db034 --- /dev/null +++ b/test/sandbox/app/components/partial_with_yield_and_method_call_component.rb @@ -0,0 +1,5 @@ +class PartialWithYieldAndMethodCallComponent < ViewComponent::Base + def world + "world" + end +end diff --git a/test/sandbox/test/rendering_test.rb b/test/sandbox/test/rendering_test.rb index 4bcfe1dfc..18baf8cb4 100644 --- a/test/sandbox/test/rendering_test.rb +++ b/test/sandbox/test/rendering_test.rb @@ -1322,4 +1322,9 @@ def test_render_partial_with_yield render_inline(PartialWithYieldComponent.new) assert_text "hello world", exact: true, normalize_ws: true end + + def test_render_partial_with_yield_and_method_call + render_inline(PartialWithYieldAndMethodCallComponent.new) + assert_text "hello world", exact: true, normalize_ws: true + end end