もくじ
テンプレートからlayoutを微妙に変えられるcontent_forとyield_content
たとえば、記事ページと一覧ページでサイドバーの内容を変えたい時、どうしますか?Layout側でIf文で出し分けるという方法もありますね。
でも、Middlemanではそのような場合はcontent_for
とyield_content
を使うとコードの見通しが良くなります。
公式ページのこのページにある例を少し変えて説明します。
layout.erb
1 2 3 4 5 6 7 8 9 |
<html> <head> <title>私のサイト</title> </head> <body> <%= yield %> <%= yield_content :sub_content %> </body> </html> |
hello.erb
1 2 3 4 |
<% content_for :sub_content %> <div>なんらかのコンテンツ</div> <% end %> <h1>Hello World</h1> |
こうすることで、最終的に以下のようなhtmlが生成されます。
1 2 3 4 5 6 7 8 9 |
<html> <head> <title>私のサイト</title> </head> <body> <h1>Hello World</h1> <div>なんらかのコンテンツ</div> </body> </html> |
テンプレートからcontent_for
でなんらかのコンテンツをセットしてあげて、レイアウト側から取り出すことができます。yield_content
のよい点は、仮にテンプレート側でcontent_for
で何もセットしていない場合、エラーにならず何も出力しないことです。
この仕組みによって、テンプレートからメインコンテンツ以外(たとえばサイドバーやメニュー)を微妙に変えたい時など、レイアウト側のコードをif文などで汚さずに、テンプレート側で書くことができます。あるべきコードがあるべきところにあり見通しが良くなります。
Nested Layout(入れ子レイアウト)でも使えるcontent_forとyield_content
Middlemanではwrap_layoutというヘルパーメソッドを使うことで、レイアウトを何重にも入れ子にすることができます。このNested Layout(入れ子レイアウト)でもcontent_forとyield_contentは大活躍します。
公式ドキュメントのこのページにある例を少し変更して説明します。ただ、erbだと現状Nested Layout(入れ子レイアウト)は動かないので、slimに変換して説明します。(erbだと動かない理由は以下をご覧ください)
入れ子の親が以下のようだとします。
layout.slim
1 2 3 4 5 6 7 |
html body header | ヘッダー = yield = yield_content :sub_content footer |
子は以下のようだとします。
article_layout.slim
1 2 3 4 5 |
- content_for :sub_content | なんらかのコンテンツ = wrap_layout :layout article = yield |
これで、子側で設定した:sub_content
に”なんらかのコンテンツ”という文字列がセットされ、親側のレイアウトで取り出すことができます。
階層構造としては、テンプレート→子レイアウト→親レイアウトとなります。子レイアウトが何重になっても大丈夫です。
個人的に柔軟で便利だと思うのは、下の階層でcontent_for
でセットしたコンテンツはそれより上ならどこの階層でもyield_content
で取り出してもOKです。なので、前述の例だと、テンプレートでセットしたものを、子レイアウトでも取り出してもいいし、親レイアウトで取り出してもOKです。
スポンサーリンク
content_forとwrap_layoutの順番に注意
子レイアウトでの書き方で注意しなければならない点があります。content_for
とwrap_layout
の順番です。以下のように、content_forを後ろに書くと親側で取り出すことができません。(何も出力されない。)
1 2 3 4 5 |
= wrap_layout :layout article = yield - content_for :sub_content | なんらかのコンテンツ |
まとめ
いかがでしたでしょうか。レイアウト側にif文などで全てのコンテンツを書いていた方は一度、content_for
とyield_content
やNested Layoutを試してみてはいかがでしょうか。コードがわかりやすくなり、メンテナンスしやすくなるのは間違いないです。
※Middlemanのバージョン: 3.4.0