diff options
Diffstat (limited to 'actionview/lib')
-rw-r--r-- | actionview/lib/action_view.rb | 1 | ||||
-rw-r--r-- | actionview/lib/action_view/template/resolver.rb | 29 | ||||
-rw-r--r-- | actionview/lib/action_view/unbound_template.rb | 32 |
3 files changed, 52 insertions, 10 deletions
diff --git a/actionview/lib/action_view.rb b/actionview/lib/action_view.rb index 5ee14bfc78..7f85bf2a5e 100644 --- a/actionview/lib/action_view.rb +++ b/actionview/lib/action_view.rb @@ -44,6 +44,7 @@ module ActionView autoload :Rendering autoload :RoutingUrlFor autoload :Template + autoload :UnboundTemplate autoload :ViewPaths autoload_under "renderer" do diff --git a/actionview/lib/action_view/template/resolver.rb b/actionview/lib/action_view/template/resolver.rb index e291dc268a..1be82f5df5 100644 --- a/actionview/lib/action_view/template/resolver.rb +++ b/actionview/lib/action_view/template/resolver.rb @@ -169,6 +169,12 @@ module ActionView else @pattern = DEFAULT_PATTERN end + @unbound_templates = Concurrent::Map.new + super() + end + + def clear_cache + @unbound_templates.clear super() end @@ -189,16 +195,19 @@ module ActionView end def build_template(template, virtual_path, locals) - handler, format, variant = extract_handler_and_format_and_variant(template) - - filename = File.expand_path(template) - source = Template::Sources::File.new(filename) - Template.new(source, filename, handler, - virtual_path: virtual_path, - format: format, - variant: variant, - locals: locals - ) + @unbound_templates.compute_if_absent([template, virtual_path]) do + handler, format, variant = extract_handler_and_format_and_variant(template) + source = Template::Sources::File.new(template) + + UnboundTemplate.new( + source, + template, + handler, + virtual_path: virtual_path, + format: format, + variant: variant, + ) + end.bind_locals(locals) end def reject_files_external_to_app(files) diff --git a/actionview/lib/action_view/unbound_template.rb b/actionview/lib/action_view/unbound_template.rb new file mode 100644 index 0000000000..db69b6d016 --- /dev/null +++ b/actionview/lib/action_view/unbound_template.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +require "concurrent/map" + +module ActionView + class UnboundTemplate + def initialize(source, identifer, handler, options) + @source = source + @identifer = identifer + @handler = handler + @options = options + + @templates = Concurrent::Map.new(initial_capacity: 2) + end + + def bind_locals(locals) + @templates[locals] ||= build_template(locals) + end + + private + + def build_template(locals) + options = @options.merge(locals: locals) + Template.new( + @source, + @identifer, + @handler, + options + ) + end + end +end |