[英]Rails passing a block to a helper method
Viget Labs posted an article and gist detailing a rails helper method for adding a particular class (like .selected
or .active
) to a navigation link if it's url matches the current path. Viget的实验室发布的文章和要点 ,详细说明增加一个特别的类(如导轨helper方法
.selected
或.active
),如果它的URL的电流路径相匹配的导航链接。
You can use it in your layout like so: 您可以在布局中使用它,如下所示:
= nav_link "News", articles_path, {class: "btn btn-small"}
<!-- which creates the following html -->
<a href="/articles" class="btn btn-small selected">News</a>
Nice. 尼斯。 I'm using bootstrap, and want to have an icon in my button, so I need to generate the following html:
我正在使用bootstrap,并希望在我的按钮中有一个图标,所以我需要生成以下html:
<a href="/articles" class="btn btn-small selected"><i class="icon-home"> </i> News</a>
I forked the gist and figured out a simple way of doing it. 我分享了要点并想出了一个简单的方法。 My fork lets the developer pass :inner_html and :inner_class to the helper like so:
我的fork允许开发人员将:inner_html和:inner_class传递给helper,如下所示:
= nav_link "News", articles_path, {class: "btn btn-small"}, {inner_html: 'i', inner_class: 'icon-home'}
It works fine, but I don't like my underlying implementation: 它工作正常,但我不喜欢我的底层实现:
def link
if @options[:inner_html]
link_to(@path, html_options) do
content_tag(@options[:inner_html], '', :class => @options[:inner_class]) + " #{@title}"
end
else
link_to(@title, @path, html_options)
end
end
As you can see, I'm passing the new options to content_tag
inside the block of a link_to method. 如您所见,我将新选项传递给link_to方法块内的
content_tag
。 I was hoping I would be able to refactor it in a few ways. 我希望我能够通过几种方式重构它。
First of all, I'd prefer to be able to do this in my view: 首先,我希望能够在我看来做到这一点:
= nav_link "News", articles_path, {class: "btn btn-small"} do
%i.icon-home
I want to give the inner html as a block, and not as attributes of the option hash. 我想将内部html作为块,而不是选项哈希的属性。 Can anyone give me any pointers on how to achieve this?
任何人都可以给我任何关于如何实现这一点的指示?
I thought it would a simple case of telling the nav_link method to accept a block: 我认为告诉nav_link方法接受一个块是一个简单的例子:
def nav_link(title, path, html_options = {}, options = {}, &block)
LinkGenerator.new(request, title, path, html_options, options, &block).to_html
end
class LinkGenerator
include ActionView::Helpers::UrlHelper
include ActionView::Context
def initialize(request, title, path, html_options = {}, options = {}, &block)
@request = request
@title = title
@path = path
@html_options = html_options
@options = options
@block = block
end
def link
if @block.present?
link_to @path, html_options do
@block.call
@title
end
end
end
But this fails to output the icon, and instead inserts a number (4). 但是这无法输出图标,而是插入一个数字(4)。 I don't get it clearly.
我不清楚。 Anyone got any advice.
任何人都有任何建议。 Where can I go to read more about this sort of thing, as I really want to be able to figure stuff like this out without having to ask on stackoverflow.
我在哪里可以阅读更多有关此类事情的内容,因为我真的希望能够在不必询问stackoverflow的情况下找出这样的内容。
I tried your problem and the following worked for me perfectly, in the helper: 我试过你的问题,以下内容对我很有帮助:
def my_link(title, path, &block)
if block_given?
link_to path do
block.call
concat(title)
end
else
link_to title, path
end
end
Usage: 用法:
my_link "No title", User.first do
%i.icon-home
The solution in the end was as follows: 最终的解决方案如下:
# capture the output of the block, early on if block_given?
def nav_link(title, path, html_options = {}, options = {}, &block)
LinkGenerator.new(request, title, path, html_options, options, (capture(&block) if block_given?)).to_html
end
I also had to modify my link method: 我还必须修改我的链接方法:
def link
if @block.present?
link_to(@path, html_options) do
@block.concat(@title)
end
else
link_to(@title, @path, html_options)
end
end
I've updated my gist . 我更新了我的要点 。 You could probably hack it up to accept more complex blocks.
你可能会破解它以接受更复杂的块。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.