■レイアウトに複数のコンテンツ領域を設置する
レイアウトでは、まずRenderBodyメソッドでメインのコンテンツ領域を表すのが基本だ。個別のビュー・スクリプトで記述された内容は、実行時に「@RenderBody()」と記述された部分に埋め込まれることになる。
もっとも、より複雑なサイトでは時として、複数のコンテンツ領域を持ちたいということもある。例えば、以下のようなケースである。
|
図3 複数のコンテンツ領域を必要とするケースのレイアウトも可 |
|
このようなケースに対応するのが、Razorのセクション機能だ。セクションは、レイアウトに埋め込めるサブのコンテンツ領域と考えればよいだろう。
例えば、以下はデフォルトのレイアウトに対して、ScriptCssセクションを追加した例だ。上の図3における(3)のようなケースを想定している。
<!DOCTYPE html>
<html>
<head>
……中略……
<script src="@Url.Content("~/Scripts/modernizr-1.7.min.js")"
type="text/javascript"></script>
@RenderSection("ScriptCss", false)
</head>
|
<!DOCTYPE html>
<html>
<head>
……中略……
<script src="@Url.Content("~/Scripts/modernizr-1.7.min.js")"
type="text/javascript"></script>
@RenderSection("ScriptCss", False)
</head>
|
|
リスト5 JavaScript/スタイルシートを埋め込むべきScriptCssセクションを定義したレイアウト(上:_Layout.cshtml、下:_Layout.vbhtml) |
レイアウトにセクション領域を定義するには、リスト5のようにRenderSectionメソッドを埋め込むだけだ。RenderSectionメソッドの構文は、以下のとおり。
RenderSection(string name [,bool required])
|
|
リスト6 RenderSectionメソッドの構文 |
name:セクション名
required:セクションが必須か(デフォルトはtrue) |
引数requiredがtrueの場合、個別のテンプレートでそのセクションは省略できなくなるので注意してほしい。今回のような例では、引数requiredはfalseとしておくべきだろう(いつもページ固有のJavaScript/スタイルシートが必要であるとは限らないからだ)。本稿ではセクションを1つだけ指定しているが、もちろん、必要に応じて複数のセクションを埋め込んでも構わない。
このようなセクション付きレイアウトに対してコンテンツを埋め込むには、テンプレート・ファイルで「@sectionブロック」を準備する。例えば以下は、標準で用意されているHome/About.cshtmlもしくはHome/About.vbhtmlに対してScriptCssセクションを追加した例だ。
@{
ViewBag.Title = "このサイトについて";
}
@section ScriptCss {
<link href="@Url.Content("~/Content/jquery-ui-1.8.13.custom.css")" rel="stylesheet" type="text/css" />
<script src="@Url.Content("~/Scripts/jquery-ui-1.8.11.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.ui.datepicker-ja.js")" type="text/javascript"></script>
}
<h2>このサイトについて</h2>
<p>
ここにコンテンツを置いてください。
</p>
|
@Code
ViewData("Title") = "このサイトについて"
End Code
@Section ScriptCss
<link href="@Url.Content("~/Content/jquery-ui-1.8.13.custom.css")" rel="stylesheet" type="text/css" />
<script src="@Url.Content("~/Scripts/jquery-ui-1.8.11.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.ui.datepicker-ja.js")" type="text/javascript"></script>
End Section
<h2>このサイトについて</h2>
<p>
ここにコンテンツを置いてください。
</p>
|
|
リスト7 個別のテンプレートにScriptCssセクションを追加したコード(上:About.cshtml、下:About.vbhtml) |
このように、セクションに埋め込むべきコンテンツを@sectionブロックでくくるわけだ。@section命令の構文は、以下のとおり。
@section name {
content
}
|
@Section name
content
End Section
|
|
リスト8 @section命令の構文(上:C#、下:VB) |
name:セクション名
content:セクションに埋め込むべきコンテンツ |
ちなみに、セクション領域以外のコンテンツ(=レイアウト上、RenderBodyで定義された領域)は、特別な囲みなどを意識することなく、これまでと同じく記述できる。
以上を理解できたら、Home/Aboutアクションにアクセスしてみよう。ブラウザの[ソースの表示]から確認すると、確かにScriptCssセクションで定義されたコンテンツが埋め込まれていることが見て取れる。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>このサイトについて</title>
<link href="/Content/Site.css"
rel="stylesheet" type="text/css" />
<script src="/Scripts/jquery-1.5.1.min.js"
type="text/javascript"></script>
<script src="/Scripts/modernizr-1.7.min.js"
type="text/javascript"></script>
<link href="/Content/jquery-ui-1.8.13.custom.css"
rel="stylesheet" type="text/css" />
<script src="/Scripts/jquery-ui-1.8.11.min.js"
type="text/javascript"></script>
<script src="/Scripts/jquery.ui.datepicker-ja.js"
type="text/javascript"></script>
</head>
<body>
|
|
リスト9 サンプルの実行結果を[ソースの表示]から確認したコード |
■レイアウトを入れ子に配置する
レイアウトは、入れ子に配置することも可能だ。例えば、以下は個別のテンプレートと、標準で用意されているレイアウト(_Layout.cshtml/_Layout.vbhtml)との間に、子レイアウトである_SubLayout.cshtml/_SubLayout.vbhtmlをかませた例である。
@{
Layout = "~/Views/Shared/_Layout.cshtml";
}
<img src="http://www.wings.msn.to/image/wings.jpg" />
<hr />
<div>
@RenderBody()
</div>
<hr />
Copyright WINGS Project, 2011
|
@Code
Layout = "~/Views/Shared/_Layout.vbhtml"
End Code
<img src="http://www.wings.msn.to/image/wings.jpg" />
<hr />
<div>
@RenderBody()
</div>
<hr />
Copyright WINGS Project, 2011
|
|
リスト10 入れ子のレイアウトを定義したコード(上:_SubLayout.cshtml、下:_SubLayout.vbhtml) |
レイアウトを入れ子にするとはいっても、ことさらに特別な構文を要するわけではない。あえていうならば、親レイアウトを呼び出すためにLayoutメソッドを呼び出している点が、子レイアウト固有のルールといえば、ルールだ*3。
あとは、個別のテンプレートが子レイアウトを見にいくように、_ViewStart.cshtml/_ViewStart.vbhtmlファイルを以下のように修正すればよい。
@{
Layout = "~/Views/Shared/_SubLayout.cshtml";
}
|
@Code
Layout = "~/Views/Shared/_SubLayout.vbhtml"
End Code
|
|
リスト11 子レイアウトを適用するための設定コード(上:_ViewStart.cshtml、下:_ViewStart.vbhtml) |
これで、
個別のテンプレート → 子レイアウト → 親レイアウト
の関連ができたので、さっそく、サンプルを確認してみよう。以下の図のように、確かにレイアウトが入れ子に適用されていることが確認できる。
|
図4 入れ子にしたレイアウトの適用結果 |
|
Insider.NET 記事ランキング
本日
月間