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
21 changes: 20 additions & 1 deletion lib/reactionview/template/handlers/erb.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,31 @@ class ERB < ActionView::Template::Handlers::ERB
autoload :Herb, "reactionview/template/handlers/herb/herb"

def call(template, source)
if template.format == :html && ReActionView.config.intercept_erb
if intercept_template?(template)
::ReActionView::Template::Handlers::Herb.call(template, source)
else
super
end
end

private

def intercept_template?(template)
template.format == :html && ReActionView.config.intercept_erb && local_template?(template)
end

def local_template?(template)
Comment thread
marcoroth marked this conversation as resolved.
return true unless template.respond_to?(:identifier) && template.identifier
return false if vendored_template?(template)

template.identifier.start_with?(Rails.root.to_s)
end

def vendored_template?(template)
return false unless defined?(Bundler)

template.identifier.start_with?(Bundler.bundle_path.to_s)
end
end
end
end
Expand Down
79 changes: 75 additions & 4 deletions test/template/handlers/herb_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -99,15 +99,15 @@ def @view_context.user_path(id)
"/users/#{id}"
end

template_obj = ActionView::Template.new(
template_object = ActionView::Template.new(
template,
"test_template",
ReActionView::Template::Handlers::ERB,
virtual_path: "test",
format: :html,
locals: []
)
compiled_source = template_obj.handler.call(template_obj, template)
compiled_source = template_object.handler.call(template_object, template)

@view_context.instance_variable_set(:@user, {
name: "John Doe",
Expand Down Expand Up @@ -160,15 +160,15 @@ def @view_context.ui_badge(count, **_options)
"<span class=\"badge\">#{count}</span>".html_safe
end

template_obj = ActionView::Template.new(
template_object = ActionView::Template.new(
template,
"test_template",
ReActionView::Template::Handlers::ERB,
virtual_path: "test",
format: :html,
locals: []
)
compiled_source = template_obj.handler.call(template_obj, template)
compiled_source = template_object.handler.call(template_object, template)

@view_context.instance_variable_set(:@show_countries, true)
result = @view_context.instance_eval(compiled_source).to_s
Expand Down Expand Up @@ -365,4 +365,75 @@ def @view_context.ui_badge(count, **_options)

assert_compiled_snapshot(template)
end

test "does not process templates that are not local" do
ReActionView.config.intercept_erb = true

template = %(<p><h2>I am invalid</h2></p>)
template_object = ActionView::Template.new(
template,
"test_template",
ReActionView::Template::Handlers::ERB,
virtual_path: "test",
format: :html,
locals: []
)

compiled_source = Rails.stub(:root, Pathname.new("/local/template")) do
template_object.handler.call(template_object, template)
end

result = @view_context.instance_eval(compiled_source).to_s

normalized_result = result.gsub(/>\s+</, "><").gsub(/\s+/, " ").strip
assert_equal "<p><h2>I am invalid</h2></p>", normalized_result
end

test "does not process templates from gems vendored inside the application" do
ReActionView.config.intercept_erb = true

template = %(<p><h2>I am invalid</h2></p>)
template_object = ActionView::Template.new(
template,
"/app/vendor/bundle/ruby/3.4.0/gems/actionpack-8.1.2/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb",
ReActionView::Template::Handlers::ERB,
virtual_path: "rescues/routing_error",
format: :html,
locals: []
)

compiled_source = Rails.stub(:root, Pathname.new("/app")) do
Bundler.stub(:bundle_path, Pathname.new("/app/vendor/bundle")) do
template_object.handler.call(template_object, template)
end
end

result = @view_context.instance_eval(compiled_source).to_s

normalized_result = result.gsub(/>\s+</, "><").gsub(/\s+/, " ").strip
assert_equal "<p><h2>I am invalid</h2></p>", normalized_result
end

test "processes application templates when gems are vendored inside the application" do
ReActionView.config.intercept_erb = true
ReActionView.config.debug_mode = true

template = %(<div><h1>Hello</h1></div>)
template_object = ActionView::Template.new(
template,
"/app/app/views/users/show.html.erb",
ReActionView::Template::Handlers::ERB,
virtual_path: "users/show",
format: :html,
locals: []
)

compiled_source = Rails.stub(:root, Pathname.new("/app")) do
Bundler.stub(:bundle_path, Pathname.new("/app/vendor/bundle")) do
template_object.handler.call(template_object, template)
end
end

assert_includes compiled_source, %(data-herb-debug-file-full-path="/app/app/views/users/show.html.erb")
end
end
Loading