追記(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』をどうぞお役立てください。
概要
原著者の許諾を得て翻訳・公開いたします。