Content_for Api 翻译理解

CaptureHelper包含了让你能够选出可以在其他样板或样式复用的标记代码(html为主)
它通过capture存放block到变量,通过content_for 来存放可以复用的html代码。

capture(*args)

capture方法让你可以分离出部分(通常是可复用的)代码并储存到一个变量中,之后你就可以在任何样板或样式中使用这个变量。

capture方法可以在ERB样板中使用

1
2
3
4
<% @greeting = capture do %>
  Welcome to my shiny new web page!  The date and time is
  <%= Time.now %>
<% end %>

…并且在Builder(RXML)样板中

1
2
3
@timestamp = capture do
  "The current timestamp is #{Time.now}."
end

你之后就能在任何地方使用这个变量。比如:

1
2
3
4
5
<html>
<head><title><%= @greeting %></title></head>
<body>
<b><%= @greeting %></b>
</body></html>

这个是capture的源代码

1
2
3
4
5
6
7
8
# File actionpack/lib/action_view/helpers/capture_helper.rb, line 38
def capture(*args)
  value = nil
  buffer = with_output_buffer { value = yield(*args) }
  if string = buffer.presence || value and string.is_a?(String)
    ERB::Util.html_escape string
  end
end

content_for(name, content=nil, &block)

给 #content_for 个名字,并在其中保存一段标记语言以备后用。随后你能在样板,helper,或者样式中呼叫这段代码,只要叫出content_for的名字即可。 注意:yield能呼叫出储存的内容,但是在helper中并不管用,但是content_for能起到作用。

例子

1
2
3
<% content_for :not_authorized do %>
  alert('You are not authorized to do that!')
<% end %>

你能在之后的样式中任何地方使用content_for :not_authorized。

1
2
3
<%= content_for :not_authorized if current_user.nil? %>
这相等于:
<%= yield :not_authorized if current_user.nil? %>

(再次提醒,yield在template之中万能,但是helper中还是乖乖呼叫content_for吧)


content_for还能在helper中被使用

1
2
3
4
5
module StorageHelper
  def stored_content
    content_for(:storage) || "Your storage is empty"
  end
end

这个helper和普通的helper一样工作 <%= stored_content %>

你能使用yield即使在样式中已经有一个存在的yield。举例:

1
2
3
4
5
6
7
8
9
10
<%# 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>

现在,我们将建立一个包含叫script的content_for方法

1
2
3
4
5
6
<%# This is our view %>
Please login!

<% content_for :script do %>
  <script type="text/javascript">alert('You are not authorized to view this page!')</script>
<% end %>

之后,在另一个视图中,你可以做这样的事情:

1
2
3
4
5
<%= link_to 'Logout', :action => 'logout', :remote => true %>

<% content_for :script do %>
  <%= javascript_include_tag :defaults %>
<% end %>

这会将你之前设定的脚本标签中默认的js文件load在页面上;如果多次在view中使用到这段代码,content_for会很实用.

注意#content_for连接的是同名的识别器的block,他会依次render。举例:

1
2
3
4
5
6
7
8
9
<% content_for :navigation do %>
  <li><%= link_to 'Home', :action => 'index' %></li>
<% end %>

<%#  Add some other content, or use a different template: %>

<% content_for :navigation do %>
  <li><%= link_to 'Login', :action => 'login' %></li>
<% end %>

那么,在另一个样板或样式中,这个代码会按次序render这两个links(将所有同名的都 render 进去)。

<ul><%= content_for :navigation %></ul> 最后。简单的content可以作为param被传递

<% content_for :script, javascript_include_tag(:defaults) %> 警告:#content_for在缓存中被忽视。所以你不应该把它用在会被部分缓存的元素上。

tips : 一般先是<% render 'template'%>然后再yield想要的内容

content_for?(name)

content_for? 只是检查content_for是否成功被调用,可以传递部分参数进你的视图,比较有用。 例子: 也许你针对不同的元素会用不一样的css

1
2
3
4
5
6
7
8
9
10
11
<%# 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) ? 'one-column' : 'two-column' %>">
  <%= yield %>
  <%= yield :right_col %>
</body>
</html>

`

provide(name, content = nil, &block)

和content_for 一样但是当和streaming flushes使用并直接被引用至样式。换句话说,如果当你想连接几次到一个相同的buffer,传递同样的样板,用content_for,如果不是,用provide仅找当前的layout。(这段翻译坑爹,待我找人问问)

意译自api-rubyonrails

Comments

Copyright © 2013 robinhwang Redesgin by RobinHwang