Railsで「特定の条件の時だけ div 要素でラップする」みたいなヘルパーを作りました。
module MyHelper
def wrap_if(condition, ...)
# false の時は、何も加工せずにブロックで渡されたHTMLを描画したい
return yield unless condition
# true の時は div 要素でラップする
tag.div(...) { yield }
end
end
<%= wrap_if(@flag, class: 'wrapper') do %>
<p>こんにちは!</p>
<% end %>
しかし、実際に動かしてみると、条件が false のとき、ブロックで渡したHTMLが2回描画されるという結果に・・・
結果
<!-- false のとき2重で描画される。2回目は何故かエスケープされる -->
<p>こんにちは!</p>
<p>こんにちは!</p>
<!-- true のときはOK -->
<div class="wrapper">
<p>こんにちは!</p>
</div>
こういうときは capture を使って String オブジェクトに変換すると良いらしいです。
module MyHelper
def wrap_if(condition, ...)
content = capture { yield }
return content unless wrap
tag.div(content, ...)
end
end
ドキュメント:
https://api.rubyonrails.org/classes/ActionView/Helpers/CaptureHelper.html#method-i-capture