6

Viget Labs は、 url が現在のパスと一致する場合に特定のクラス (または など) をナビゲーション リンクに追加するための Rails ヘルパー メソッドの詳細を説明する記事要点を投稿しました。.selected.active

次のようにレイアウトで使用できます。

= nav_link "News", articles_path, {class: "btn btn-small"}

<!-- which creates the following html -->

<a href="/articles" class="btn btn-small selected">News</a>

良い。私はブートストラップを使用していて、ボタンにアイコンを入れたいので、次の html を生成する必要があります。

<a href="/articles" class="btn btn-small selected"><i class="icon-home"> </i> News</a>

は要点をフォークし、それを行う簡単な方法を見つけました。私のフォークにより、開発者は次のように:inner_html:inner_classをヘルパーに渡すことができます。

= nav_link "News", articles_path, {class: "btn btn-small"}, {inner_html: 'i', inner_class: 'icon-home'}

それは正常に動作しますが、基になる実装が好きではありません:

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

ご覧のとおり、新しいオプションをcontent_taglink_to メソッドのブロック内に渡しています。いくつかの方法でリファクタリングできることを望んでいました。

まず第一に、私は自分の見解でこれを行うことができることを望みます:

= nav_link "News", articles_path, {class: "btn btn-small"} do
  %i.icon-home

オプションハッシュの属性としてではなく、ブロックとして内側のhtmlを与えたいです。これを達成する方法について誰かが私に何か指針を与えることができますか?

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

しかし、これはアイコンの出力に失敗し、代わりに数字 (4) を挿入します。はっきりわかりません。誰でもアドバイスをくれました。この種のことについて詳しく知りたい場合は、どこに行けばよいでしょうか。私は、stackoverflow で質問しなくても、このようなことを理解できるようになりたいと思っています。

4

2 に答える 2

4

私はあなたの問題を試しましたが、ヘルパーで次のことが完璧に機能しました:

  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

使用法:

my_link "No title", User.first do
  %i.icon-home 
于 2012-08-10T14:09:24.523 に答える
2

最終的な解決策は次のとおりでした。

# 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

リンク方法も変更する必要がありました。

def link
  if @block.present?
    link_to(@path, html_options) do
      @block.concat(@title)
    end
  else
    link_to(@title, @path, html_options)
  end
end

要点を更新しました。おそらくハックして、より複雑なブロックを受け入れることができます。

于 2012-08-11T05:24:59.807 に答える