require'active_support/core_ext/object/try'moduleActionViewclassTemplateRenderer<AbstractRenderer#:nodoc:defrender(context,options)@view=context@details=extract_details(options)template=determine_template(options)context=@lookup_contextprepend_formats(template.formats)unlesscontext.rendered_formatcontext.rendered_format=template.formats.first||formats.firstendrender_template(template,options[:layout],options[:locals])end# Determine the template to be rendered using the given options.defdetermine_template(options)#:nodoc:keys=options.fetch(:locals,{}).keysifoptions.key?(:body)Template::Text.new(options[:body])elsifoptions.key?(:text)Template::Text.new(options[:text],formats.first)elsifoptions.key?(:plain)Template::Text.new(options[:plain])elsifoptions.key?(:html)Template::HTML.new(options[:html],formats.first)elsifoptions.key?(:file)with_fallbacks{find_template(options[:file],nil,false,keys,@details)}elsifoptions.key?(:inline)handler=Template.handler_for_extension(options[:type]||"erb")Template.new(options[:inline],"inline template",handler,:locals=>keys)elsifoptions.key?(:template)ifoptions[:template].respond_to?(:render)options[:template]elsefind_template(options[:template],options[:prefixes],false,keys,@details)endelseraiseArgumentError,"You invoked render but did not give any of :partial, :template, :inline, :file, :plain, :text or :body option."endend# Renders the given template. A string representing the layout can be# supplied as well.defrender_template(template,layout_name=nil,locals=nil)#:nodoc:view,locals=@view,locals||{}render_with_layout(layout_name,locals)do|layout|instrument(:template,:identifier=>template.identifier,:layout=>layout.try(:virtual_path))dotemplate.render(view,locals){|*name|view._layout_for(*name)}endendenddefrender_with_layout(path,locals)#:nodoc:layout=path&&find_layout(path,locals.keys)content=yield(layout)iflayoutview=@viewview.view_flow.set(:layout,content)layout.render(view,locals){|*name|view._layout_for(*name)}elsecontentendend# This is the method which actually finds the layout using details in the lookup# context object. If no layout is found, it checks if at least a layout with# the given name exists across all details before raising the error.deffind_layout(layout,keys)with_layout_format{resolve_layout(layout,keys)}enddefresolve_layout(layout,keys)caselayoutwhenStringbeginiflayout=~/^\//with_fallbacks{find_template(layout,nil,false,keys,@details)}elsefind_template(layout,nil,false,keys,@details)endrescueActionView::MissingTemplateall_details=@details.merge(:formats=>@lookup_context.default_formats)raiseunlesstemplate_exists?(layout,nil,false,keys,all_details)endwhenProcresolve_layout(layout.call,keys)whenFalseClassnilelselayoutendendendend