2009-12-12 20:50:12 -05:00
require " abstract_controller/base "
2010-06-02 16:56:41 -04:00
require " action_view "
2009-02-27 14:42:13 -05:00
2009-02-24 20:25:21 -05:00
module AbstractController
2009-12-12 19:48:34 -05:00
class DoubleRenderError < Error
DEFAULT_MESSAGE = " Render and/or redirect were called multiple times in this action. Please note that you may only call render OR redirect, and at most once per action. Also note that neither redirect nor render terminate execution of the action, so if you want to exit an action after redirecting, you need to do something like \" redirect_to(...) and return \" . "
def initialize ( message = nil )
super ( message || DEFAULT_MESSAGE )
end
end
2010-03-10 16:11:48 -05:00
# 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.
# TODO Add some deprecation warnings to remove I18n.locale from controllers
class I18nProxy < :: I18n :: Config #:nodoc:
attr_reader :i18n_config , :lookup_context
def initialize ( i18n_config , lookup_context )
@i18n_config , @lookup_context = i18n_config , lookup_context
end
def locale
@i18n_config . locale
end
def locale = ( value )
2010-04-12 04:50:27 -04:00
@lookup_context . locale = value
2010-03-10 16:11:48 -05:00
end
end
2010-03-08 05:32:01 -05:00
module Rendering
extend ActiveSupport :: Concern
2010-03-12 14:39:53 -05:00
2010-03-08 05:32:01 -05:00
include AbstractController :: ViewPaths
2010-03-10 16:11:48 -05:00
# 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
2010-03-18 21:12:04 -04:00
module ClassMethods
def view_context_class
@view_context_class || = begin
controller = self
Class . new ( ActionView :: Base ) do
if controller . respond_to? ( :_helpers )
include controller . _helpers
2010-03-19 01:55:44 -04:00
if controller . respond_to? ( :_router )
include controller . _router . url_helpers
end
2010-03-18 21:12:04 -04:00
# TODO: Fix RJS to not require this
self . helpers = controller . _helpers
end
end
end
end
end
attr_writer :view_context_class
def view_context_class
@view_context_class || self . class . view_context_class
end
2010-03-19 01:21:25 -04:00
def initialize ( * )
@view_context_class = nil
super
end
2009-06-08 20:41:08 -04:00
# An instance of a view class. The default view class is ActionView::Base
#
# The view class must have the following methods:
2010-03-18 21:12:04 -04:00
# View.new[lookup_context, assigns, controller]
2010-03-08 05:32:01 -05:00
# Create a new ActionView instance for a controller
2010-03-18 21:12:04 -04:00
# View#render[options]
2010-03-08 05:32:01 -05:00
# Returns String with the rendered template
2009-06-08 20:41:08 -04:00
#
2010-02-16 13:45:59 -05:00
# Override this method in a module to change the default behavior.
2009-08-06 18:45:40 -04:00
def view_context
2010-03-18 21:12:04 -04:00
view_context_class . new ( lookup_context , view_assigns , self )
2009-02-24 20:25:21 -05:00
end
2009-05-28 10:49:02 -04:00
2010-03-12 14:39:53 -05:00
# Normalize arguments, options and then delegates render_to_body and
# sticks the result in self.response_body.
2010-01-20 08:21:27 -05:00
def render ( * args , & block )
2010-04-04 22:49:12 -04:00
self . response_body = render_to_string ( * args , & block )
end
# Raw rendering of a template to a string. Just convert the results of
# render_to_body into a String.
# :api: plugin
def render_to_string ( * args , & block )
2010-03-07 21:23:16 -05:00
options = _normalize_args ( * args , & block )
_normalize_options ( options )
2010-04-04 22:49:12 -04:00
render_to_body ( options )
2009-03-18 18:58:47 -04:00
end
2009-05-28 10:49:02 -04:00
2009-04-21 19:02:30 -04:00
# Raw rendering of a template to a Rack-compatible body.
2009-03-19 18:45:48 -04:00
# :api: plugin
2009-04-17 19:34:49 -04:00
def render_to_body ( options = { } )
2010-03-08 05:32:01 -05:00
_process_options ( options )
_render_template ( options )
2009-02-27 14:42:13 -05:00
end
2010-03-08 05:32:01 -05:00
# Find and renders a template based on the options given.
2010-03-12 14:39:53 -05:00
# :api: private
def _render_template ( options ) #:nodoc:
view_context . render ( options )
2009-05-28 10:49:02 -04:00
end
2009-02-27 14:42:13 -05:00
2010-01-22 11:57:36 -05:00
# The prefix used in render "foo" shortcuts.
def _prefix
controller_path
2010-01-20 08:21:27 -05:00
end
2009-05-22 15:28:40 -04:00
private
2009-10-21 13:55:47 -04:00
2010-03-18 18:52:43 -04:00
# This method should return a hash with assigns.
# You can overwrite this configuration per controller.
# :api: public
def view_assigns
hash = { }
variables = instance_variable_names
variables -= protected_instance_variables if respond_to? ( :protected_instance_variables )
variables . each { | name | hash [ name . to_s [ 1 .. - 1 ] ] = instance_variable_get ( name ) }
hash
end
2010-03-08 10:32:40 -05:00
# Normalize options by converting render "foo" to render :action => "foo" and
# render "foo/bar" to render :file => "foo/bar".
2010-03-07 21:23:16 -05:00
def _normalize_args ( action = nil , options = { } )
2010-01-22 11:57:36 -05:00
case action
2010-03-08 05:32:01 -05:00
when NilClass
2010-01-22 11:57:36 -05:00
when Hash
options , action = action , nil
when String , Symbol
action = action . to_s
2010-03-08 10:32:40 -05:00
key = action . include? ( ?/ ) ? :file : :action
options [ key ] = action
2010-03-08 05:32:01 -05:00
else
options . merge! ( :partial = > action )
2010-01-22 11:57:36 -05:00
end
options
end
2010-03-07 21:23:16 -05:00
def _normalize_options ( options )
2010-03-08 05:32:01 -05:00
if options [ :partial ] == true
options [ :partial ] = action_name
end
2010-03-07 21:23:16 -05:00
2010-03-08 05:32:01 -05:00
if ( options . keys & [ :partial , :file , :template ] ) . empty?
2010-03-08 17:13:24 -05:00
options [ :prefix ] || = _prefix
2009-10-18 20:52:36 -04:00
end
2010-03-08 05:32:01 -05:00
options [ :template ] || = ( options [ :action ] || action_name ) . to_s
options
2010-02-24 16:06:24 -05:00
end
2010-03-08 05:32:01 -05:00
def _process_options ( options )
2009-10-21 13:55:47 -04:00
end
2009-02-24 20:25:21 -05:00
end
2010-01-31 21:32:28 -05:00
end