# frozen_string_literal: truemoduleActionControllermoduleRenderingextendActiveSupport::ConcernRENDER_FORMATS_IN_PRIORITY=[:body,:plain,:html]moduleClassMethods# Documentation at ActionController::Renderer#renderdelegate:render,to: :renderer# Returns a renderer instance (inherited from ActionController::Renderer)# for the controller.attr_reader:rendererdefsetup_renderer!# :nodoc:@renderer=Renderer.for(self)enddefinherited(klass)klass.setup_renderer!superendend# Renders a template and assigns the result to +self.response_body+.## If no rendering mode option is specified, the template will be derived# from the first argument.## render "posts/show"# # => renders app/views/posts/show.html.erb## # In a PostsController action...# render :show# # => renders app/views/posts/show.html.erb## If the first argument responds to +render_in+, the template will be# rendered by calling +render_in+ with the current view context.## ==== \Rendering Mode## [+:partial+]# See ActionView::PartialRenderer for details.## render partial: "posts/form", locals: { post: Post.new }# # => renders app/views/posts/_form.html.erb## [+:file+]# Renders the contents of a file. This option should <b>not</b> be used# with unsanitized user input.## render file: "/path/to/some/file"# # => renders /path/to/some/file## [+:inline+]# Renders an ERB template string.## @name = "World"# render inline: "<h1>Hello, <%= @name %>!</h1>"# # => renders "<h1>Hello, World!</h1>"## [+:body+]# Renders the provided text, and sets the content type as +text/plain+.## render body: "Hello, World!"# # => renders "Hello, World!"## [+:plain+]# Renders the provided text, and sets the content type as +text/plain+.## render plain: "Hello, World!"# # => renders "Hello, World!"## [+:html+]# Renders the provided HTML string, and sets the content type as +text/html+.# If the string is not +html_safe?+, performs HTML escaping on the string# before rendering.## render html: "<h1>Hello, World!</h1>".html_safe# # => renders "<h1>Hello, World!</h1>"## render html: "<h1>Hello, World!</h1>"# # => renders "<h1>Hello, World!</h1>"## [+:json+]# Renders the provided object as JSON, and sets the content type as# +application/json+. If the object is not a string, it will be converted# to JSON by calling +to_json+.## render json: { hello: "world" }# # => renders "{\"hello\":\"world\"}"## By default, when a rendering mode is specified, no layout template is# rendered.## ==== Options## [+:assigns+]# Hash of instance variable assignments for the template.## render inline: "<h1>Hello, <%= @name %>!</h1>", assigns: { name: "World" }# # => renders "<h1>Hello, World!</h1>"## [+:locals+]# Hash of local variable assignments for the template.## render inline: "<h1>Hello, <%= name %>!</h1>", locals: { name: "World" }# # => renders "<h1>Hello, World!</h1>"## [+:layout+]# The layout template to render. Can also be +false+ or +true+ to disable# or (re)enable the default layout template.## render "posts/show", layout: "holiday"# # => renders app/views/posts/show.html.erb with the app/views/layouts/holiday.html.erb layout## render "posts/show", layout: false# # => renders app/views/posts/show.html.erb with no layout## render inline: "<h1>Hello, World!</h1>", layout: true# # => renders "<h1>Hello, World!</h1>" with the default layout## [+:status+]# The HTTP status code to send with the response. Can be specified as a# number or as the status name in Symbol form. Defaults to 200.## render "posts/new", status: 422# # => renders app/views/posts/new.html.erb with HTTP status code 422## render "posts/new", status: :unprocessable_entity# # => renders app/views/posts/new.html.erb with HTTP status code 422##--# Check for double render errors and set the content_type after rendering.defrender(*args)raise::AbstractController::DoubleRenderErrorifresponse_bodysuperend# Similar to #render, but only returns the rendered template as a string,# instead of setting +self.response_body+.#--# Override render_to_string because body can now be set to a Rack body.defrender_to_string(*)result=superifresult.respond_to?(:each)string=+""result.each{|r|string<<r}stringelseresultendenddefrender_to_body(options={})# :nodoc:super||_render_in_priorities(options)||" "endprivate# Before processing, set the request formats in current controller formats.defprocess_action(*)# :nodoc:self.formats=request.formats.filter_map(&:ref)superenddef_process_variant(options)ifdefined?(request)&&!request.nil?&&request.variant.present?options[:variant]=request.variantendenddef_render_in_priorities(options)RENDER_FORMATS_IN_PRIORITY.eachdo|format|returnoptions[format]ifoptions.key?(format)endnilenddef_set_html_content_typeself.content_type=Mime[:html].to_senddef_set_rendered_content_type(format)ifformat&&!response.media_typeself.content_type=format.to_sendenddef_set_vary_headerifresponse.headers["Vary"].blank?&&request.should_apply_vary_header?response.headers["Vary"]="Accept"endend# Normalize both text and status options.def_normalize_options(options)_normalize_text(options)ifoptions[:html]options[:html]=ERB::Util.html_escape(options[:html])endifoptions[:status]options[:status]=Rack::Utils.status_code(options[:status])endsuperenddef_normalize_text(options)RENDER_FORMATS_IN_PRIORITY.eachdo|format|ifoptions.key?(format)&&options[format].respond_to?(:to_text)options[format]=options[format].to_textendendend# Process controller specific options, as status, content-type and location.def_process_options(options)status,content_type,location=options.values_at(:status,:content_type,:location)self.status=statusifstatusself.content_type=content_typeifcontent_typeheaders["Location"]=url_for(location)iflocationsuperendendend