ActionController::Base.class_eval do def self.string_layout( the_string_layout, conditions = {} ) if the_string_layout.nil? clear_string_layout_conditions else add_string_layout_conditions( conditions ) end write_inheritable_attribute( :string_layout, the_string_layout ) end def self.string_layout_conditions #:nodoc: read_inheritable_attribute( :string_layout_conditions ) end def self.add_string_layout_conditions( conditions ) write_inheritable_hash :string_layout_conditions, normalize_conditions( conditions ) end def self.clear_string_layout_conditions write_inheritable_attribute :string_layout_conditions, { } end def default_string_layout self.class.read_inheritable_attribute( :string_layout ) end def active_string_layout( passed_string_layout = nil ) string_layout_blob = passed_string_layout || default_string_layout the_active_string_layout = case string_layout_blob when String StringLayout.new( :layout => string_layout_blob ) when Symbol send( string_layout_blob ) when Proc string_layout_blob.call( self ) end if the_active_string_layout.nil? nil elsif the_active_string_layout.respond_to?( :layout ) the_active_string_layout elsif the_active_string_layout.respond_to?( :to_s ) StringLayout.new( :layout => the_active_string_layout.to_s ) else StringLayout.new( :layout => '<%= @content_for_layout %>' ) end end def render_with_a_string_layout( options = nil, deprecated_status = nil, deprecated_layout = nil, &block ) template_with_options = options.is_a?( Hash ) return render_with_no_string_layout( options, deprecated_status, &block ) unless apply_string_layout?( template_with_options, options ) the_string_layout = pick_string_layout( template_with_options, options, deprecated_layout ) return render_with_no_string_layout( options, deprecated_status, &block ) unless the_string_layout.respond_to?( :layout ) logger.info( "Rendering #{options} within string_layout #{the_string_layout}" ) if logger if template_with_options content_for_layout = render_with_no_string_layout( options, &block ) deprecated_status = options[:status] || deprecated_status else content_for_layout = render_with_no_string_layout( options, deprecated_status, &block ) end erase_render_results add_variables_to_assigns @template.instance_variable_set( "@content_for_layout", content_for_layout ) if the_string_layout.respond_to?( :layout ) render_text( @template.compile_and_render_template( nil, the_string_layout.layout ), deprecated_status ) else render_text( @template.render_file( the_string_layout, true ), deprecated_status ) end end def apply_string_layout?( template_with_options, options ) return false if options == :update template_with_options ? candidate_for_string_layout?( options ) : !template_exempt_from_layout? end def candidate_for_string_layout?( options ) ( options.has_key?( :string_layout ) && options[:string_layout] != false ) || !template_exempt_from_layout?( default_template_name( options[:action] || options[:template] ) ) end def pick_string_layout( template_with_options, options, deprecated_layout ) if deprecated_layout.respond_to?( :layout ) deprecated_layout elsif template_with_options case string_layout = options[:string_layout] when FalseClass nil when NilClass, TrueClass active_string_layout if action_has_string_layout? else active_string_layout( string_layout ) end else active_string_layout if action_has_string_layout? end end def action_has_string_layout? if conditions = self.class.string_layout_conditions case when only = conditions[:only] only.include?( action_name ) when except = conditions[:except] !except.include?( action_name ) else true end else true end end alias_method :render_with_no_string_layout, :render_with_a_layout alias_method :render, :render_with_a_string_layout end