# frozen_string_literal: true# :markup: markdownmoduleActionControllermoduleRenderingextendActiveSupport::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.## class Greeting# def render_in(view_context)# view_context.render html: "<h1>Hello, World</h1>"# end## def format# :html# end# end## render(Greeting.new)# # => "<h1>Hello, World</h1>"## render(renderable: Greeting.new)# # => "<h1>Hello, World</h1>"## #### 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 **not** 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\"}"## `:renderable`# : Renders the provided object by calling `render_in` with the current view# context. The response format is determined by calling `format` on the# renderable if it responds to `format`, falling back to `text/html` by# default.## render renderable: Greeting.new# # => renders "<h1>Hello, World</h1>"### 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