[英]How do I yield results from multiple statements in a Ruby block?
I have a pair of Rails helpers, one of which is meant to accept a block and the other of which just renders a button. 我有一对Rails助手,其中一个是用来接受一个块的,另一个是用来渲染按钮的。 Here are simplified versions the helper definitions: 这是帮助程序定义的简化版本:
def nav_wrapper(nav_at, id, css_class, &block)
"<ul class="complicated">\n #{yield} \n</ul>".html_safe
end
def nav_btn(nav_at, caption, id = caption.downcase.dasherize)
"Nav button codes goes here".html_safe
end
I'm trying to set things up such that I can do something like this: 我正在尝试进行设置,以便可以执行以下操作:
<%= nav_wrapper(@nav_at, "Top Nav", "class") do %>
<%= nav_btn(@nav_at, "Foo", "id") %>
<%= nav_btn(@nav_at, "Bar", "id") %>
<%= nav_wrapper(@nav_at, "Sub Nav", "class") do %>
<%= nav_btn(@nav_at, "SubFoo", "id") %>
<%= nav_btn(@nav_at, "SubBar", "id") %>
<% end %>
<% end %>
But, the yield
in the nav_wrapper
method only picks up the last statement of each block. 但是,该yield
在nav_wrapper
方法只挑选了每个块的最后一条语句。 So in this example, I get the Top Nav wrapper, Foo and Bar are skipped, I get the Sub Nav wrapper (being the last statement in the outer nav_wrapper
block), SubFoo is skipped, and I get SubBar (being the last statement in the inner nav_wrapper
block). 所以在这个例子中,我得到了Top Nav包装器,Foo和Bar被跳过,Sub Nav包装器(在外部nav_wrapper
块中的最后一条语句),SubFoo被跳过,SubBar(在内部nav_wrapper
块)。
I know that the reason for this behavior is that the block of code is implicitly returning the last evaluated value, but I know there are lots of template helpers that render all the interstitial lines ( form_for
, for example). 我知道发生这种情况的原因是代码块隐式返回了最后一个求值,但是我知道有很多模板助手可以渲染所有插页式广告行(例如, form_for
)。 Can someone help me figure out what the magic trick is here? 有人可以帮我弄清楚这里的魔术吗?
When a ERB template is compiled, it is converted to code which adds strings to a buffer. 编译ERB模板时,它将转换为将字符串添加到缓冲区的代码。 (Look at the source code for ERB to see what I mean.) Methods from Action View like form_for
execute the block, and then retrieve the text in the ERB buffer. (查看ERB的源代码以了解我的意思。)动作视图中的方法(如form_for
执行该块,然后在ERB缓冲区中检索文本。
Open up the lib/ruby/1.9.1/gems/1.9.1
folder, and look for actionpack. 打开lib/ruby/1.9.1/gems/1.9.1
文件夹,然后查找actionpack。 Open up whatever version of Action Pack you have, and go to lib/action_view/helpers/capture_helper.rb
. 打开任何版本的Action Pack,然后转到lib/action_view/helpers/capture_helper.rb
。 There is a method in there called capture
, which is used by form_for
to execute a block and retrieve the text generated by ERB. 那里有一个叫做capture
的方法, form_for
使用它来执行一个块并检索ERB生成的文本。
If you are writing a Rails helper, then presumably capture
will be available to your code. 如果您正在编写Rails助手,那么大概capture
将可用于您的代码。 If not, try include ActionView::Helpers::CaptureHelper
. 如果不是,请尝试include ActionView::Helpers::CaptureHelper
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.