跳至内容 跳至搜索

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 模式

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

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

选项

: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