提交 8cd9f6d2 编写于 作者: P Prem Sichanugrist

Introduce `render :plain` for render plain text

This is as an option to render content with a content type of
`text/plain`. This is the preferred option if you are planning to render
a plain text content.

Please see #12374 for more detail.
上级 9e9cc660
* Introduce `render :plain` as an option to render content with a content type
of `text/plain`. This is the preferred option if you are planning to render
a plain text content.
Please see #12374 for more detail.
*Prem Sichanugrist*
* Introduce `render :body` as an option for sending a raw content back to * Introduce `render :body` as an option for sending a raw content back to
browser. Note that this rendering option will unset the default content type browser. Note that this rendering option will unset the default content type
and does not include "Content-Type" header back in the response. and does not include "Content-Type" header back in the response.
......
...@@ -27,7 +27,7 @@ def render_to_string(*) ...@@ -27,7 +27,7 @@ def render_to_string(*)
end end
def render_to_body(options = {}) def render_to_body(options = {})
super || options[:body].presence || options[:text].presence || ' ' super || options[:body].presence || options[:text].presence || options[:plain].presence || ' '
end end
private private
...@@ -40,6 +40,10 @@ def _process_format(format, options = {}) ...@@ -40,6 +40,10 @@ def _process_format(format, options = {})
self.content_type = "none" self.content_type = "none"
self.headers.delete "Content-Type" self.headers.delete "Content-Type"
end end
if options[:plain].present?
self.content_type = Mime::TEXT
end
end end
# Normalize arguments by catching blocks and setting them on :update. # Normalize arguments by catching blocks and setting them on :update.
...@@ -59,7 +63,11 @@ def _normalize_options(options) #:nodoc: ...@@ -59,7 +63,11 @@ def _normalize_options(options) #:nodoc:
options[:text] = options[:text].to_text options[:text] = options[:text].to_text
end end
if options.delete(:nothing) || (options.key?(:body) && options[:body].nil?) || (options.key?(:text) && options[:text].nil?) if options.key?(:plain) && options[:plain].respond_to?(:to_text)
options[:plain] = options[:plain].to_text
end
if options.delete(:nothing) || (options.key?(:body) && options[:body].nil?) || (options.key?(:text) && options[:text].nil?) || (options.key?(:plain) && options[:plain].nil?)
options[:body] = " " options[:body] = " "
end end
......
require 'abstract_unit'
module RenderPlain
class MinimalController < ActionController::Metal
include AbstractController::Rendering
include ActionController::Rendering
def index
render plain: "Hello World!"
end
end
class SimpleController < ActionController::Base
self.view_paths = [ActionView::FixtureResolver.new]
def index
render plain: "hello david"
end
end
class WithLayoutController < ::ApplicationController
self.view_paths = [ActionView::FixtureResolver.new(
"layouts/application.text.erb" => "<%= yield %>, I'm here!",
"layouts/greetings.text.erb" => "<%= yield %>, I wish thee well.",
"layouts/ivar.text.erb" => "<%= yield %>, <%= @ivar %>"
)]
def index
render plain: "hello david"
end
def custom_code
render plain: "hello world", status: 404
end
def with_custom_code_as_string
render plain: "hello world", status: "404 Not Found"
end
def with_nil
render plain: nil
end
def with_nil_and_status
render plain: nil, status: 403
end
def with_false
render plain: false
end
def with_layout_true
render plain: "hello world", layout: true
end
def with_layout_false
render plain: "hello world", layout: false
end
def with_layout_nil
render plain: "hello world", layout: nil
end
def with_custom_layout
render plain: "hello world", layout: "greetings"
end
def with_ivar_in_layout
@ivar = "hello world"
render plain: "hello world", layout: "ivar"
end
end
class RenderPlainTest < Rack::TestCase
test "rendering text from a minimal controller" do
get "/render_plain/minimal/index"
assert_body "Hello World!"
assert_status 200
end
test "rendering text from an action with default options renders the text with the layout" do
with_routing do |set|
set.draw { get ':controller', action: 'index' }
get "/render_plain/simple"
assert_body "hello david"
assert_status 200
end
end
test "rendering text from an action with default options renders the text without the layout" do
with_routing do |set|
set.draw { get ':controller', action: 'index' }
get "/render_plain/with_layout"
assert_body "hello david"
assert_status 200
end
end
test "rendering text, while also providing a custom status code" do
get "/render_plain/with_layout/custom_code"
assert_body "hello world"
assert_status 404
end
test "rendering text with nil returns an empty body padded for Safari" do
get "/render_plain/with_layout/with_nil"
assert_body " "
assert_status 200
end
test "Rendering text with nil and custom status code returns an empty body padded for Safari and the status" do
get "/render_plain/with_layout/with_nil_and_status"
assert_body " "
assert_status 403
end
test "rendering text with false returns the string 'false'" do
get "/render_plain/with_layout/with_false"
assert_body "false"
assert_status 200
end
test "rendering text with layout: true" do
get "/render_plain/with_layout/with_layout_true"
assert_body "hello world, I'm here!"
assert_status 200
end
test "rendering text with layout: 'greetings'" do
get "/render_plain/with_layout/with_custom_layout"
assert_body "hello world, I wish thee well."
assert_status 200
end
test "rendering text with layout: false" do
get "/render_plain/with_layout/with_layout_false"
assert_body "hello world"
assert_status 200
end
test "rendering text with layout: nil" do
get "/render_plain/with_layout/with_layout_nil"
assert_body "hello world"
assert_status 200
end
test "rendering from minimal controller returns response with text/plain content type" do
get "/render_plain/minimal/index"
assert_content_type "text/plain"
end
test "rendering from normal controller returns response with text/plain content type" do
get "/render_plain/simple/index"
assert_content_type "text/plain; charset=utf-8"
end
end
end
...@@ -12,6 +12,8 @@ module RenderingHelper ...@@ -12,6 +12,8 @@ module RenderingHelper
# * <tt>:file</tt> - Renders an explicit template file (this used to be the old default), add :locals to pass in those. # * <tt>:file</tt> - Renders an explicit template file (this used to be the old default), add :locals to pass in those.
# * <tt>:inline</tt> - Renders an inline template similar to how it's done in the controller. # * <tt>:inline</tt> - Renders an inline template similar to how it's done in the controller.
# * <tt>:text</tt> - Renders the text passed in out. # * <tt>:text</tt> - Renders the text passed in out.
# * <tt>:plain</tt> - Renders the text passed in out. Setting the content
# type as <tt>text/plain</tt>.
# * <tt>:body</tt> - Renders the text passed in, and does not set content # * <tt>:body</tt> - Renders the text passed in, and does not set content
# type in the response. # type in the response.
# #
......
...@@ -420,7 +420,7 @@ def _default_layout(require_layout = false) ...@@ -420,7 +420,7 @@ def _default_layout(require_layout = false)
end end
def _include_layout?(options) def _include_layout?(options)
(options.keys & [:body, :text, :inline, :partial]).empty? || options.key?(:layout) (options.keys & [:body, :text, :plain, :inline, :partial]).empty? || options.key?(:layout)
end end
end end
end end
...@@ -25,6 +25,8 @@ def determine_template(options) #:nodoc: ...@@ -25,6 +25,8 @@ def determine_template(options) #:nodoc:
Template::Text.new(options[:body]) Template::Text.new(options[:body])
elsif options.key?(:text) elsif options.key?(:text)
Template::Text.new(options[:text], formats.first) Template::Text.new(options[:text], formats.first)
elsif options.key?(:plain)
Template::Text.new(options[:plain])
elsif options.key?(:file) elsif options.key?(:file)
with_fallbacks { find_template(options[:file], nil, false, keys, @details) } with_fallbacks { find_template(options[:file], nil, false, keys, @details) }
elsif options.key?(:inline) elsif options.key?(:inline)
...@@ -37,7 +39,7 @@ def determine_template(options) #:nodoc: ...@@ -37,7 +39,7 @@ def determine_template(options) #:nodoc:
find_template(options[:template], options[:prefixes], false, keys, @details) find_template(options[:template], options[:prefixes], false, keys, @details)
end end
else else
raise ArgumentError, "You invoked render but did not give any of :partial, :template, :inline, :file, :text or :body option." raise ArgumentError, "You invoked render but did not give any of :partial, :template, :inline, :file, :plain, :text or :body option."
end end
end end
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册