Skip to content

Commit 3776c6b

Browse files
committed
Fix bug where rendering Slot with empty block resulted in error.
When rendering a slot with an empty block, the capturing the block returns nil, which does not respond_to `strip`.
1 parent 5b2c32d commit 3776c6b

File tree

7 files changed

+30
-2
lines changed

7 files changed

+30
-2
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# master
22

3+
# 2.17.1
4+
5+
* Fix bug where rendering Slot with empty block resulted in error.
6+
7+
*Joel Hawksley*
8+
39
# 2.17.0
410

511
* Slots return stripped HTML, removing leading and trailing whitespace.

coverage/coverage.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ Incomplete test coverage
88
/lib/view_component/preview.rb: 94.0% (missed: 47,57,107)
99
/lib/view_component/render_to_string_monkey_patch.rb: 83.33% (missed: 9)
1010
/lib/view_component/test_helpers.rb: 91.67% (missed: 17,25)
11-
/test/view_component/integration_test.rb: 96.73% (missed: 14,15,16,18,20,370,371,372,374)
11+
/test/view_component/integration_test.rb: 96.76% (missed: 14,15,16,18,20,376,377,378,380)

lib/view_component/slotable.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ def slot(slot_name, **args, &block)
9898
slot_instance = args.present? ? slot_class.new(**args) : slot_class.new
9999

100100
# Capture block and assign to slot_instance#content
101-
slot_instance.content = view_context.capture(&block).strip.html_safe if block_given?
101+
slot_instance.content = view_context.capture(&block).to_s.strip.html_safe if block_given?
102102

103103
if slot[:collection]
104104
# Initialize instance variable as an empty array
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# frozen_string_literal: true
2+
3+
class EmptySlotComponent < ViewComponent::Base
4+
include ViewComponent::Slotable
5+
6+
with_slot :title
7+
8+
def call
9+
title.content
10+
end
11+
end
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<%= render(EmptySlotComponent.new(class_names: "mt-4")) do |component| %>
2+
<% component.slot(:title) do %>
3+
<% end %>
4+
<% end %>

test/config/routes.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
root to: "integration_examples#index"
55
get :content_areas, to: "integration_examples#content_areas"
66
get :slots, to: "integration_examples#slots"
7+
get :empty_slot, to: "integration_examples#empty_slot"
78
get :partial, to: "integration_examples#partial"
89
get :content, to: "integration_examples#content"
910
get :variants, to: "integration_examples#variants"

test/view_component/integration_test.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,12 @@ class IntegrationTest < ActionDispatch::IntegrationTest
366366
assert_equal(title_node, expected_title_html)
367367
end
368368

369+
test "renders empty slot without error" do
370+
get "/empty_slot"
371+
372+
assert_response :success
373+
end
374+
369375
if Rails.version.to_f >= 6.1
370376
test "rendering component using the render_component helper raises an error" do
371377
error = assert_raises ActionView::Template::Error do

0 commit comments

Comments
 (0)