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