Razorでレイアウトを使用
前回のブログ投稿で、製品カテゴリの一覧を描画する/ProductsというURLの実装方法を簡単に検証しました。
以下は簡単なProductsController実装で、上記の/ProductsというURLを実装します。これは、データベースから製品のカテゴリー一覧を取得し、それらをビューファイルへ渡し、適切なHTMLを描画して、ブラウザに返します。
これが、(Razorを使用して実装された)「Index.cshtml」ビューファイルの様子です。
上記のビューファイルは、まだレイアウトページを使用していません。つまり、今サイトにURLやページを追加すると、複数の場所に中核のサイトレイアウトを重複させることになります。レイアウトを使用すると、この重複が避けられ、サイト設計をより一層簡単に管理できるようになります。では、今から1つ使用してサンプルを更新してみましょう。
レイアウトを使用してリファクタリング
Razorにより、既存のページから始めて、レイアウトを使用し、リファクタリングすることが、非常に簡単になります。上記の簡単なサンプルを使用してやってみましょう。最初の手順は、「SiteLayout.cshtml」ファイルを、プロジェクトの「\Views\Shared」フォルダ(共通のビューファイル/テンプレートが置かれるデフォルトの場所)に追加します。
SiteLayout.cshtml
「SiteLayout.cshtml」ファイルを使用して、サイトの共通のコンテンツを定義します。以下はその例です。
上記のファイルに対する注意です。
- ファイルのトップに@inheritsディレクティブは(ASP.NET MVC 3ベータ版段階で)もう必要ありません。必要によりオプションで持つこともできますが(例えば、独自の基本クラスが必要など)、必須ではありません。これにより、ファイルはクリーンになります。また、デザイナーとデザイナー以外が、お互いが理解できない概念に戸惑うことなく、そのファイル上での作業が簡単にできるようにもなります。
- 上記のレイアウトファイル内で@RenderBodyメソッドを呼び出し、このレイアウトに基づいたビューで、HTML内で中核のコンテンツを『埋め込む』場所を示します。
- <head>セクションの<title>要素内に『View.Title』プロパティを出力します。少し後でこの方法を説明します。
これで共通のレイアウトテンプレートができたので、これを使用すれば、サイトのどのページでも統一感のある見た目と操作性が保てます。
Index.cshtml
では、今作成した「SiteLayout.cshtml」ファイルに基づいて、「Index.cshtml」ビューの更新をしてみましょう。以下は、まず最初の状態です。
上記ファイルについての注意です。
- ボディのメインコンテンツをタグや要素でくくる必要はありません。デフォルトで、Razorは、自動的に「Index.cshtml」のコンテンツを、そのレイアウトページの『body』セクションとして取り扱います。もしレイアウトが複数の置換可能範囲を持っている場合は、オプションで『名前付きセクション』を定義できます。しかし、Razorは、90%のケースで(ボディセクションでのみ必要な場合)、クリーンでシンプルにします。
- 上記の「Index.cshtml」ページ内で、View.Titleの値をプログラム的に設定します。「Index.cshtml」ファイル内のコードは、「SiteLayout.cshtml」コードが実行される前に実行されるため、プログラム的に値を設定するビューのコードを書き、それをレイアウトに引き渡して描画することができます。これは、特に、ページのタイトルの設定や、検索エンジン最適化(SEO)に対して、<head>内の<meta>要素を設定したい時に便利です。
- 今から、「Index.cshtml」ページ内で使用するレイアウトテンプレートを、プログラム的に設定していきます。これは、ビュー上のLayoutプロパティを設定すればできます(初回のプレビューでは、このプロパティを『LayoutPage』と呼んでいました。ASP.NET MVC 3ベータ版ではそれを『Layout』 に変更しただけです)。このプロパティの別の設定方法(ASP.NET MVC 3ベータ版での新機能)を後で説明します。
これで、サイト内で/ProductsというURLをリクエストすると、以下のHTMLが返されます。
上記でお分かりのように、返されるHTMLのコンテンツは、「SiteLayout.cshtml」と「Index.cshtml」のマージになります。トップにある『Product Categories』タイトルは、ビューに基づいて正確に設定されており、動的なカテゴリの一覧は、正確な場所に紐づけられています。