Action View 捕获帮助器
CaptureHelper 公开方法,让你可以提取生成的标记,这些标记可以在模板或布局文件的其他部分使用。
它提供了一种通过 capture
将块捕获到变量中的方法,以及通过 content_for
捕获块标记以在布局中使用的方法。
当通过 provide
使用流响应时,还提供了一种方法。有关更多信息,请参阅 ActionController::Streaming
。
实例公共方法
capture(*args, &block) 链接
capture 方法将模板的一部分作为字符串对象提取出来。然后,你可以在模板、布局或帮助器中的任何位置使用此对象。
capture 方法可以在 ERB 模板中使用…
<% @greeting = capture do %>
Welcome to my shiny new web page! The date and time is
<%= Time.now %>
<% end %>
…和 Builder (RXML) 模板。
@timestamp = capture do
"The current timestamp is #{Time.now}."
end
然后,你可以在任何其他位置使用该变量。例如
<html>
<head><title><%= @greeting %></title></head>
<body>
<b><%= @greeting %></b>
</body>
</html>
capture 的返回值是由块生成的字符串。例如
@greeting # => "Welcome to my shiny new web page! The date and time is 2018-09-06 11:09:16 -0500"
来源: 显示 | 在 GitHub 上
# File actionview/lib/action_view/helpers/capture_helper.rb, line 47 def capture(*args, &block) value = nil @output_buffer ||= ActionView::OutputBuffer.new buffer = @output_buffer.capture { value = yield(*args) } string = if @output_buffer.equal?(value) buffer else buffer.presence || value end case string when OutputBuffer string.to_s when ActiveSupport::SafeBuffer string when String ERB::Util.html_escape(string) end end
content_for(name, content = nil, options = {}, &block) 链接
调用 content_for
会将块标记存储在标识符中以供以后使用。为了在其他模板、帮助器模块或布局中访问此存储的内容,你需要将标识符作为参数传递给 content_for
。
注意:yield
仍然可以用来检索存储的内容,但调用 yield
在帮助器模块中不起作用,而 content_for
起作用。
<% content_for :not_authorized do %>
alert('You are not authorized to do that!')
<% end %>
然后,你可以在模板中的任何位置使用 content_for :not_authorized
。
<%= content_for :not_authorized if current_user.nil? %>
这相当于
<%= yield :not_authorized if current_user.nil? %>
但是,content_for
也可以在帮助器模块中使用。
module StorageHelper
def stored_content
content_for(:storage) || "Your storage is empty"
end
end
此帮助器的工作方式与普通帮助器相同。
<%= stored_content %>
您还可以在布局中使用 yield
语法和对 yield
的现有调用。例如
<%# This is the layout %>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>My Website</title>
<%= yield :script %>
</head>
<body>
<%= yield %>
</body>
</html>
现在,我们将创建一个具有 content_for
调用(创建 script
标识符)的视图。
<%# This is our view %>
Please login!
<% content_for :script do %>
<script>alert('You are not authorized to view this page!')</script>
<% end %>
然后,在另一个视图中,您可以执行类似以下操作
<%= link_to 'Logout', action: 'logout', remote: true %>
<% content_for :script do %>
<%= javascript_include_tag :defaults %>
<% end %>
这将在页面上放置您的默认 JavaScript 文件集的 script
标签;如果您只在几个视图中使用这些脚本,此技术很有用。
请注意,content_for
按顺序连接(默认)为特定标识符提供的块。例如
<% content_for :navigation do %>
<li><%= link_to 'Home', action: 'index' %></li>
<% end %>
在另一个地方
<% content_for :navigation do %>
<li><%= link_to 'Login', action: 'login' %></li>
<% end %>
然后,在另一个模板或布局中,此代码将按顺序呈现这两个链接
<ul><%= content_for :navigation %></ul>
如果 flush 参数为 true
,content_for
将替换它所给出的块。例如
<% content_for :navigation do %>
<li><%= link_to 'Home', action: 'index' %></li>
<% end %>
<%# Add some other content, or use a different template: %>
<% content_for :navigation, flush: true do %>
<li><%= link_to 'Login', action: 'login' %></li>
<% end %>
然后,在另一个模板或布局中,此代码将只呈现最后一个链接
<ul><%= content_for :navigation %></ul>
最后,可以将简单内容作为参数传递
<% content_for :script, javascript_include_tag(:defaults) %>
警告:content_for
在缓存中被忽略。因此,您不应将其用于将被片段缓存的元素。
来源:显示 | 在 GitHub 上
# File actionview/lib/action_view/helpers/capture_helper.rb, line 172 def content_for(name, content = nil, options = {}, &block) if content || block_given? if block_given? options = content if content content = capture(&block) end if content options[:flush] ? @view_flow.set(name, content) : @view_flow.append(name, content) end nil else @view_flow.get(name).presence end end
content_for?(name) 链接
content_for?
检查是否已使用 content_for
捕获任何内容。
根据视图中的内容以不同的方式呈现布局的各个部分非常有用。
<%# This is the layout %>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>My Website</title>
<%= yield :script %>
</head>
<body class="<%= content_for?(:right_col) ? 'two-column' : 'one-column' %>">
<%= yield %>
<%= yield :right_col %>
</body>
</html>
来源:显示 | 在 GitHub 上
# File actionview/lib/action_view/helpers/capture_helper.rb, line 215 def content_for?(name) @view_flow.get(name).present? end
provide(name, content = nil, &block) 链接
与 content_for
相同,但与流媒体一起使用时会直接刷新回布局。换句话说,如果您想在呈现给定模板时多次连接到同一个缓冲区,则应使用 content_for
,如果不是,则使用 provide
告诉布局停止查找更多内容。
有关更多信息,请参阅 ActionController::Streaming
。
来源:显示 | 在 GitHub 上
# File actionview/lib/action_view/helpers/capture_helper.rb, line 194 def provide(name, content = nil, &block) content = capture(&block) if block_given? result = @view_flow.append!(name, content) if content result unless content end