追記(2022/11/24)
content_tag
は現在はレガシ記法とされており、それに代わってtag
メソッドの利用が推奨されています。本記事で紹介されているcontent_tag
メソッドのclass:
オプションやescape:
オプションもtag
メソッドで利用できます。
参考: Rails API tag
-- ActionView::Helpers::TagHelper
また、tag('dev')
のようなレガシ記法ではなく、tag.dev
のような記法が推奨されています。後者はHTML 5に対応しています。
詳しくは以下の記事をどうぞ。
Rails tips: ビューのcontent_tag
のあまり知られていないオプション(翻訳)
一般に、RailsアプリでHTMLコードを生成する方法は主に2つあります。HTMLコードを直に書く方法と、ActionView
モジュールのヘルパーでHTMLを生成する方法です。今回は後者の中からcontent_tag
ヘルパーを取り上げたいと思います。このヘルパーには、あまり知られていないオプションがいくつかあります。
Railsコンソールを実行してActionView::Helpers::TagHelper
モジュールやActionView::Context
モジュールをinclude
して、これらのオプションを確かめてみましょう。1番目のモジュールはcontent_tag
ヘルパーにアクセスできるようにするために、2番目のモジュールはネストしたタグをテストできるようにするためにそれぞれinclude
します。
基本的な使い方
content_tag
ヘルパーでは引数が1つ以上必要です。1番目の引数である要素名は省略できません。
content_tag(:div)
#=> "< div >< /div >"
2番目の引数には要素のコンテンツを渡せます。
content_tag(:div, "content")
#=> "< div >content< /div >"
これだけでは力不足なのであれば、ネストしたタグを渡せます。
content_tag(:div) do
content_tag(:strong, "header")
end
#=> "< div >< strong >header< /strong >< /div >"
属性
要素にはこの他にもオプションを渡せます。よく使われているのはclass
です。これも試してみましょう。
content_tag(:div, "header", class: 'link')
#=> "< div class="link" >header< /div >"
場合によってはクラス名を動的に渡す必要が生じることもあります。その場合、クラス名がなければ空文字ではなくnil
を渡すことが重要です。理由は次のコードに示しました。
content_tag(:div, "header", class: "")
#=> < div class="" >header< /div >
content_tag(:div, "header", class: nil)
#=> "< div >header< /div >"
複数のクラスをまとめて渡すこともできます。
content_tag(:div, "header", class: ["one", "two"])
#=> "< div class="one two" >header< /div >"
属性のエスケープ
属性はデフォルトでエスケープされるので、(たとえばユーザーがリッチテキストエディタで入力できるようにした場合にデータベースに保存されている)生のHTMLコードを属性として渡しても、出力はエスケープされます。
content_tag(:div, "")
おそらくこんな出力は欲しくないでしょう。ありがたいことに、こんなときのための4番目のオプションがあります。このオプションは属性をエスケープするかどうかの指定で、デフォルトではtrue
になっています。
content_tag(:div, "", {}, false) #=> < div >< div >< /div >< /div >
以上です。content_tag
ヘルパーはちっぽけですがビューでとても便利ですので、機能を詳しく知っておくと何かと役に立ちます。
RSpec & TDDの電子書籍を無料でダウンロード
もっと稼ぎたい方や会社をさらに発展させたい方へ: テスティングのスキルの重要性にお気づきでしょうか?テストを正しく書き始めることが、唯一のファーストステップです。無料でダウンロードいただける私の書籍『RSpec & Test Driven Developmentの無料ebook』をどうぞお役立てください。
概要
原著者の許諾を得て翻訳・公開いたします。