ウェブサービスを作っています。

似たようなレイアウトを DRY に記述する

A と B というレイアウトがあって、どちらもほとんど同じレイアウトだけれども、微妙にいろんな箇所が違うという場合にどうするか考えてみました。


まず、骨格となる app/views/layouts/base.html.erb というファイルを作ります。ここには、A・B の共通部分を記述します。
異なっている部分には、名前付き yield を渡します。

app/views/layouts/base.html.erb

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
  <head>
    ...
  </head>

  <body><a name="top" id="top"></a>
    <%= yield :top %>
    <div id="wrapper">
      <div id="contentsLeft">
        <%= yield %>
      </div>
      <div id="contentsRight">
        <%= yield :contents_right %>
      </div>
    </div>
  </body>
</html>


次に、content_for を記述した実際のレイアウトファイルを作ります。
各ファイルの末尾で、base.html.erb を読み込むようにします。

app/views/layouts/a.html.erb

<%- content_for :top do -%>
  A:top 部分
<%- end -%>

<%- content_for :contents_right do -%>
  A:contents_right 部分
<%- end -%>

<%= render :file => 'layouts/base.html.erb' %>

app/views/layouts/b.html.erb

<%- content_for :top do -%>
  B:top 部分
<%- end -%>

<%- content_for :contents_right do -%>
  B:contents_right 部分
<%- end -%>

<%= render :file => 'layouts/base.html.erb' %>


あとは、各コントローラでレイアウトを選択するだけです。