跳至内容 跳至搜索

Action View Rendering Helpers

实现允许从视图上下文中渲染的方法。要使用此模块,您只需要实现返回 ActionView::Renderer 对象的 view_renderer。

方法
#
R

实例公共方法

_layout_for(*args, &block)

在上下文对象中重写 _layout_for,以便支持将块传递给局部视图的情况。根据名称或块返回被传递给布局的内容。

您可以将布局视为一个带有块调用的方法。如果用户调用 yield :some_name,则块默认返回 content_for(:some_name)。如果用户仅调用 yield,则默认块将返回 content_for(:layout)

用户可以通过将块传递给布局来覆盖此默认设置

# The template
<%= render layout: "my_layout" do %>
  Content
<% end %>

# The layout
<html>
  <%= yield %>
</html>

在这种情况下,此方法将返回传递给 render :layout 的块,而不是默认的块(该块将返回 content_for(:layout)),并且响应将是

<html>
  Content
</html>

最后,块可以接受块参数,这些参数可以通过 yield 传递

# The template
<%= render layout: "my_layout" do |customer| %>
  Hello <%= customer.name %>
<% end %>

# The layout
<html>
  <%= yield Struct.new(:name).new("David") %>
</html>

在这种情况下,布局将接收传递给 render :layout 的块,并且指定的结构将作为参数传递到块中。结果将是

<html>
  Hello David
</html>
# File actionview/lib/action_view/helpers/rendering_helper.rb, line 207
def _layout_for(*args, &block)
  name = args.first

  if block && !name.is_a?(Symbol)
    capture(*args, &block)
  else
    super
  end
end

render(options = {}, locals = {}, &block)

渲染模板并返回结果。

将要渲染的模板作为第一个参数传递。这是局部视图渲染的简写语法,因此模板文件名应以“_”前缀。局部视图渲染器首先在调用模板的目录中查找局部视图模板。

<% # app/views/posts/new.html.erb %>
<%= render "form" %>
# => renders app/views/posts/_form.html.erb

使用完整的视图路径从其他目录渲染局部视图。

<% # app/views/posts/show.html.erb %>
<%= render "comments/form" %>
# => renders app/views/comments/_form.html.erb

如果不使用渲染模式,第二个参数可以是用于模板的局部变量赋值的 Hash

<% # app/views/posts/new.html.erb %>
<%= render "form", post: Post.new %>
# => renders app/views/posts/_form.html.erb

如果第一个参数响应 render_in,则通过调用 render_in 并传入当前视图上下文来渲染模板。

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>"

Rendering Mode

将渲染模式作为第一个参数传递以覆盖它。

:partial

有关详细信息,请参阅 ActionView::PartialRenderer

    <%= render partial: "form", locals: { post: Post.new } %>
    # => renders app/views/posts/_form.html.erb
:file

渲染文件的内容。此选项应与未经消毒的用户输入一起使用。

    <%= render file: "/path/to/some/file" %>
    # => renders /path/to/some/file
:inline

渲染 ERB 模板字符串。

    <% name = "World" %>
    <%= render inline: "<h1>Hello, <%= name %>!</h1>" %>
    # => renders "<h1>Hello, World!</h1>"
:body

渲染提供的文本,并将格式设置为 :text

    <%= render body: "Hello, World!" %>
    # => renders "Hello, World!"
:plain

渲染提供的文本,并将格式设置为 :text

    <%= render plain: "Hello, World!" %>
    # => renders "Hello, World!"
:html

渲染提供的 HTML 字符串,并将格式设置为 :html。如果字符串不是 html_safe?,则在渲染之前对字符串执行 HTML 转义。

    <%= render html: "<h1>Hello, World!</h1>".html_safe %>
    # => renders "<h1>Hello, World!</h1>"

    <%= render html: "<h1>Hello, World!</h1>" %>
    # => renders "&lt;h1&gt;Hello, World!&lt;/h1&gt;"
:renderable

通过调用 render_in 并传入当前视图上下文来渲染提供的对象。格式通过调用可渲染对象的 format 来确定(如果它响应 format),默认回退到 :html

    <%= render renderable: Greeting.new %>
    # => renders "<h1>Hello, World</h1>"

Options

:locals

用于模板的局部变量赋值的 Hash

    <%= render inline: "<h1>Hello, <%= name %>!</h1>", locals: { name: "World" } %>
    # => renders "<h1>Hello, World!</h1>"
:formats

覆盖当前格式以渲染不同格式的模板。

    <% # app/views/posts/show.html.erb %>
    <%= render template: "posts/content", formats: [:text] %>
    # => renders app/views/posts/content.text.erb
:variants

渲染不同变体的模板。

    <% # app/views/posts/show.html.erb %>
    <%= render template: "posts/content", variants: [:tablet] %>
    # => renders app/views/posts/content.html+tablet.erb
:handlers

渲染不同处理程序的模板。

    <% # app/views/posts/show.html.erb %>
    <%= render template: "posts/content", handlers: [:builder] %>
    # => renders app/views/posts/content.html.builder
# File actionview/lib/action_view/helpers/rendering_helper.rb, line 138
def render(options = {}, locals = {}, &block)
  case options
  when Hash
    in_rendering_context(options) do |renderer|
      if block_given?
        view_renderer.render_partial(self, options.merge(partial: options[:layout]), &block)
      else
        view_renderer.render(self, options)
      end
    end
  else
    if options.respond_to?(:render_in)
      options.render_in(self, &block)
    else
      view_renderer.render_partial(self, partial: options, locals: locals, &block)
    end
  end
end