2017-07-23 11:36:41 -04:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2017-10-21 09:21:02 -04:00
|
|
|
require "action_view/view_paths"
|
2013-06-26 07:40:46 -04:00
|
|
|
|
|
|
|
module ActionView
|
|
|
|
# This is a class to fix I18n global state. Whenever you provide I18n.locale during a request,
|
|
|
|
# it will trigger the lookup_context and consequently expire the cache.
|
|
|
|
class I18nProxy < ::I18n::Config #:nodoc:
|
|
|
|
attr_reader :original_config, :lookup_context
|
|
|
|
|
|
|
|
def initialize(original_config, lookup_context)
|
|
|
|
original_config = original_config.original_config if original_config.respond_to?(:original_config)
|
|
|
|
@original_config, @lookup_context = original_config, lookup_context
|
|
|
|
end
|
|
|
|
|
|
|
|
def locale
|
|
|
|
@original_config.locale
|
|
|
|
end
|
|
|
|
|
|
|
|
def locale=(value)
|
|
|
|
@lookup_context.locale = value
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
module Rendering
|
|
|
|
extend ActiveSupport::Concern
|
|
|
|
include ActionView::ViewPaths
|
|
|
|
|
|
|
|
# Overwrite process to setup I18n proxy.
|
|
|
|
def process(*) #:nodoc:
|
|
|
|
old_config, I18n.config = I18n.config, I18nProxy.new(I18n.config, lookup_context)
|
|
|
|
super
|
|
|
|
ensure
|
|
|
|
I18n.config = old_config
|
|
|
|
end
|
|
|
|
|
|
|
|
module ClassMethods
|
2019-01-23 18:44:32 -05:00
|
|
|
def _routes
|
|
|
|
end
|
|
|
|
|
|
|
|
def _helpers
|
|
|
|
end
|
|
|
|
|
2019-01-24 15:45:21 -05:00
|
|
|
def build_view_context_class(klass, supports_path, routes, helpers)
|
2019-01-23 18:44:32 -05:00
|
|
|
Class.new(klass) do
|
|
|
|
if routes
|
|
|
|
include routes.url_helpers(supports_path)
|
|
|
|
include routes.mounted_helpers
|
|
|
|
end
|
|
|
|
|
|
|
|
if helpers
|
|
|
|
include helpers
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-06-26 07:40:46 -04:00
|
|
|
def view_context_class
|
2019-01-23 17:19:50 -05:00
|
|
|
klass = ActionView::LookupContext::DetailsKey.view_context_class(ActionView::Base)
|
2013-06-26 07:40:46 -04:00
|
|
|
|
2019-01-24 15:45:21 -05:00
|
|
|
@view_context_class ||= build_view_context_class(klass, supports_path?, _routes, _helpers)
|
2013-06-26 07:40:46 -04:00
|
|
|
|
2019-01-23 17:19:50 -05:00
|
|
|
if klass.changed?(@view_context_class)
|
2019-01-24 15:45:21 -05:00
|
|
|
@view_context_class = build_view_context_class(klass, supports_path?, _routes, _helpers)
|
2013-06-26 07:40:46 -04:00
|
|
|
end
|
2019-01-23 18:44:32 -05:00
|
|
|
|
|
|
|
@view_context_class
|
2013-06-26 07:40:46 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def view_context_class
|
2019-01-18 18:07:22 -05:00
|
|
|
self.class.view_context_class
|
2013-06-26 07:40:46 -04:00
|
|
|
end
|
|
|
|
|
2015-06-13 23:33:30 -04:00
|
|
|
# An instance of a view class. The default view class is ActionView::Base.
|
2013-06-26 07:40:46 -04:00
|
|
|
#
|
|
|
|
# The view class must have the following methods:
|
2018-12-17 16:10:26 -05:00
|
|
|
#
|
2018-12-17 17:16:55 -05:00
|
|
|
# * <tt>View.new(lookup_context, assigns, controller)</tt> — Create a new
|
2018-12-17 16:10:26 -05:00
|
|
|
# ActionView instance for a controller and we can also pass the arguments.
|
|
|
|
#
|
|
|
|
# * <tt>View#render(option)</tt> — Returns String with the rendered template.
|
2013-06-26 07:40:46 -04:00
|
|
|
#
|
|
|
|
# Override this method in a module to change the default behavior.
|
|
|
|
def view_context
|
|
|
|
view_context_class.new(view_renderer, view_assigns, self)
|
|
|
|
end
|
|
|
|
|
|
|
|
# Returns an object that is able to render templates.
|
2017-09-30 05:33:53 -04:00
|
|
|
def view_renderer # :nodoc:
|
2013-06-26 07:40:46 -04:00
|
|
|
@_view_renderer ||= ActionView::Renderer.new(lookup_context)
|
|
|
|
end
|
|
|
|
|
2013-09-09 11:05:09 -04:00
|
|
|
def render_to_body(options = {})
|
|
|
|
_process_options(options)
|
|
|
|
_render_template(options)
|
|
|
|
end
|
|
|
|
|
2013-08-01 20:27:28 -04:00
|
|
|
def rendered_format
|
2016-01-16 13:17:59 -05:00
|
|
|
Template::Types[lookup_context.rendered_format]
|
2013-08-01 20:27:28 -04:00
|
|
|
end
|
|
|
|
|
2013-06-26 07:40:46 -04:00
|
|
|
private
|
|
|
|
|
2013-12-03 05:17:01 -05:00
|
|
|
# Find and render a template based on the options given.
|
2016-12-24 08:08:23 -05:00
|
|
|
def _render_template(options)
|
2015-01-15 08:52:46 -05:00
|
|
|
variant = options.delete(:variant)
|
|
|
|
assigns = options.delete(:assigns)
|
|
|
|
context = view_context
|
2013-12-03 05:17:01 -05:00
|
|
|
|
2015-01-15 08:52:46 -05:00
|
|
|
context.assign assigns if assigns
|
2013-11-19 19:51:49 -05:00
|
|
|
lookup_context.rendered_format = nil if options[:formats]
|
2014-02-13 09:59:09 -05:00
|
|
|
lookup_context.variants = variant if variant
|
2013-12-03 05:17:01 -05:00
|
|
|
|
2015-01-15 08:52:46 -05:00
|
|
|
view_renderer.render(context, options)
|
2013-11-19 19:51:49 -05:00
|
|
|
end
|
|
|
|
|
2015-07-17 14:15:35 -04:00
|
|
|
# Assign the rendered format to look up context.
|
2016-12-24 08:08:23 -05:00
|
|
|
def _process_format(format)
|
2013-09-09 11:32:39 -04:00
|
|
|
super
|
|
|
|
lookup_context.formats = [format.to_sym]
|
|
|
|
lookup_context.rendered_format = lookup_context.formats.first
|
|
|
|
end
|
|
|
|
|
2013-07-12 07:01:10 -04:00
|
|
|
# Normalize args by converting render "foo" to render :action => "foo" and
|
2014-09-25 11:07:07 -04:00
|
|
|
# render "foo/bar" to render :template => "foo/bar".
|
2016-10-28 23:05:58 -04:00
|
|
|
def _normalize_args(action = nil, options = {})
|
2013-07-12 07:01:10 -04:00
|
|
|
options = super(action, options)
|
|
|
|
case action
|
|
|
|
when NilClass
|
|
|
|
when Hash
|
|
|
|
options = action
|
|
|
|
when String, Symbol
|
|
|
|
action = action.to_s
|
2014-09-25 11:07:07 -04:00
|
|
|
key = action.include?(?/) ? :template : :action
|
2013-07-12 07:01:10 -04:00
|
|
|
options[key] = action
|
|
|
|
else
|
2017-01-15 00:06:57 -05:00
|
|
|
if action.respond_to?(:permitted?) && action.permitted?
|
|
|
|
options = action
|
|
|
|
else
|
|
|
|
options[:partial] = action
|
|
|
|
end
|
2013-07-12 07:01:10 -04:00
|
|
|
end
|
2013-06-26 07:40:46 -04:00
|
|
|
|
2013-07-12 07:01:10 -04:00
|
|
|
options
|
2013-06-26 07:40:46 -04:00
|
|
|
end
|
|
|
|
|
2013-07-12 07:01:10 -04:00
|
|
|
# Normalize options.
|
|
|
|
def _normalize_options(options)
|
|
|
|
options = super(options)
|
|
|
|
if options[:partial] == true
|
|
|
|
options[:partial] = action_name
|
|
|
|
end
|
2013-06-26 07:40:46 -04:00
|
|
|
|
2013-07-12 07:01:10 -04:00
|
|
|
if (options.keys & [:partial, :file, :template]).empty?
|
|
|
|
options[:prefixes] ||= _prefixes
|
|
|
|
end
|
|
|
|
|
|
|
|
options[:template] ||= (options[:action] || action_name).to_s
|
|
|
|
options
|
|
|
|
end
|
2013-06-26 07:40:46 -04:00
|
|
|
end
|
|
|
|
end
|