2017-07-23 11:36:41 -04:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2013-06-25 08:58:29 -04:00
|
|
|
module ActionView
|
2010-03-08 10:50:10 -05:00
|
|
|
module ViewPaths
|
|
|
|
extend ActiveSupport::Concern
|
|
|
|
|
|
|
|
included do
|
2019-02-08 17:43:22 -05:00
|
|
|
ViewPaths.set_view_paths(self, ActionView::PathSet.new.freeze)
|
2010-03-08 10:50:10 -05:00
|
|
|
end
|
|
|
|
|
Lock down new `ImplicitRender` behavior for 5.0 RC
1. Conceptually revert #20276
The feature was implemented for the `responders` gem. In the end,
they did not need that feature, and have found a better fix (see
plataformatec/responders#131).
`ImplicitRender` is the place where Rails specifies our default
policies for the case where the user did not explicitly tell us
what to render, essentially describing a set of heuristics. If
the gem (or the user) knows exactly what they want, they could
just perform the correct `render` to avoid falling through to
here, as `responders` did (the user called `respond_with`).
Reverting the patch allows us to avoid exploding the complexity
and defining “the fallback for a fallback” policies.
2. `respond_to` and templates are considered exhaustive enumerations
If the user specified a list of formats/variants in a `respond_to`
block, anything that is not explicitly included should result
in an `UnknownFormat` error (which is then caught upstream to
mean “406 Not Acceptable” by default). This is already how it
works before this commit.
Same goes for templates – if the user defined a set of templates
(usually in the file system), that set is now considered exhaustive,
which means that “missing” templates are considered `UnknownFormat`
errors (406).
3. To keep API endpoints simple, the implicit render behavior for
actions with no templates defined at all (regardless of formats,
locales, variants, etc) are defaulted to “204 No Content”. This
is a strictly narrower version of the feature landed in #19036 and
#19377.
4. To avoid confusion when interacting in the browser, these actions
will raise an `UnknownFormat` error for “interactive” requests
instead. (The precise definition of “interactive” requests might
change – the spirit here is to give helpful messages and avoid
confusions.)
Closes #20666, #23062, #23077, #23564
[Godfrey Chan, Jon Moss, Kasper Timm Hansen, Mike Clark, Matthew Draper]
2016-02-23 12:41:26 -05:00
|
|
|
delegate :template_exists?, :any_templates?, :view_paths, :formats, :formats=,
|
2016-08-06 13:36:34 -04:00
|
|
|
:locale, :locale=, to: :lookup_context
|
2010-03-08 10:50:10 -05:00
|
|
|
|
2011-05-04 05:26:02 -04:00
|
|
|
module ClassMethods
|
2019-02-08 17:43:22 -05:00
|
|
|
def _view_paths
|
|
|
|
ViewPaths.get_view_paths(self)
|
|
|
|
end
|
|
|
|
|
|
|
|
def _view_paths=(paths)
|
|
|
|
ViewPaths.set_view_paths(self, paths)
|
|
|
|
end
|
|
|
|
|
2014-05-14 12:42:55 -04:00
|
|
|
def _prefixes # :nodoc:
|
2014-05-08 07:26:20 -04:00
|
|
|
@_prefixes ||= begin
|
2015-01-03 15:46:09 -05:00
|
|
|
return local_prefixes if superclass.abstract?
|
2014-05-14 13:26:46 -04:00
|
|
|
|
2015-01-03 15:46:09 -05:00
|
|
|
local_prefixes + superclass._prefixes
|
2011-05-04 05:26:02 -04:00
|
|
|
end
|
|
|
|
end
|
2014-05-08 07:26:20 -04:00
|
|
|
|
2019-08-18 11:35:23 -04:00
|
|
|
# Append a path to the list of view paths for this controller.
|
|
|
|
#
|
|
|
|
# ==== Parameters
|
|
|
|
# * <tt>path</tt> - If a String is provided, it gets converted into
|
|
|
|
# the default view path. You may also provide a custom view path
|
|
|
|
# (see ActionView::PathSet for more information)
|
|
|
|
def append_view_path(path)
|
|
|
|
self._view_paths = view_paths + Array(path)
|
|
|
|
end
|
|
|
|
|
|
|
|
# Prepend a path to the list of view paths for this controller.
|
|
|
|
#
|
|
|
|
# ==== Parameters
|
|
|
|
# * <tt>path</tt> - If a String is provided, it gets converted into
|
|
|
|
# the default view path. You may also provide a custom view path
|
|
|
|
# (see ActionView::PathSet for more information)
|
|
|
|
def prepend_view_path(path)
|
|
|
|
self._view_paths = ActionView::PathSet.new(Array(path) + view_paths)
|
|
|
|
end
|
|
|
|
|
|
|
|
# A list of all of the default view paths for this controller.
|
|
|
|
def view_paths
|
|
|
|
_view_paths
|
|
|
|
end
|
|
|
|
|
|
|
|
# Set the view paths.
|
|
|
|
#
|
|
|
|
# ==== Parameters
|
|
|
|
# * <tt>paths</tt> - If a PathSet is provided, use that;
|
|
|
|
# otherwise, process the parameter into a PathSet.
|
|
|
|
def view_paths=(paths)
|
|
|
|
self._view_paths = ActionView::PathSet.new(Array(paths))
|
|
|
|
end
|
|
|
|
|
2014-05-10 02:52:44 -04:00
|
|
|
private
|
2016-09-14 04:57:52 -04:00
|
|
|
# Override this method in your controller if you want to change paths prefixes for finding views.
|
|
|
|
# Prefixes defined here will still be added to parents' <tt>._prefixes</tt>.
|
2016-08-06 13:55:02 -04:00
|
|
|
def local_prefixes
|
|
|
|
[controller_path]
|
|
|
|
end
|
2011-05-04 05:26:02 -04:00
|
|
|
end
|
|
|
|
|
2019-02-08 17:43:22 -05:00
|
|
|
# :stopdoc:
|
|
|
|
@all_view_paths = {}
|
|
|
|
|
|
|
|
def self.get_view_paths(klass)
|
|
|
|
@all_view_paths[klass] || get_view_paths(klass.superclass)
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.set_view_paths(klass, paths)
|
|
|
|
@all_view_paths[klass] = paths
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.all_view_paths
|
|
|
|
@all_view_paths.values.uniq
|
|
|
|
end
|
|
|
|
# :startdoc:
|
|
|
|
|
2011-05-04 05:26:02 -04:00
|
|
|
# The prefixes used in render "foo" shortcuts.
|
2014-05-14 12:42:55 -04:00
|
|
|
def _prefixes # :nodoc:
|
2014-05-08 07:26:20 -04:00
|
|
|
self.class._prefixes
|
2011-05-04 05:26:02 -04:00
|
|
|
end
|
|
|
|
|
2015-07-17 14:15:35 -04:00
|
|
|
# <tt>LookupContext</tt> is the object responsible for holding all
|
|
|
|
# information required for looking up templates, i.e. view paths and
|
|
|
|
# details. Check <tt>ActionView::LookupContext</tt> for more information.
|
2010-03-08 10:50:10 -05:00
|
|
|
def lookup_context
|
2011-05-06 08:32:48 -04:00
|
|
|
@_lookup_context ||=
|
2011-05-04 03:07:11 -04:00
|
|
|
ActionView::LookupContext.new(self.class._view_paths, details_for_lookup, _prefixes)
|
2010-03-08 10:50:10 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def details_for_lookup
|
2016-08-16 03:30:11 -04:00
|
|
|
{}
|
2010-03-08 10:50:10 -05:00
|
|
|
end
|
|
|
|
|
2016-11-11 12:31:20 -05:00
|
|
|
# Append a path to the list of view paths for the current <tt>LookupContext</tt>.
|
|
|
|
#
|
|
|
|
# ==== Parameters
|
|
|
|
# * <tt>path</tt> - If a String is provided, it gets converted into
|
|
|
|
# the default view path. You may also provide a custom view path
|
|
|
|
# (see ActionView::PathSet for more information)
|
2010-03-08 10:50:10 -05:00
|
|
|
def append_view_path(path)
|
|
|
|
lookup_context.view_paths.push(*path)
|
|
|
|
end
|
|
|
|
|
2016-11-11 12:31:20 -05:00
|
|
|
# Prepend a path to the list of view paths for the current <tt>LookupContext</tt>.
|
|
|
|
#
|
|
|
|
# ==== Parameters
|
|
|
|
# * <tt>path</tt> - If a String is provided, it gets converted into
|
|
|
|
# the default view path. You may also provide a custom view path
|
|
|
|
# (see ActionView::PathSet for more information)
|
2010-03-08 10:50:10 -05:00
|
|
|
def prepend_view_path(path)
|
|
|
|
lookup_context.view_paths.unshift(*path)
|
|
|
|
end
|
|
|
|
end
|
2014-05-14 12:41:20 -04:00
|
|
|
end
|