Skip to content

Don't compile external templates#94

Open
jherdman wants to merge 1 commit intomarcoroth:mainfrom
jherdman:ignore-external-templates
Open

Don't compile external templates#94
jherdman wants to merge 1 commit intomarcoroth:mainfrom
jherdman:ignore-external-templates

Conversation

@jherdman
Copy link
Copy Markdown

User's should not be beholden to template errors outside of their application. When we detect a template not local to the project we use the fallback ERB implementation.

Resolves #91

@jherdman
Copy link
Copy Markdown
Author

jherdman commented Apr 1, 2026

@marcoroth im seeing some test fails here, but I think they're on main. Anything I can do to help?

@marcoroth
Copy link
Copy Markdown
Owner

marcoroth commented Apr 1, 2026

@jherdman thanks! I think you might have to run bundle exec appraisal bundle install since you added mocha

class_attribute :erb_implementation, default: Handlers::Herb::Herb

def call(template, source)
return compile_with_fallback_erb_implementation(template, source) unless local_template?(template)
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If people opt-in to use Herb (or have a .herb file) we should compile everything using Herb. So I think we want to move this condition to lib/reactionview/template/handlers/erb.rb:10:

if template.format == :html && ReActionView.config.intercept_erb

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I think I understand your motivation, but I want to double check. Am I correct to understand that ReActionView::Template::Handlers::Herb is never used unless we intercept ERb files?

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct yes, see here:

ActionView::Template.register_template_handler :herb, ReActionView::Template::Handlers::Herb
end
end
config.after_initialize do
ActiveSupport.on_load(:action_view) do
ActionView::Template.register_template_handler :erb, ReActionView::Template::Handlers::ERB if ReActionView.config.intercept_erb

So if you have .html.herb it uses ReActionView::Template::Handlers::Herb directly, and otherwise if you have intercept_erb = true it goes through ReActionView::Template::Handlers::ERB

Copy link
Copy Markdown
Owner

@marcoroth marcoroth Apr 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally, we would still try to compile everything through Herb::Engine and only fall back (and warn) if there are some parse errors. But we don't need to do this in this PR.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you reckon the cost of a rescue, log, retry through the fallback, is acceptable? Implementation doesn't seem that difficult imho.

Copy link
Copy Markdown
Owner

@marcoroth marcoroth Apr 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is a compile-time concern I'm not too worried about the performance cost, that said, we could also just do it in development/test and not in production.

User's should not be beholden to template errors outside of their
application. When we detect a template not local to the project we use
the fallback ERB implementation.
@jherdman jherdman force-pushed the ignore-external-templates branch from 5b7269c to 05ead32 Compare April 1, 2026 11:00
Comment on lines +383 to +387
compiled_source = template_obj.handler.call(template_obj, template)
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
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test pattern follows your others, but, much to my surprise, something in this setup doesn't raise an error when I encounter an erroneous template. This frustrated my abilities to implement logging.

We know real world usage raises per the original issue. Is there something askew with the test setup?

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

def local_template?(template)
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Short of exposing this as a class method on the Herb handler, it felt like this duplication was either warranted, so we should consider a TemplateUtilities module that we can mix in. Thoughts?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ReactionView is Cranky About Internal Rails Templates

2 participants