Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .erb_lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
EnableDefaultLinters: true
exclude:
- '**/vendor/**/*'
- 'test/sandbox/app/components/content_security_policy_nonce_component.html.erb'
linters:
ErbSafety:
enabled: true
Expand Down
6 changes: 5 additions & 1 deletion docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ nav_order: 6

## main

* Fix bug where inheritance of components with formatless templates improperly raised a NoMethodError.

*GitHub Copilot*, *Joel Hawksley*, *Cameron Dutro*

## 4.6.0

* Add `view_identifier` to the `render.view_component` instrumentation event payload, containing the path to the component's template file (e.g. `app/components/my_component.html.erb`). For components using inline render methods, `view_identifier` will be `nil`.
Expand All @@ -22,7 +26,7 @@ nav_order: 6

* Return `html_safe` empty string from `render_in` when `render?` is false.

*Copilot*
*GitHub Copilot*

## 4.5.0

Expand Down
7 changes: 7 additions & 0 deletions lib/view_component/template.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ def initialize(component:, details:, lineno: nil, path: nil)

class File < Template
def initialize(component:, details:, path:)
# If the template file has no format (e.g. .erb instead of .html.erb),
# assume the default format (html).
if details.format.nil?
Kernel.warn("WARNING: Template format for #{path} is missing, defaulting to :html.")
details = ActionView::TemplateDetails.new(details.locale, details.handler, DEFAULT_FORMAT, details.variant)
end

@strip_annotation_line = false

# Rails 8.1 added a newline to compiled ERB output (rails/rails#53731).
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<div class="child"><%= content %></div>
4 changes: 4 additions & 0 deletions test/sandbox/app/components/format_less_child_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# frozen_string_literal: true

class FormatLessChildComponent < FormatLessParentComponent
end
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<div class="parent"><%= content %></div>
4 changes: 4 additions & 0 deletions test/sandbox/app/components/format_less_parent_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# frozen_string_literal: true

class FormatLessParentComponent < ViewComponent::Base
end
12 changes: 12 additions & 0 deletions test/sandbox/test/rendering_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -852,6 +852,18 @@ def test_inherited_component_overrides_inherits_template
assert_selector("div", text: "hello, my own template")
end

def test_inherited_component_with_format_less_template
# Reproduces https://github.com/ViewComponent/view_component/issues/2573
# When a parent component uses a format-less template (e.g. .erb or .slim
# instead of .html.erb or .html.slim), the child component crashes with
# "undefined method 'upcase' for nil" during compilation.
render_inline(FormatLessChildComponent.new) do
"Hello World"
end

assert_selector("div.child", text: "Hello World")
end

def test_inherited_inline_component_inherits_inline_method
render_inline(InlineInheritedComponent.new)

Expand Down
1 change: 1 addition & 0 deletions test/test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ module Warning
def self.warn(message)
called_by = caller_locations(1, 1).first.path
return super unless called_by&.start_with?(PROJECT_ROOT) && !called_by.start_with?("#{PROJECT_ROOT}/vendor")
return super if message.include?("Template format for")

raise "Warning: #{message}"
end
Expand Down
Loading