1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00
rails--rails/actionview/lib/action_view/rendering.rb
@schneems and @sgrif 2bbcca004c Deprecate *_path methods in mailers
Email does not support relative links since there is no implicit host. Therefore all links inside of emails must be fully qualified URLs. All path helpers are now deprecated. When removed, the error will give early indication to developers to use `*_url` methods instead.

Currently if a developer uses a `*_path` helper, their tests and `mail_view` will not catch the mistake. The only way to see the error is by sending emails in production. Preventing sending out emails with non-working path's is the desired end goal of this PR.

Currently path helpers are mixed-in to controllers (the ActionMailer::Base acts as a controller). All `*_url` and `*_path` helpers are made available through the same module. This PR separates this behavior into two modules so we can extend the `*_path` methods to add a Deprecation to them. Once deprecated we can use this same area to raise a NoMethodError and add an informative message directing the developer to use `*_url` instead.

The module with warnings is only mixed in when a controller returns false from the newly added `supports_relative_path?`.

Paired @sgrif & @schneems
2014-07-30 12:01:45 -05:00

146 lines
4.1 KiB
Ruby

require "action_view/view_paths"
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
def view_context_class
@view_context_class ||= begin
include_path_helpers = supports_path?
routes = respond_to?(:_routes) && _routes
helpers = respond_to?(:_helpers) && _helpers
Class.new(ActionView::Base) do
if routes
include routes.url_helpers(include_path_helpers)
include routes.mounted_helpers
end
if helpers
include helpers
end
end
end
end
end
attr_internal_writer :view_context_class
def view_context_class
@_view_context_class ||= self.class.view_context_class
end
# An instance of a view class. The default view class is ActionView::Base
#
# The view class must have the following methods:
# View.new[lookup_context, assigns, controller]
# Create a new ActionView instance for a controller and we can also pass the arguments.
# View#render(option)
# Returns String with the rendered template
#
# 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.
# :api: private
def view_renderer
@_view_renderer ||= ActionView::Renderer.new(lookup_context)
end
def render_to_body(options = {})
_process_options(options)
_render_template(options)
end
def rendered_format
Mime[lookup_context.rendered_format]
end
private
# Find and render a template based on the options given.
# :api: private
def _render_template(options) #:nodoc:
variant = options[:variant]
lookup_context.rendered_format = nil if options[:formats]
lookup_context.variants = variant if variant
view_renderer.render(view_context, options)
end
# Assign the rendered format to lookup context.
def _process_format(format, options = {}) #:nodoc:
super
lookup_context.formats = [format.to_sym]
lookup_context.rendered_format = lookup_context.formats.first
end
# Normalize args by converting render "foo" to render :action => "foo" and
# render "foo/bar" to render :file => "foo/bar".
# :api: private
def _normalize_args(action=nil, options={})
options = super(action, options)
case action
when NilClass
when Hash
options = action
when String, Symbol
action = action.to_s
key = action.include?(?/) ? :file : :action
options[key] = action
else
options[:partial] = action
end
options
end
# Normalize options.
# :api: private
def _normalize_options(options)
options = super(options)
if options[:partial] == true
options[:partial] = action_name
end
if (options.keys & [:partial, :file, :template]).empty?
options[:prefixes] ||= _prefixes
end
options[:template] ||= (options[:action] || action_name).to_s
options
end
end
end