未验证 提交 c82a9193 编写于 作者: J Joel Hawksley 提交者: GitHub

Document view components support (#38656)

上级 99b607e6
......@@ -82,8 +82,12 @@ def initialize(controller, env, defaults)
# need to call <tt>.to_json</tt> on the object you want to render.
# * <tt>:body</tt> - Renders provided text and sets content type of <tt>text/plain</tt>.
#
# If no <tt>options</tt> hash is passed or if <tt>:update</tt> is specified, the default is
# to render a partial and use the second parameter as the locals hash.
# If no <tt>options</tt> hash is passed or if <tt>:update</tt> is specified, then:
#
# If an object responding to `render_in` is passed, `render_in` is called on the object,
# passing in the current view context.
#
# Otherwise, a partial is rendered using the second parameter as the locals hash.
def render(*args)
raise "missing controller" unless controller
......
......@@ -70,8 +70,8 @@ def test_render_component
renderer = ApplicationController.renderer
assert_equal(
%(<span title="my title">(Inline render)</span>),
renderer.render(TestComponent.new(title: "my title")).strip
%(Hello, World!),
renderer.render(TestComponent.new)
)
end
......
# frozen_string_literal: true
class TestComponent < ActionView::Base
delegate :render, to: :view_context
def initialize(title:)
@title = title
end
def render_in(view_context)
self.class.compile
@view_context = view_context
rendered_template
class TestComponent
def render_in(_view_context)
"Hello, World!"
end
def format
:html
end
def self.template
<<~'erb'
<span title="<%= title %>">(<%= render(plain: "Inline render") %>)</span>
erb
end
def self.compile
@compiled ||= nil
return if @compiled
class_eval(
"def rendered_template; @output_buffer = ActionView::OutputBuffer.new; " +
ActionView::Template::Handlers::ERB.erb_implementation.new(template, trim: true).src +
"; end"
)
@compiled = true
end
private
attr_reader :title, :view_context
end
......@@ -22,8 +22,12 @@ module RenderingHelper
# type of <tt>text/plain</tt> from <tt>ActionDispatch::Response</tt>
# object.
#
# If no options hash is passed or :update specified, the default is to render a partial and use the second parameter
# as the locals hash.
# If no <tt>options</tt> hash is passed or if <tt>:update</tt> is specified, then:
#
# If an object responding to `render_in` is passed, `render_in` is called on the object,
# passing in the current view context.
#
# Otherwise, a partial is rendered using the second parameter as the locals hash.
def render(options = {}, locals = {}, &block)
case options
when Hash
......
# frozen_string_literal: true
class TestComponent < ActionView::Base
delegate :render, to: :view_context
def initialize(title:)
@title = title
end
# Entrypoint for rendering. Called by ActionView::RenderingHelper#render.
#
# Returns ActionView::OutputBuffer.
def render_in(view_context, &block)
self.class.compile
@view_context = view_context
@content = view_context.capture(&block) if block_given?
rendered_template
end
def self.template
<<~'erb'
<span title="<%= title %>"><%= content %> (<%= render(plain: "Inline render") %>)</span>
erb
class TestComponent
def render_in(_view_context)
"Hello, World!"
end
def self.compile
@compiled ||= nil
return if @compiled
class_eval(
"def rendered_template; @output_buffer = ActionView::OutputBuffer.new; " +
ActionView::Template::Handlers::ERB.erb_implementation.new(template, trim: true).src +
"; end"
)
@compiled = true
end
private
attr_reader :content, :title, :view_context
end
......@@ -681,8 +681,8 @@ def test_render_throws_exception_when_no_extensions_passed_to_register_template_
def test_render_component
assert_equal(
%(<span title="my title">Hello, World! (Inline render)</span>),
@view.render(TestComponent.new(title: "my title")) { "Hello, World!" }.strip
%(Hello, World!),
@view.render(TestComponent.new)
)
end
end
......
......@@ -277,6 +277,16 @@ since an attacker could use this action to access security sensitive files in yo
TIP: `send_file` is often a faster and better option if a layout isn't required.
#### Rendering objects
Rails can render objects responding to `:render_in`.
```ruby
render MyComponent.new
```
This calls `render_in` on the provided object with the current view context.
#### Options for `render`
Calls to the `render` method generally accept six options:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册