2011年7月28日木曜日

railsでネストしたレイアウトを実現する

railsのviewはレイアウト機能があり、画面の共通化が可能です。

・画面のイメージ・レイアウトを共通化する
・メニューを表示する
...etc

非常に便利な機能ですが、「サイト全体で画面のイメージを共通化しつつ、XXX機能でも共通のレイアウトにする」事が簡単にはできないと思っていました(レイアウトの二重適用)。
ところがRuby on Rails Guidesに実現方法がのっていました。非常に簡単なのでご紹介しておきます。

■application.html.erb (全体的な共通レイアウト)

<html>
<head>
  <title><%= @page_title or 'Page Title' %></title>
  <%= stylesheet_link_tag 'layout' %>
  <style type="text/css"><%= yield :stylesheets %></style>
</head>
<body>
  <div id="top_menu">Top menu items here</div>
  <div id="menu">Menu items here</div>
  <div id="content"><%= content_for?(:content) ? yield(:content) : yield %></div>
</body>
</html>
上記のポイントは二つ。

・yield :stylesheets
=> 機能側で定義したstylesheetをheadタグ内にレンダリングする例です
・content_for?(:content) ? yield(:content) : yield
=> 機能側で:contentがある場合は引数にしてyield、無い場合通常のyield

■news.html.erb(機能毎レイアウト)

<% content_for :stylesheets do %>
  #top_menu {display: none}
  #right_menu {float: right; background-color: yellow; color: black}
<% end %>
<% content_for :content do %>
  <div id="right_menu">Right menu items here</div>
  <%= yield(:news_content) or yield %>
<% end %>
<%= render :file => 'layouts/application' %>
・content_for :stylesheets
=>上記のstylesheetを準備します。同じようにjavascriptも定義可能です。
・content_for :content / yield(:news_content) or yield
=> :contentを定義し、更に:news_contentがある場合は引数にしてyield、無い場合通常のyield
・render :file => 'layouts/application'
=> 上記contentを準備して、全体レイアウトをレンダリング

■xxx.html.erb(各画面)

<h1>タイトル</h1>
...

各画面固有のレンダリング内容

■xxx_controller.rb

class XxxController < ApplicationController
   layout "news"
   def xxx
   end
end

layoutで機能毎共通レイアウトを指定
上記の様に設定すると
application.html.erb
  news.html.erb
    xxx.html.erb

とネストしたレンダリング可能です!

■備考

2011/07/21 22:06 なんてこったい! Rails3レシピブックにのっているじゃないか(^_^;)

0 件のコメント:

コメントを投稿