LayoutとRendering
今回は View について説明していきます。 Layouts and Rendering in Rails および、 Railsドキュメント を参考にしました。
ERBの基本
HTML などに Ruby のスクリプトを埋め込むことによって出力結果を動的に変更するのが ERB です。
すべてのビューは app/view
以下のディレクトリに格納されています。
基本的なタグ
以下にコードを埋め込むために利用するタグの書き方を掲載します。
出力しない
<% ~ %>
戻り値を出力
<%= ~ %>
戻り値をエスケープしないで出力
<%== ~ %>
後ろの改行を取り除いて戻り値を出力
<% ~ -%>
行頭までの空白を削除して戻り値を出力
<%- ~ %>
コメント
<%# ~ %>
ビューの変数
ビュー内でコントローラのインスタンス変数にアクセスすることが出来ます。
@変数名
ビューの選択
デフォルトでは、コントローラは自動的にルーティングに対応したビューを使います。
例えば、 BooksController
でアクション index
が /app/controllers/books_controllers.rb
に記述してあり、ルーティングファイルに resources :books
とある場合、index
が呼ばれたときは自動的に app/views/books/index.html.erb
をレンダリングします。
基本的に利用されるビューは action_name.html.erb
です。
ビューを明示的に指定
使用するビューを明示的に指定するためには、 render
メソッドを利用します。
何もレンダリングしない場合
render :nothing => true
アクションに関連付けられたビューを使う場合
render "edit"
render :edit
render :action => "edit"
上記の例では、 edit
のビューがレンダリングに使用されます。
異なるコントローラーのビューを使う場合
render "products/show"
render :templete => "products/show"
上記のようにすることで、 app/views/products/show.html.erb
がテンプレートとして使われます。
全く別のビューを使う場合
render "/rails/another/app/views/products/views.html.erb"
render :file => "/rails/another/app/views/products/views.html.erb"
上記の記述ではサーバー上の /rails/another/app/views/products/views.html.erb
をテンプレートとして利用します。このように絶対パスでビューを指定することも出来ます。
テキストのレンダリング
以下のように記述すると一切マークアップされていないテキストをレンダリングします。
render :text => "OK"
JSONを生成
JSONフォーマットのデータをブラウザに返したい場合は、以下のように記述します。
to_json
を呼ぶ必要はありません。
render :json => @product
XMLを生成
XMLフォーマットのデータをブラウザに返したい場合は、以下のように記述します。
to_xml
を呼ぶ必要はありません。
render :xml => @product
JavaScriptの生成
JavaScriptをレンダリングしたい場合は、以下のように記述します。 MIME type は自動的に埋め込まれます。
render :js => "alert('Hello Rails')"
リダイレクト
リダイレクトするには以下のように、 redirect_to
に文字列でリダイレクト先を渡します。ここではヘルパーメソッドを利用しています。
redirect_to photos_url
もし、前のページに戻すためには :back
を引数に指定します。
redirect_to :back
レイアウト
デフォルトではレイアウトは app/views/layouts
の中のコントローラと同じ名前のものが使われます。
例えば、 PhotosController クラスの場合は app/views/layouts/photos.html.erb
もしくは app/views/layouts/photos.builder
が使われます。
もし、上記のようなファイルが見つからなかった場合は、 app/views/layouts/application.html.erb
もしくは app/views/layouts/application.builder
が使われます。
コントローラ内でのレイアウトの指定
コントローラ内で利用するレイアウトを上書きすることが出来ます。指定したレイアウト名が app/views/layouts/
ディレクトリ内から検索されます。
class ProductsController < ApplicationController
layout "inventory"
#...
end
上記の例では、 app/views/layouts/inventory.html.erb
が利用されます。
レイアウトをrenderで指定
render
メソッドにオプションとして :layout
を指定することで、レイアウトを指定することが出来ます。
以下のように記述することで、 app/views/layouts/special_layout.html.erb
をレイアウトとして利用することが出来ます。
render :layout => 'special_layout'
また、以下のように、 :layout => false
とすることで、レイアウトを全く利用しないレンダリングを行うことが出来ます。
render :layout => false
部分テンプレート
レンダリング部分を分割して再利用性を高めるのに、部分テンプレートが便利に使えます。
部分テンプレートの名前は必ずアンダーバー(_)で始まります。
例えばビュー内で、
<%= render "menu" %>
と記述することで、 _menu.html.erb
が部分テンプレートとして使われます。
以下のように記述した場合は、 app/views/shared/_menu.html.erb
が部分テンプレートとして利用されます。
<%= render "shared/menu" %>
レンダリングとレイアウト
レンダリングを行う場合は現在のレイアウトとビューを組み合わせて行われます。
レイアウトでは通常のビューで利用できるタグを生成する関数、部分テンプレートに加えて、 yeild
や、 content_for
を利用することが出来ます。
タグ生成関数
Rails ではタグを生成するためのヘルパーが用意されています。例えば以下のようなものがあります。
auto_discovery_link_tag
javascript_include_tag
stylesheet_link_tag
image_tag
video_tag
audio_tag
yield
レイアウト内で、 yield
を利用すると、その部分に現在レンダリングしようとしているビュー内容が埋め込まれます。
例えば以下のように使います。
<html>
<head>
</head>
<body>
<%= yield %>
</body>
</html>
複数回 yield
を使うことも出来ます。
<html>
<head>
<%= yield :head %>
</head>
<body>
<%= yield %>
</body>
</html>
yield :head
のような名前付き yield の中身をレンダリングするには、 content_for
メソッドを利用します。
content_for
先ほどの名前付き yield
の中身をビュー側で指定するために、 content_for
を利用します。
例えば、先ほどのレイアウトを使って、以下のようなビューをレンダリングすることを考えます。
<% content_for :head do %>
<title>A simple page</title>
<% end %>
<p>Hello, Rails!</p>
これをレンダリングすると以下のようになります。
<html>
<head>
<title>A simple page</title>
</head>
<body>
<p>Hello, Rails!</p>
</body>
</html>