Commit 3e8b9edc by Nobuo Kihara

docs/guide-ja/structure-views.md - revised [ci skip]

parent fc477860
...@@ -3,9 +3,8 @@ ...@@ -3,9 +3,8 @@
ビューは [MVC](http://ja.wikipedia.org/wiki/Model_View_Controller) アーキテクチャの一部を成すものです。 ビューは [MVC](http://ja.wikipedia.org/wiki/Model_View_Controller) アーキテクチャの一部を成すものです。
ビューはエンドユーザにデータを表示することに責任を持つコードです。 ビューはエンドユーザにデータを表示することに責任を持つコードです。
ウェブアプリケーションにおいては、ビューは、通常、主として HTML コードと表示目的の PHP コードを含む PHP スクリプトファイルである、 ウェブアプリケーションにおいては、ビューは、通常、主として HTML コードと表示目的の PHP コードを含む PHP スクリプトファイルである、*ビューテンプレート* の形式で作成されます。
*ビューテンプレート* の形式で作成されます。 そして、ビューテンプレートを管理する [[yii\web\View|ビュー]] [アプリケーションコンポーネント](structure-application-components.md) が、
そして、ビューテンプレートを管理する [[yii\web\View|ビュー]] [アプリケーションコンポーネント](structure-application-components.md) は、
ビューの構築とレンダリングを助けるためによく使われるメソッドを提供します。 ビューの構築とレンダリングを助けるためによく使われるメソッドを提供します。
なお、簡潔さを重視して、ビューテンプレートまたはビューテンプレートファイルを単にビューと呼ぶことがよくあります。 なお、簡潔さを重視して、ビューテンプレートまたはビューテンプレートファイルを単にビューと呼ぶことがよくあります。
...@@ -38,25 +37,22 @@ $this->title = '繝ュ繧ー繧、繝ウ'; ...@@ -38,25 +37,22 @@ $this->title = '繝ュ繧ー繧、繝ウ';
<?php ActiveForm::end(); ?> <?php ActiveForm::end(); ?>
``` ```
ビューの中でアクセスできる `$this` は、このビューテンプレートを管理しレンダリングしている ビューの中でアクセスできる `$this` は、このビューテンプレートを管理しレンダリングしている [[yii\web\View|ビューコンポーネント]] を参照します。
[[yii\web\View|ビューコンポーネント]] を参照します。
`$this` 以外に、上記の例の `$model` のように、前もって定義された変数がビューの中にあることがあります。 `$this` 以外に、上記の例の `$model` のように、前もって定義された変数がビューの中にあることがあります。
このような変数は、[コントローラ](structure-controllers.md) または [ビューのレンダリング](#rendering-views) をトリガするオブジェクトによってビューに *プッシュ* されたデータを表します。 このような変数は、[コントローラ](structure-controllers.md) または [ビューのレンダリング](#rendering-views) をトリガするオブジェクトによってビューに *プッシュ* されたデータを表します。
> Tip|ヒント: 上の例では、事前に定義された変数は、IDE に認識されるように、 > Tip|ヒント: 上の例では、事前に定義された変数は、IDE に認識されるように、ビューの先頭のコメントブロックの中にリストされています。
ビューの先頭のコメントブロックの中にリストされています。これは、ビューに これは、ビューにドキュメントを付けるのにも良い方法です。
ドキュメントを付けるのにも良い方法です。
### セキュリティ <a name="security"></a> ### セキュリティ <a name="security"></a>
HTML ページを生成するビューを作成するときは、エンドユーザから受け取るデータを HTML ページを生成するビューを作成するときは、エンドユーザから受け取るデータを表示する前にエンコード および/または フィルタすることが重要です。
表示する前に エンコード および/または フィルター することが重要です。
そうしなければ、あなたのアプリケーションは [クロスサイトスクリプティング](http://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%AD%E3%82%B9%E3%82%B5%E3%82%A4%E3%83%88%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0) 攻撃をこうむるおそれがあります。 そうしなければ、あなたのアプリケーションは [クロスサイトスクリプティング](http://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%AD%E3%82%B9%E3%82%B5%E3%82%A4%E3%83%88%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0) 攻撃をこうむるおそれがあります。
平文テキストを表示するためには、まず [[yii\helpers\Html::encode()]] を呼んでエンコードします。 平文テキストを表示するためには、まず [[yii\helpers\Html::encode()]] を呼んでエンコードします。
例えば、次のコードはユーザの名前を表示する前にエンコードしています: 例えば、次のコードはユーザの名前を表示する前にエンコードしています。
```php ```php
<?php <?php
...@@ -68,8 +64,8 @@ use yii\helpers\Html; ...@@ -68,8 +64,8 @@ use yii\helpers\Html;
</div> </div>
``` ```
HTML コンテンツを表示するためには、[[yii\helpers\HtmlPurifier]] を使って、最初にコンテンツをフィルターします。 HTML コンテンツを表示するためには、[[yii\helpers\HtmlPurifier]] を使って、最初にコンテンツをフィルタします。
例えば、次のコードは、投稿のコンテンツを表示する前にフィルターしています: 例えば、次のコードは、投稿のコンテンツを表示する前にフィルタしています。
```php ```php
<?php <?php
...@@ -81,28 +77,22 @@ use yii\helpers\HtmlPurifier; ...@@ -81,28 +77,22 @@ use yii\helpers\HtmlPurifier;
</div> </div>
``` ```
> Tip|ヒント: HTMLPurifier は、出力を安全なものにすることにおいては素晴らしい仕事をしますが、 > Tip|ヒント: HTMLPurifier は、出力を安全なものにすることにおいては素晴らしい仕事をしますが、速くはありません。
速くはありません。アプリケーションが高いパフォーマンスを要求する場合は、 アプリケーションが高いパフォーマンスを要求する場合は、フィルター結果を [キャッシュ](caching-overview.md) することを考慮すべきです。
フィルター結果を [キャッシュ](caching-overview.md) することを考慮すべきです。
### ビューを整理する <a name="organizing-views"></a> ### ビューを整理する <a name="organizing-views"></a>
[コントローラ](structure-controllers.md)[モデル](structure-models.md) と同じように、 [コントローラ](structure-controllers.md)[モデル](structure-models.md) と同じように、ビューを整理するための規約があります。.
ビューを整理するための規約があります。.
* コントローラによって表示されるビューは、既定では、ディレクトリ * コントローラによって表示されるビューは、既定では、ディレクトリ `@app/views/ControllerID` の下に置かれるべきものです。
`@app/views/ControllerID` の下に置かれるべきものです。
ここで、`ControllerID`[コントローラ ID](structure-controllers.md#routes) を指します。 ここで、`ControllerID`[コントローラ ID](structure-controllers.md#routes) を指します。
例えば、コントローラクラスが `PostController` である場合、ディレクトリは `@app/views/post` 例えば、コントローラクラスが `PostController` である場合、ディレクトリは `@app/views/post` となります。
となります。`PostCommentController` の場合は、ディレクトリは `@app/views/post-comment` です。 `PostCommentController` の場合は、ディレクトリは `@app/views/post-comment` です。
また、コントローラがモジュールに属する場合は、ディレクトリは [[yii\base\Module::basePath|モジュールディレクトリ]] また、コントローラがモジュールに属する場合は、ディレクトリは [[yii\base\Module::basePath|モジュールディレクトリ]] の下の `views/ControllerID` です。
の下の `views/ControllerID` です。 * [ウィジェット](structure-widgets.md) で表示されるビューは、既定では、`WidgetPath/views` ディレクトリの下に置かれるべきものです。
* [ウィジェット](structure-widgets.md) で表示されるビューは、既定では、`WidgetPath/views` ここで、`WidgetPath` は、ウィジェットのクラスファイルを含んでいるディレクトリを指します。
ディレクトリの下に置かれるべきものです。ここで、`WidgetPath` は、ウィジェットのクラスファイル * 他のオブジェクトによって表示されるビューについても、ウィジェットの場合と同じ規約に従うことが推奨されます。
を含んでいるディレクトリを指します。
* 他のオブジェクトによって表示されるビューについても、ウィジェットの場合と同じ規約に従うことが
推奨されます。
これらの既定のビューディレクトリは、コントローラやウィジェットの [[yii\base\ViewContextInterface::getViewPath()]] これらの既定のビューディレクトリは、コントローラやウィジェットの [[yii\base\ViewContextInterface::getViewPath()]]
メソッドをオーバーライドすることでカスタマイズすることが可能です。 メソッドをオーバーライドすることでカスタマイズすることが可能です。
...@@ -110,14 +100,13 @@ use yii\helpers\HtmlPurifier; ...@@ -110,14 +100,13 @@ use yii\helpers\HtmlPurifier;
## ビューをレンダリングする <a name="rendering-views"></a> ## ビューをレンダリングする <a name="rendering-views"></a>
[コントローラ](structure-controllers.md) の中でも、[ウィジェット](structure-widgets.md) の中でも、 [コントローラ](structure-controllers.md) の中でも、[ウィジェット](structure-widgets.md) の中でも、または、その他のどんな場所でも、
または、その他のどんな場所でも、ビューをレンダリングするメソッドを呼ぶことによって ビューをレンダリングするメソッドを呼ぶことによってビューをレンダリングすることが出来ます。
ビューをレンダリングすることが出来ます。
これらのメソッドは、下記に示されるような類似のシグニチャを共有します。 これらのメソッドは、下記に示されるような類似のシグニチャを共有します。
``` ```
/** /**
* @param string $view ビュー名またはファイルパス、実際のレンダリングメソッドに依存する * @param string $view ビュー名またはファイルパス (実際のレンダリングメソッドに依存する)
* @param array $params ビューに引き渡されるデータ * @param array $params ビューに引き渡されるデータ
* @return string レンダリングの結果 * @return string レンダリングの結果
*/ */
...@@ -127,20 +116,14 @@ methodName($view, $params = []) ...@@ -127,20 +116,14 @@ methodName($view, $params = [])
### コントローラでのレンダリング <a name="rendering-in-controllers"></a> ### コントローラでのレンダリング <a name="rendering-in-controllers"></a>
[コントローラ](structure-controllers.md) の中では、ビューをレンダリングするために [コントローラ](structure-controllers.md) の中では、ビューをレンダリングするために次のコントローラメソッドを呼ぶことが出来ます。
次のコントローラメソッドを呼ぶことが出来ます:
* [[yii\base\Controller::render()|render()]]: [名前付きビュー](#named-views) をレンダリングし、 * [[yii\base\Controller::render()|render()]]: [名前付きビュー](#named-views) をレンダリングし、その結果に [レイアウト](#layouts) を適用する。
その結果に [レイアウト](#layouts) を適用する。 * [[yii\base\Controller::renderPartial()|renderPartial()]]: [名前付きビュー](#named-views) をレイアウトなしでレンダリングする。
* [[yii\base\Controller::renderPartial()|renderPartial()]]: [名前付きビュー](#named-views) * [[yii\web\Controller::renderAjax()|renderAjax()]]: [名前付きビュー](#named-views) をレイアウトなしでレンダリングし、登録されている全ての JS/CSS スクリプトおよびファイルを注入する。
レイアウトなしでレンダリングする。
* [[yii\web\Controller::renderAjax()|renderAjax()]]: [名前付きビュー](#named-views)
レイアウトなしでレンダリングし、登録されている全ての JS/CSS スクリプトおよびファイルを注入する。
通常、AJAX ウェブリクエストに対するレスポンスにおいて使用される。 通常、AJAX ウェブリクエストに対するレスポンスにおいて使用される。
* [[yii\base\Controller::renderFile()|renderFile()]]: ビューファイルのパスまたは [エイリアス](concept-aliases.md) * [[yii\base\Controller::renderFile()|renderFile()]]: ビューファイルのパスまたは [エイリアス](concept-aliases.md) の形式で指定されたビューをレンダリングする。
の形式で指定されたビューをレンダリングする。 * [[yii\base\Controller::renderContent()|renderContent()]]: 静的な文字列をレンダリングして、現在適用可能な [レイアウト](#layouts) に埋め込む。このメソッドは バージョン 2.0.1 以降で使用可能。
* [[yii\base\Controller::renderContent()|renderContent()]]: 現在適用可能な [レイアウト](#layouts) に埋め込むことによって、
静的な文字列をレンダリングする。このメソッドは バージョン 2.0.1 以降で使用可能。
例えば、 例えば、
...@@ -172,12 +155,10 @@ class PostController extends Controller ...@@ -172,12 +155,10 @@ class PostController extends Controller
### ウィジェットでのレンダリング <a name="rendering-in-widgets"></a> ### ウィジェットでのレンダリング <a name="rendering-in-widgets"></a>
[ウィジェット](structure-widgets.md) の中では、ビューをレンダリングするために、 [ウィジェット](structure-widgets.md) の中では、ビューをレンダリングするために、次のウィジェットメソッドを使用することが出来ます。
次のウィジェットメソッドを使用することが出来ます。
* [[yii\base\Widget::render()|render()]]: [名前付きのビュー](#named-views) をレンダリングする。 * [[yii\base\Widget::render()|render()]]: [名前付きのビュー](#named-views) をレンダリングする。
* [[yii\base\Widget::renderFile()|renderFile()]]: ビューファイルのパスまたは [エイリアス](concept-aliases.md) * [[yii\base\Widget::renderFile()|renderFile()]]: ビューファイルのパスまたは [エイリアス](concept-aliases.md) の形式で指定されたビューをレンダリングする。
の形式で指定されたビューをレンダリングする。
例えば、 例えば、
...@@ -204,19 +185,15 @@ class ListWidget extends Widget ...@@ -204,19 +185,15 @@ class ListWidget extends Widget
### ビューでのレンダリング <a name="rendering-in-views"></a> ### ビューでのレンダリング <a name="rendering-in-views"></a>
[[yii\base\View|ビューコンポーネント]] によって提供される下記のメソッドのどれかを使うと、 [[yii\base\View|ビューコンポーネント]] によって提供される下記のメソッドのどれかを使うと、ビューの中で、別のビューをレンダリングすることが出来ます。
ビューの中で、別のビューをレンダリングすることが出来ます:
* [[yii\base\View::render()|render()]]: [名前付きのビュー](#named-views) をレンダリングする。 * [[yii\base\View::render()|render()]]: [名前付きのビュー](#named-views) をレンダリングする。
* [[yii\web\View::renderAjax()|renderAjax()]]: [名前付きビュー](#named-views) をレンダリングし、 * [[yii\web\View::renderAjax()|renderAjax()]]: [名前付きビュー](#named-views) をレンダリングし、登録されている全ての JS/CSS スクリプトおよびファイルを注入する。
登録されている全ての JS/CSS スクリプトおよびファイルを注入する。
通常、AJAX ウェブリクエストに対するレスポンスにおいて使用される。 通常、AJAX ウェブリクエストに対するレスポンスにおいて使用される。
* [[yii\base\View::renderFile()|renderFile()]]: ビューファイルのパスまたは [エイリアス](concept-aliases.md) * [[yii\base\View::renderFile()|renderFile()]]: ビューファイルのパスまたは [エイリアス](concept-aliases.md) の形式で指定されたビューをレンダリングする。
の形式で指定されたビューをレンダリングする。
例えば、ビューの中の次のコードは、現在レンダリングされているビューと同じディレクトリにある 例えば、ビューの中の次のコードは、現在レンダリングされているビューと同じディレクトリにある `_overview.php` というビューファイルをレンダリングします。
`_overview.php` というビューファイルをレンダリングします。 ビューでは `$this`[[yii\base\View|ビュー]] コンポーネントを参照することを思い出してください。
ビューでは `$this`[[yii\base\View|ビュー]] コンポーネントを参照することを思い出してください:
```php ```php
<?= $this->render('_overview') ?> <?= $this->render('_overview') ?>
...@@ -237,8 +214,7 @@ echo \Yii::$app->view->renderFile('@app/views/site/license.php'); ...@@ -237,8 +214,7 @@ echo \Yii::$app->view->renderFile('@app/views/site/license.php');
### 名前付きビュー <a name="named-views"></a> ### 名前付きビュー <a name="named-views"></a>
ビューをレンダリングするとき、ビューを指定するのには、ビューの名前か、 ビューをレンダリングするとき、ビューを指定するのには、ビューの名前か、ビューファイルのパス/エイリアスか、どちらかを使うことが出来ます。
ビューファイルのパス/エイリアスか、どちらかを使うことが出来ます。
たいていの場合は、より簡潔で柔軟な前者を使います。 たいていの場合は、より簡潔で柔軟な前者を使います。
名前を使って指定されるビューを *名前付きビュー* と呼びます。 名前を使って指定されるビューを *名前付きビュー* と呼びます。
...@@ -246,42 +222,32 @@ echo \Yii::$app->view->renderFile('@app/views/site/license.php'); ...@@ -246,42 +222,32 @@ echo \Yii::$app->view->renderFile('@app/views/site/license.php');
* ビュー名はファイル拡張子を省略することが出来ます。その場合、`.php` が拡張子として使われます。 * ビュー名はファイル拡張子を省略することが出来ます。その場合、`.php` が拡張子として使われます。
例えば、`about` というビュー名は `about.php` というファイル名に対応します。 例えば、`about` というビュー名は `about.php` というファイル名に対応します。
* ビュー名が二つのスラッシュ (`//`) で始まる場合は、対応するビューファイルのパスは `@app/views/ViewName` * ビュー名が二つのスラッシュ (`//`) で始まる場合は、対応するビューファイルのパスは `@app/views/ViewName` となります。
となります。つまり、ビューファイルは [[yii\base\Application::viewPath|アプリケーションのビューパス]] つまり、ビューファイルは [[yii\base\Application::viewPath|アプリケーションのビューパス]] の下で探されます。
の下で探されます。例えば、`//site/about``@app/views/site/about.php` へと解決されます。 例えば、`//site/about``@app/views/site/about.php` へと解決されます。
* ビュー名が一つのスラッシュ (`/`) で始まる場合は、ビューファイルのパスは、ビュー名の前に、現在 * ビュー名が一つのスラッシュ (`/`) で始まる場合は、ビューファイルのパスは、ビュー名の前に、現在アクティブな [モジュール](structure-modules.md)[[yii\base\Module::viewPath|ビューパス]] を置くことによって形成されます。
アクティブな [モジュール](structure-modules.md)[[yii\base\Module::viewPath|ビューパス]] アクティブなモジュールが無い場合は、`@app/views/ViewName` が使用されます。
を置くことによって形成されます。アクティブなモジュールが無い場合は、`@app/views/ViewName` 例えば、`/user/create` は、現在アクティブなモジュールが `user` である場合は、`@app/modules/user/views/user/create.php` へと解決されます。
が使用されます。例えば、`/user/create` は、現在アクティブなモジュールが `user` である場合は、 アクティブなモジュールが無い場合は、ビューファイルのパスは `@app/views/user/create.php` となります。
`@app/modules/user/views/user/create.php` へと解決されます。アクティブなモジュールが無い場合は、 * ビューが [[yii\base\View::context|コンテキスト]] を伴ってレンダリングされ、そのコンテキストが [[yii\base\ViewContextInterface]] を実装している場合は、
ビューファイルのパスは `@app/views/user/create.php` となります。 ビューファイルのパスは、コンテキストの [[yii\base\ViewContextInterface::getViewPath()|ビューパス]] をビュー名の前に置くことによって形成されます。
* ビューが [[yii\base\View::context|コンテキスト]] を伴ってレンダリングされ、そのコンテキストが これは、主として、コントローラとウィジェットの中でレンダリングされるビューに当てはまります。
[[yii\base\ViewContextInterface]] を実装している場合は、ビューファイルのパスは、コンテキストの 例えば、コンテキストが `SiteController` コントローラである場合、`site/about``@app/views/site/about.php` へと解決されます。
[[yii\base\ViewContextInterface::getViewPath()|ビューパス]] をビュー名の前に置くことによって * あるビューが別のビューの中でレンダリングされる場合は、後者のビューファイルを含んでいるディレクトリが前者のビュー名の前に置かれて、実際のビューファイルのパスが形成されます。
形成されます。これは、主として、コントローラとウィジェットの中でレンダリングされるビューに当てはまります。 例えば、`item` は、`@app/views/post/index.php` というビューの中でレンダリングされる場合、`@app/views/post/item` へと解決されます。
例えば、コンテキストが `SiteController` コントローラである場合、`site/about``@app/views/site/about.php`
へと解決されます。 上記の規則によると、コントローラ `app\controllers\PostController` の中で `$this->render('view')` を呼ぶと、実際には、ビューファイル `@app/views/post/view.php` がレンダリングされ、
* あるビューが別のビューの中でレンダリングされる場合は、後者のビューファイルを含んでいるディレクトリが 一方、そのビューの中で `$this->render('_overview')` を呼ぶと、ビューファイル `@app/views/post/_overview.php` がレンダリングされることになります。
前者のビュー名の前に置かれて、実際のビューファイルのパスが形成されます。例えば、`item` は、
`@app/views/post/index.php` というビューの中でレンダリングされる場合、`@app/views/post/item`
へと解決されます。
上記の規則によると、コントローラ `app\controllers\PostController` の中で `$this->render('view')` を呼ぶと、
実際には、ビューファイル `@app/views/post/view.php` がレンダリングされ、一方、そのビューの中で
`$this->render('_overview')` を呼ぶと、ビューファイル `@app/views/post/_overview.php`
がレンダリングされることになります。
### ビューの中でデータにアクセスする <a name="accessing-data-in-views"></a> ### ビューの中でデータにアクセスする <a name="accessing-data-in-views"></a>
ビューの中でデータにアクセスするためのアプローチが二つあります: 「プッシュ」と「プル」です。 ビューの中でデータにアクセスするためのアプローチが二つあります。「プッシュ」と「プル」です。
ビューをレンダリングするメソッドに二番目のパラメータとしてデータを渡すのが「プッシュ」のアプローチです。 ビューをレンダリングするメソッドに二番目のパラメータとしてデータを渡すのが「プッシュ」のアプローチです。
データは、「名前-値」のペアの配列として表されなければなりません。 データは、「名前-値」のペアの配列として表されなければなりません。
ビューがレンダリングされるときに、PHP の `extract()` 関数がこの配列に対して呼び出され、 ビューがレンダリングされるときに、PHP の `extract()` 関数がこの配列に対して呼び出され、ビューの中でこの配列から変数が抽出されます。
ビューの中でこの配列から変数が抽出されます。 例えば、次のコードはコントローラの中でビューをレンダリングしていますが、`report` ビューに二つの変数、すなわち、`$foo = 1``$bar = 2` をプッシュしています。
例えば、次のコードはコントローラの中でビューをレンダリングしていますが、`report` ビューに
二つの変数、すなわち、`$foo = 1``$bar = 2` をプッシュしています。
```php ```php
echo $this->render('report', [ echo $this->render('report', [
...@@ -290,11 +256,10 @@ echo $this->render('report', [ ...@@ -290,11 +256,10 @@ echo $this->render('report', [
]); ]);
``` ```
「プル」のアプローチは、[[yii\base\View|ビューコンポーネント]] またはビューからアクセス出来るその他のオブジェクト (例えば `Yii::$app`) から 「プル」のアプローチは、[[yii\base\View|ビューコンポーネント]] またはビューからアクセス出来るその他のオブジェクト (例えば `Yii::$app`) から積極的にデータを読み出すものです。
積極的にデータを読み出すものです。 下記のコード例のように、ビューの中では `$this->context` という式でコントローラオブジェクトを取得することが出来ます。
下記のコードを例として使って、ビューの中で `$this->context` という式でコントローラオブジェクト その結果、`report` ビューの中で、コントローラの全てのプロパティやメソッドにアクセスすることが出来ます。
を取得することが出来ます。その結果、`report` ビューの中でコントローラの全てのプロパティや 次の例ではコントローラ ID にアクセスしています。
メソッドにアクセスすることが出来ます。次の例ではコントローラ ID にアクセスしています:
```php ```php
The controller ID is: <?= $this->context->id ?> The controller ID is: <?= $this->context->id ?>
...@@ -304,24 +269,20 @@ The controller ID is: <?= $this->context->id ?> ...@@ -304,24 +269,20 @@ The controller ID is: <?= $this->context->id ?>
通常は「プッシュ」アプローチが、ビューでデータにアクセスする方法として推奨されます。 通常は「プッシュ」アプローチが、ビューでデータにアクセスする方法として推奨されます。
なぜなら、ビューのコンテキストオブジェクトに対する依存がより少ないからです。 なぜなら、ビューのコンテキストオブジェクトに対する依存がより少ないからです。
その短所は、常にデータ配列を手作業で作成する必要がある、ということです。 その短所は、常にデータ配列を手作業で作成する必要がある、ということです。
ビューが共有されてさまざまな場所でレンダリングされる場合、その作業が面倒くさくなり、また、 ビューが共有されてさまざまな場所でレンダリングされる場合、その作業が面倒くさくなり、また、間違いも生じやすくなります。
間違いも生じやすくなります。
### ビューの間でデータを共有する <a name="sharing-data-among-views"></a> ### ビューの間でデータを共有する <a name="sharing-data-among-views"></a>
[[yii\base\View|ビューコンポーネント]] が提供する [[yii\base\View::params|params]] プロパティを使うと [[yii\base\View|ビューコンポーネント]] が提供する [[yii\base\View::params|params]] プロパティを使うと、ビューの間でデータを共有することが出来ます。
ビューの間でデータを共有することが出来ます。
例えば、`about` というビューで、次のようなコードを使って、 例えば、`about` というビューで、次のようなコードを使って、パン屑リストの現在の区分を指定することが出来ます。
パン屑リストの現在の区分を指定することが出来ます。
```php ```php
$this->params['breadcrumbs'][] = 'About Us'; $this->params['breadcrumbs'][] = 'About Us';
``` ```
そして、[レイアウト](#layouts) ファイル (これも一つのビューです) の中で、[[yii\base\View::params|params]] そして、[レイアウト](#layouts) ファイル (これも一つのビューです) の中で、[[yii\base\View::params|params]] によって渡されたデータを使って、パン屑リストを表示することが出来ます。
によって渡されたデータを使って、パン屑リストを表示することが出来ます:
```php ```php
<?= yii\widgets\Breadcrumbs::widget([ <?= yii\widgets\Breadcrumbs::widget([
...@@ -334,23 +295,19 @@ $this->params['breadcrumbs'][] = 'About Us'; ...@@ -334,23 +295,19 @@ $this->params['breadcrumbs'][] = 'About Us';
レイアウトは、複数のビューの共通部分をあらわす特殊なタイプのビューです。 レイアウトは、複数のビューの共通部分をあらわす特殊なタイプのビューです。
例えば、たいていのウェブアプリケーションでは、ページは共通のヘッダとフッタを持っています。 例えば、たいていのウェブアプリケーションでは、ページは共通のヘッダとフッタを持っています。
すべてのビューで同じヘッダとフッタを繰り返すことも出来ますが、もっと良い方法は、 すべてのビューで同じヘッダとフッタを繰り返すことも出来ますが、もっと良い方法は、そういうことはレイアウトの中で一度だけして、コンテンツビューのレンダリング結果をレイアウトの中の適切な場所に埋め込むことです。
そういうことはレイアウトの中で一度だけして、コンテンツビューのレンダリング結果を
レイアウトの中の適切な場所に埋め込むことです。
### レイアウトを作成する <a name="creating-layouts"></a> ### レイアウトを作成する <a name="creating-layouts"></a>
レイアウトもまたビューですので、通常のビューと同様な方法で作成することが出来ます。既定では、 レイアウトもまたビューですので、通常のビューと同様な方法で作成することが出来ます。
レイアウトは `@app/views/layouts` ディレクトリに保存されます。[モジュール](structure-modules.md) 既定では、レイアウトは `@app/views/layouts` ディレクトリに保存されます。
の中で使用されるレイアウトについては、[[yii\base\Module::basePath|モジュールディレクトリ]] の下の [モジュール](structure-modules.md) の中で使用されるレイアウトについては、[[yii\base\Module::basePath|モジュールディレクトリ]]
`views/layouts` ディレクトリに保存されるべきものとなります。既定のレイアウトディレクトリは、 の下の `views/layouts` ディレクトリに保存されるべきものとなります。
アプリケーションまたはモジュールの [[yii\base\Module::layoutPath]] プロパティを構成することで 既定のレイアウトディレクトリは、アプリケーションまたはモジュールの [[yii\base\Module::layoutPath]] プロパティを構成することでカスタマイズすることが出来ます。
カスタマイズすることが出来ます。
次の例は、レイアウトがどのようなものであるかを示すものです。説明のために、レイアウトの中のコードを 次の例は、レイアウトがどのようなものであるかを示すものです。説明のために、レイアウトの中のコードを大幅に単純化していることに注意してください。
大幅に単純化していることに注意してください。実際には、ヘッドのタグやメインメニューなど、もっと 実際には、ヘッドのタグやメインメニューなど、もっと多くのコンテンツを追加する必要があるでしょう。
多くのコンテンツを追加する必要があるでしょう。
```php ```php
<?php <?php
...@@ -379,13 +336,11 @@ use yii\helpers\Html; ...@@ -379,13 +336,11 @@ use yii\helpers\Html;
<?php $this->endPage() ?> <?php $this->endPage() ?>
``` ```
見ると分かるように、レイアウトはすべてのページに共通な HTML タグを生成しています。`<body>` 見ると分かるように、レイアウトはすべてのページに共通な HTML タグを生成しています。`<body>` セクションの中でレイアウトが `$content` という変数をエコーしていますが、
セクションの中でレイアウトが `$content` という変数をエコーしていますが、これは、 これは、コンテンツビューのレンダリング結果を表すものであり、[[yii\base\Controller::render()]] が呼ばれるときに、レイアウトにプッシュされるものです。
コンテンツビューのレンダリング結果を表すものであり、[[yii\base\Controller::render()]] が呼ばれるときに、レイアウトにプッシュされるものです。
上記のコードに示されているように、たいていのレイアウトは次に挙げるメソッドを呼び出すべきです。 上記のコードに示されているように、たいていのレイアウトは次に挙げるメソッドを呼び出すべきです。
これらのメソッドは主としてレンダリングの過程に関するイベントをトリガして、他の場所で登録された これらのメソッドは主としてレンダリングの過程に関するイベントをトリガして、他の場所で登録されたスクリプトやタグが、メソッドが呼ばれた場所に正しく注入されるようにするためのものです。
スクリプトやタグが、メソッドが呼ばれた場所に正しく注入されるようにするためのものです。
- [[yii\base\View::beginPage()|beginPage()]]: このメソッドがレイアウトの一番初めに呼ばれるべきです。 - [[yii\base\View::beginPage()|beginPage()]]: このメソッドがレイアウトの一番初めに呼ばれるべきです。
これは、ページの開始を示す [[yii\base\View::EVENT_BEGIN_PAGE|EVENT_BEGIN_PAGE]] イベントをトリガします。 これは、ページの開始を示す [[yii\base\View::EVENT_BEGIN_PAGE|EVENT_BEGIN_PAGE]] イベントをトリガします。
...@@ -395,37 +350,33 @@ use yii\helpers\Html; ...@@ -395,37 +350,33 @@ use yii\helpers\Html;
このメソッドは、ページのレンダリングが完了したときに、登録された head の HTML コード (リンクタグ、メタタグなど) に置き換えられるプレースホルダを生成します。 このメソッドは、ページのレンダリングが完了したときに、登録された head の HTML コード (リンクタグ、メタタグなど) に置き換えられるプレースホルダを生成します。
- [[yii\web\View::beginBody()|beginBody()]]: このメソッドが `<body>` セクションの最初で呼ばれるべきです。 - [[yii\web\View::beginBody()|beginBody()]]: このメソッドが `<body>` セクションの最初で呼ばれるべきです。
このメソッドは [[yii\web\View::EVENT_BEGIN_BODY|EVENT_BEGIN_BODY]] イベントをトリガし、 このメソッドは [[yii\web\View::EVENT_BEGIN_BODY|EVENT_BEGIN_BODY]] イベントをトリガし、
body の開始位置を目的とする登録された HTML コード (JavaScript など) によって置き換えられる body の開始位置を目的とする登録された HTML コード (JavaScript など) によって置き換えられるプレースホルダを生成します。
プレースホルダを生成します。
- [[yii\web\View::endBody()|endBody()]]: このメソッドが `<body`> セクションの最後で呼ばれるべきです。 - [[yii\web\View::endBody()|endBody()]]: このメソッドが `<body`> セクションの最後で呼ばれるべきです。
このメソッドは [[yii\web\View::EVENT_END_BODY|EVENT_END_BODY]] イベントをトリガし、 このメソッドは [[yii\web\View::EVENT_END_BODY|EVENT_END_BODY]] イベントをトリガし、
body の終了位置を目的とする登録された HTML コード (JavaScript など) によって置き換えられる body の終了位置を目的とする登録された HTML コード (JavaScript など) によって置き換えられるプレースホルダを生成します。
プレースホルダを生成します。
### レイアウトでデータにアクセスする <a name="accessing-data-in-layouts"></a> ### レイアウトでデータにアクセスする <a name="accessing-data-in-layouts"></a>
レイアウトの中では、事前定義された二つの変数にアクセス出来ます: `$this``$content` です。前者は、 レイアウトの中では、事前定義された二つの変数、すなわち、`$this``$content` にアクセス出来ます。
通常のビューにおいてと同じく、[[yii\base\View|ビュー]] コンポーネントを参照します。一方、後者は、 前者は、通常のビューにおいてと同じく、[[yii\base\View|ビュー]] コンポーネントを参照します。
コントローラの中で [[yii\base\Controller::render()|render()]] メソッドを呼ぶことによってレンダリングされる、 一方、後者は、コントローラの中で [[yii\base\Controller::render()|render()]] メソッドを呼ぶことによってレンダリングされる、
コンテンツビューのレンダリング結果を含むものです。 コンテンツビューのレンダリング結果を含むものです。
レイアウトの中で他のデータにアクセスする必要があるときは、[ビューの中でデータにアクセスする](#accessing-data-in-views) レイアウトの中で他のデータにアクセスする必要があるときは、[ビューの中でデータにアクセスする](#accessing-data-in-views) の項で説明されている「プル」の方法を使う必要があります。
の項で説明されている「プル」の方法を使う必要があります。コンテンツビューからレイアウトにデータを渡す必要があるときは、 コンテンツビューからレイアウトにデータを渡す必要があるときは、[ビューの間でデータを共有する](#sharing-data-among-views) の項で説明されている方法を使うことが出来ます。
[ビューの間でデータを共有する](#sharing-data-among-views) の項で説明されている方法を使うことが出来ます。
### レイアウトを使う <a name="using-layouts"></a> ### レイアウトを使う <a name="using-layouts"></a>
[コントローラでのレンダリング](#rendering-in-controllers) の項で説明されているように、コントローラの中で [コントローラでのレンダリング](#rendering-in-controllers) の項で説明されているように、コントローラの中で
[[yii\base\Controller::render()|render()]] メソッドを呼んでビューをレンダリングすると、レンダリング結果に [[yii\base\Controller::render()|render()]] メソッドを呼んでビューをレンダリングすると、レンダリング結果にレイアウトが適用されます。
レイアウトが適用されます。既定では、`@app/views/layouts/main.php` というレイアウトが使用されます。 既定では、`@app/views/layouts/main.php` というレイアウトが使用されます。
[[yii\base\Application::layout]] または [[yii\base\Controller::layout]] のどちらかを構成することによって、異なるレイアウトを [[yii\base\Application::layout]] または [[yii\base\Controller::layout]] のどちらかを構成することによって、異なるレイアウトを使うことが出来ます。
使うことが出来ます。前者は全てのコントローラによって使用されるレイアウトを決定するものですが、後者は個々のコントローラについて 前者は全てのコントローラによって使用されるレイアウトを決定するものですが、後者は個々のコントローラについて前者をオーバーライドするものです。
前者をオーバーライドするものです。例えば、次のコードは、`post` コントローラがビューをレンダリングするときに 例えば、次のコードは、`post` コントローラがビューをレンダリングするときに `@app/views/layouts/post.php` をレイアウトとして使うようにするものです。
`@app/views/layouts/post.php` をレイアウトとして使うようにするものです。その他のコントローラは、`layout` プロパティに その他のコントローラは、`layout` プロパティに触れられていないと仮定すると、引き続き既定の `@app/views/layouts/main.php` をレイアウトとして使います。
触れられていないと仮定すると、引き続き既定の `@app/views/layouts/main.php` をレイアウトとして使います。
```php ```php
namespace app\controllers; namespace app\controllers;
...@@ -440,13 +391,11 @@ class PostController extends Controller ...@@ -440,13 +391,11 @@ class PostController extends Controller
} }
``` ```
モジュールに属するコントローラについては、モジュールの [[yii\base\Module::layout|layout]] プロパティを構成して、モジュール内の モジュールに属するコントローラについては、モジュールの [[yii\base\Module::layout|layout]] プロパティを構成して、モジュール内のコントローラに特定のレイアウトを使用することも出来ます。
コントローラに特定のレイアウトを使用することも出来ます。
`layout` プロパティは異なるレベル (コントローラ、モジュール、アプリケーション) で構成されうるものですので、 `layout` プロパティは異なるレベル (コントローラ、モジュール、アプリケーション) で構成されうるものですので、Yii は舞台裏で二つのステップを踏んで、特定のコントローラで実際に使われるレイアウトファイルが何であるかを決定します。
Yii は舞台裏で二つのステップを践んで、特定のコントローラで実際に使われるレイアウトファイルが何であるかを決定します。
最初のステップで、Yii はレイアウトの値とコンテキストモジュールを決定します: 最初のステップで、Yii はレイアウトの値とコンテキストモジュールを決定します。
- コントローラの [[yii\base\Controller::layout]] プロパティが null でないときは、それをレイアウトの値として使い、 - コントローラの [[yii\base\Controller::layout]] プロパティが null でないときは、それをレイアウトの値として使い、
コントローラの [[yii\base\Controller::module|モジュール]] をコンテキストモジュールとして使う。 コントローラの [[yii\base\Controller::module|モジュール]] をコンテキストモジュールとして使う。
...@@ -456,7 +405,7 @@ Yii 縺ッ闊槫床陬上〒莠後▽縺ョ繧ケ繝ャ繝励r霍オ繧薙〒縲∫音螳壹繧ウ繝ウ繝医Ο繝シ ...@@ -456,7 +405,7 @@ Yii 縺ッ闊槫床陬上〒莠後▽縺ョ繧ケ繝ャ繝励r霍オ繧薙〒縲∫音螳壹繧ウ繝ウ繝医Ο繝シ
そのようなモジュールが見つからなかったときは、レイアウトは適用されないということを意味する。 そのようなモジュールが見つからなかったときは、レイアウトは適用されないということを意味する。
第二のステップでは、最初のステップで決定されたレイアウトの値とコンテキストモジュールに従って、実際のレイアウトファイルを決定します。 第二のステップでは、最初のステップで決定されたレイアウトの値とコンテキストモジュールに従って、実際のレイアウトファイルを決定します。
レイアウトの値は下記のいずれかであり得ます: レイアウトの値は下記のいずれかであり得ます。
- パスエイリアス (例えば、`@app/views/layouts/main`)。 - パスエイリアス (例えば、`@app/views/layouts/main`)。
- 絶対パス (例えば、`/main`): すなわち、スラッシュで始まるレイアウトの値の場合。 - 絶対パス (例えば、`/main`): すなわち、スラッシュで始まるレイアウトの値の場合。
...@@ -471,12 +420,12 @@ Yii 縺ッ闊槫床陬上〒莠後▽縺ョ繧ケ繝ャ繝励r霍オ繧薙〒縲∫音螳壹繧ウ繝ウ繝医Ο繝シ ...@@ -471,12 +420,12 @@ Yii 縺ッ闊槫床陬上〒莠後▽縺ョ繧ケ繝ャ繝励r霍オ繧薙〒縲∫音螳壹繧ウ繝ウ繝医Ο繝シ
### 入れ子のレイアウト <a name="nested-layouts"></a> ### 入れ子のレイアウト <a name="nested-layouts"></a>
ときとして、あるレイアウトの中に別のレイアウトを入れたい場合があるでしょう。例えば、 ときとして、あるレイアウトの中に別のレイアウトを入れたい場合があるでしょう。
ウェブサイトの別々のセクションにおいて、違うレイアウトを使いたいけれども、 例えば、ウェブサイトの別々のセクションにおいて、違うレイアウトを使いたいけれども、
それらのレイアウトは全て、全体としての HTML5 ページ構造を生成する同一の基本レイアウトを それらのレイアウトは全て、全体としての HTML5 ページ構造を生成する同一の基本レイアウトを共有している、という場合です。
共有している、という場合です。この目的を達することは、次のように、子レイアウトの中で この目的を達することは、次のように、子レイアウトの中で
[[yii\base\View::beginContent()|beginContent()]] と [[yii\base\View::endContent()|endContent()]] [[yii\base\View::beginContent()|beginContent()]] と [[yii\base\View::endContent()|endContent()]]
を呼ぶことで可能になります: を呼ぶことで可能になります。
```php ```php
<?php $this->beginContent('@app/views/layouts/base.php'); ?> <?php $this->beginContent('@app/views/layouts/base.php'); ?>
...@@ -488,8 +437,8 @@ Yii 縺ッ闊槫床陬上〒莠後▽縺ョ繧ケ繝ャ繝励r霍オ繧薙〒縲∫音螳壹繧ウ繝ウ繝医Ο繝シ ...@@ -488,8 +437,8 @@ Yii 縺ッ闊槫床陬上〒莠後▽縺ョ繧ケ繝ャ繝励r霍オ繧薙〒縲∫音螳壹繧ウ繝ウ繝医Ο繝シ
上のコードが示すように、子レイアウトのコンテンツは [[yii\base\View::beginContent()|beginContent()]] と 上のコードが示すように、子レイアウトのコンテンツは [[yii\base\View::beginContent()|beginContent()]] と
[[yii\base\View::endContent()|endContent()]] によって囲まれなければなりません。 [[yii\base\View::endContent()|endContent()]] によって囲まれなければなりません。
[[yii\base\View::beginContent()|beginContent()]] に渡されるパラメータは、 [[yii\base\View::beginContent()|beginContent()]] に渡されるパラメータは、親レイアウトで何であるかを指定するものです。
親レイアウトで何であるかを指定するものです。レイアウトのファイルまたはエイリアスのどちらかを使うことが出来ます。 レイアウトのファイルまたはエイリアスのどちらかを使うことが出来ます。
上記のアプローチを使って、2レベル以上のレイアウトを入れ子にすることも出来ます。 上記のアプローチを使って、2レベル以上のレイアウトを入れ子にすることも出来ます。
...@@ -497,16 +446,14 @@ Yii 縺ッ闊槫床陬上〒莠後▽縺ョ繧ケ繝ャ繝励r霍オ繧薙〒縲∫音螳壹繧ウ繝ウ繝医Ο繝シ ...@@ -497,16 +446,14 @@ Yii 縺ッ闊槫床陬上〒莠後▽縺ョ繧ケ繝ャ繝励r霍オ繧薙〒縲∫音螳壹繧ウ繝ウ繝医Ο繝シ
### ブロックを使う <a name="using-blocks"></a> ### ブロックを使う <a name="using-blocks"></a>
ブロックを使うと、ある場所でビューコンテンツを規定して、別の場所でそれを表示することが可能になります。 ブロックを使うと、ある場所でビューコンテンツを規定して、別の場所でそれを表示することが可能になります。
ブロックはたいていはレイアウトと一緒に使われます。例えば、ブロックをコンテンツビューで定義して、 ブロックはたいていはレイアウトと一緒に使われます。
それをレイアウトで表示する、ということが出来ます。 例えば、ブロックをコンテンツビューで定義して、それをレイアウトで表示する、ということが出来ます。
[[yii\base\View::beginBlock()|beginBlock()]] と [[yii\base\View::endBlock()|endBlock()]] [[yii\base\View::beginBlock()|beginBlock()]] と [[yii\base\View::endBlock()|endBlock()]] を呼んでブロックを定義します。
を呼んでブロックを定義します。
すると、そのブロックを `$view->blocks[$blockID]` によってアクセス出来るようになります。 すると、そのブロックを `$view->blocks[$blockID]` によってアクセス出来るようになります。
ここで `$blockID` は、定義したときにブロックに割り当てたユニークな ID を指します。 ここで `$blockID` は、定義したときにブロックに割り当てたユニークな ID を指します。
次の例は、どのようにブロックを使えば、レイアウトの特定の部分をコンテンツビューで 次の例は、どのようにブロックを使えば、レイアウトの特定の部分をコンテンツビューでカスタマイズすることが出来るかを示すものです。
カスタマイズすることが出来るかを示すものです。
最初に、コンテンツビューで、一つまたは複数のブロックを定義します。 最初に、コンテンツビューで、一つまたは複数のブロックを定義します。
...@@ -528,8 +475,7 @@ Yii 縺ッ闊槫床陬上〒莠後▽縺ョ繧ケ繝ャ繝励r霍オ繧薙〒縲∫音螳壹繧ウ繝ウ繝医Ο繝シ ...@@ -528,8 +475,7 @@ Yii 縺ッ闊槫床陬上〒莠後▽縺ョ繧ケ繝ャ繝励r霍オ繧薙〒縲∫音螳壹繧ウ繝ウ繝医Ο繝シ
<?php $this->endBlock(); ?> <?php $this->endBlock(); ?>
``` ```
次に、レイアウトビューで、得ることが出来ればブロックをレンダリングし、ブロックが定義されていないときは 次に、レイアウトビューで、得ることが出来ればブロックをレンダリングし、ブロックが定義されていないときは何らかの既定のコンテンツを表示します。
何らかの既定のコンテンツを表示します。
```php ```php
... ...
...@@ -561,9 +507,8 @@ Yii 縺ッ闊槫床陬上〒莠後▽縺ョ繧ケ繝ャ繝励r霍オ繧薙〒縲∫音螳壹繧ウ繝ウ繝医Ο繝シ ...@@ -561,9 +507,8 @@ Yii 縺ッ闊槫床陬上〒莠後▽縺ョ繧ケ繝ャ繝励r霍オ繧薙〒縲∫音螳壹繧ウ繝ウ繝医Ο繝シ
## ビューコンポーネントを使う <a name="using-view-components"></a> ## ビューコンポーネントを使う <a name="using-view-components"></a>
[[yii\base\View|ビューコンポーネント]] はビューに関連する多くの機能を提供します。 [[yii\base\View|ビューコンポーネント]] はビューに関連する多くの機能を提供します。
ビューコンポーネントは、[[yii\base\View]] またはその子クラスの個別のインスタンスを作成することによっても取得できますが、 ビューコンポーネントは、[[yii\base\View]] またはその子クラスの個別のインスタンスを作成することによっても取得できますが、たいていの場合は、`view` アプリケーションコンポーネントを主として使うことになるでしょう。
たいていの場合は、`view` アプリケーションコンポーネントを主として使うことになるでしょう。 このコンポーネントは [アプリケーションの構成情報](structure-applications.md#application-configurations) の中で、次のようにして構成することが出来ます。
このコンポーネントは [アプリケーションのコンフィギュレーション](structure-applications.md#application-configurations) の中で、次のようにして構成することが出来ます:
```php ```php
[ [
...@@ -577,8 +522,7 @@ Yii 縺ッ闊槫床陬上〒莠後▽縺ョ繧ケ繝ャ繝励r霍オ繧薙〒縲∫音螳壹繧ウ繝ウ繝医Ο繝シ ...@@ -577,8 +522,7 @@ Yii 縺ッ闊槫床陬上〒莠後▽縺ョ繧ケ繝ャ繝励r霍オ繧薙〒縲∫音螳壹繧ウ繝ウ繝医Ο繝シ
] ]
``` ```
ビューコンポーネントは、次に挙げるビュー関連の有用な機能を提供します。それぞれについては、 ビューコンポーネントは、次に挙げるビュー関連の有用な機能を提供します。それぞれについては、独立の節で更に詳細に説明されます。
独立の節で更に詳細に説明されます。
* [テーマ](output-theming.md): ウェブサイトのテーマを開発し変更することを可能にします。 * [テーマ](output-theming.md): ウェブサイトのテーマを開発し変更することを可能にします。
* [フラグメントキャッシュ](caching-fragment.md): ウェブページの中の断片をキャッシュすることを可能にします。 * [フラグメントキャッシュ](caching-fragment.md): ウェブページの中の断片をキャッシュすることを可能にします。
...@@ -586,17 +530,16 @@ Yii 縺ッ闊槫床陬上〒莠後▽縺ョ繧ケ繝ャ繝励r霍オ繧薙〒縲∫音螳壹繧ウ繝ウ繝医Ο繝シ ...@@ -586,17 +530,16 @@ Yii 縺ッ闊槫床陬上〒莠後▽縺ョ繧ケ繝ャ繝励r霍オ繧薙〒縲∫音螳壹繧ウ繝ウ繝医Ο繝シ
* [アセットバンドルの取り扱い](structure-assets.md): [アセットバンドル](structure-assets.md) の登録とレンダリングをサポートします。 * [アセットバンドルの取り扱い](structure-assets.md): [アセットバンドル](structure-assets.md) の登録とレンダリングをサポートします。
* [代替のテンプレートエンジン](tutorial-template-engines.md): [Twig](http://twig.sensiolabs.org/)[Smarty](http://www.smarty.net/) など、他のテンプレートエンジンを使用することを可能にします。 * [代替のテンプレートエンジン](tutorial-template-engines.md): [Twig](http://twig.sensiolabs.org/)[Smarty](http://www.smarty.net/) など、他のテンプレートエンジンを使用することを可能にします。
次に挙げるマイナーではあっても有用な諸機能は、ウェブページを開発するときに頻繁に使用するでしょう: 次に挙げるマイナーではあっても有用な諸機能は、ウェブページを開発するときに頻繁に使用するでしょう。
### ページタイトルを設定する <a name="setting-page-titles"></a> ### ページタイトルを設定する <a name="setting-page-titles"></a>
どんなウェブページにもタイトルが無ければなりません。通常、タイトルタグは [layout](#layouts) の中で表示されます。しかし、 どんなウェブページにもタイトルが無ければなりません。通常、タイトルタグは [layout](#layouts) の中で表示されます。
実際においては、多くの場合、タイトルはレイアウトではなくコンテンツビューで決められます。この問題を解決するために、 しかし、実際においては、多くの場合、タイトルはレイアウトではなくコンテンツビューで決められます。
[[yii\web\View]] は、タイトル情報をコンテンツビューからレイアウトに渡すための [[yii\web\View::title|title]] プロパティを この問題を解決するために、[[yii\web\View]] は、タイトル情報をコンテンツビューからレイアウトに渡すための [[yii\web\View::title|title]] プロパティを提供しています。
提供しています。
この機能を利用するためには、全てのコンテンツビューにおいて、次のようにタイトルを設定します: この機能を利用するためには、全てのコンテンツビューにおいて、次のようにタイトルを設定します。
```php ```php
<?php <?php
...@@ -604,7 +547,7 @@ $this->title = 'My page title'; ...@@ -604,7 +547,7 @@ $this->title = 'My page title';
?> ?>
``` ```
そして、レイアウトビューで、`<head>` セクションに次のコードを忘れずに書くようにします: そして、レイアウトビューで、`<head>` セクションに次のコードを忘れずに書くようにします。
```php ```php
<title><?= Html::encode($this->title) ?></title> <title><?= Html::encode($this->title) ?></title>
...@@ -613,11 +556,10 @@ $this->title = 'My page title'; ...@@ -613,11 +556,10 @@ $this->title = 'My page title';
### メタタグを登録する <a name="registering-meta-tags"></a> ### メタタグを登録する <a name="registering-meta-tags"></a>
ウェブページは、通常、いろいろな関係者によって必要とされるさまざまなメタタグを生成する必要があります。ページタイトルと同じように、 ウェブページは、通常、いろいろな関係者によって必要とされるさまざまなメタタグを生成する必要があります。
タグは `<head>` セクションに出現して、通常はレイアウトの中で生成されます。 ージタイトルと同じように、メタタグは `<head>` セクションに出現して、通常はレイアウトの中で生成されます。
どのようなメタタグを生成するかをコンテンツビューの中で指定したい場合は、下記のように、 どのようなメタタグを生成するかをコンテンツビューの中で指定したい場合は、下記のように、[[yii\web\View::registerMetaTag()]] をコンテンツビューの呼ぶことが出来ます。
[[yii\web\View::registerMetaTag()]] をコンテンツビューの呼ぶことが出来ます:
```php ```php
<?php <?php
...@@ -625,20 +567,17 @@ $this->registerMetaTag(['name' => 'keywords', 'content' => 'yii, framework, php' ...@@ -625,20 +567,17 @@ $this->registerMetaTag(['name' => 'keywords', 'content' => 'yii, framework, php'
?> ?>
``` ```
上記のコードは、ビューコンポーネントによって "keywords" メタタグを登録するものです。登録されたメタタグは、 上記のコードは、ビューコンポーネントによって "keywords" メタタグを登録するものです。登録されたメタタグは、レイアウトがレンダリングを完了した後でレンダリングされます。
レイアウトがレンダリングを完了した後でレンダリングされます。すなわち、レイアウトの中で [[yii\web\View::head()]] すなわち、レイアウトの中で [[yii\web\View::head()]] を呼び出した場所に、次の HTML コードが生成されて挿入されます。
を呼び出した場所に、次の HTML コードが生成されて挿入されます:
```php ```php
<meta name="keywords" content="yii, framework, php"> <meta name="keywords" content="yii, framework, php">
``` ```
[[yii\web\View::registerMetaTag()]] を複数回呼び出した場合は、メタタグが同じものか否かに関係なく、 [[yii\web\View::registerMetaTag()]] を複数回呼び出した場合は、メタタグが同じものか否かに関係なく、複数のメタタグが登録されることに注意してください。
複数のメタタグが登録されることに注意してください。
ある型のメタタグのインスタンスが一つだけになることを保証したい場合は、このメソッドを呼ぶときに第二のパラメータとして ある型のメタタグのインスタンスが一つだけになることを保証したい場合は、このメソッドを呼ぶときに第二のパラメータとしてキーを指定することが出来ます。
キーを指定することが出来ます。例えば、次のコードでは、二つの "description" メタタグを登録していますが、 例えば、次のコードでは、二つの "description" メタタグを登録していますが、二番目のものだけがレンダリングされることになります。
二番目のものだけがレンダリングされることになります。
```html ```html
$this->registerMetaTag(['name' => 'description', 'content' => '俺が Yii で作ったクールなウェブサイトだぜぃ!!'], 'description'); $this->registerMetaTag(['name' => 'description', 'content' => '俺が Yii で作ったクールなウェブサイトだぜぃ!!'], 'description');
...@@ -648,9 +587,10 @@ $this->registerMetaTag(['name' => 'description', 'content' => '髱「逋ス縺い繝ゥ繧 ...@@ -648,9 +587,10 @@ $this->registerMetaTag(['name' => 'description', 'content' => '髱「逋ス縺い繝ゥ繧
### リンクタグを登録する <a name="registering-link-tags"></a> ### リンクタグを登録する <a name="registering-link-tags"></a>
[メタタグ](#registering-meta-tags) と同じように、リンクタグも多くの場合において有用なものです。例えば、favicon をカスタマイズしたり、 [メタタグ](#registering-meta-tags) と同じように、リンクタグも多くの場合において有用なものです。
RSS フィードを指し示したり、OpenID を別のサーバに委任したり、等々。リンクタグも、[[yii\web\View::registerLinkTag()]] を使って、 例えば、favicon をカスタマイズしたり、RSS フィードを指し示したり、OpenID を別のサーバに委任したり、等々。
メタタグと同じような方法で取り扱うことが出来ます。例えば、コンテンツビューにおいて、次のようにしてリンクタグを登録することが出来ます。 リンクタグも、[[yii\web\View::registerLinkTag()]] を使って、メタタグと同じような方法で取り扱うことが出来ます。
例えば、コンテンツビューにおいて、次のようにしてリンクタグを登録することが出来ます。
```php ```php
$this->registerLinkTag([ $this->registerLinkTag([
...@@ -674,20 +614,18 @@ $this->registerLinkTag([ ...@@ -674,20 +614,18 @@ $this->registerLinkTag([
## ビューのイベント <a name="view-events"></a> ## ビューのイベント <a name="view-events"></a>
[[yii\base\View|ビューコンポーネント]] はビューをレンダリングする過程においていくつかのイベントをトリガします。 [[yii\base\View|ビューコンポーネント]] はビューをレンダリングする過程においていくつかのイベントをトリガします。
これらのイベントに反応することによって、ビューにコンテンツを注入したり、 これらのイベントに反応することによって、ビューにコンテンツを注入したり、エンドユーザに送信される前にレンダリング結果を加工したりすることが出来ます。
エンドユーザに送信される前にレンダリング結果を加工したりすることが出来ます。
- [[yii\base\View::EVENT_BEFORE_RENDER|EVENT_BEFORE_RENDER]]: コントローラでファイルをレンダリングする前にトリガされます。 - [[yii\base\View::EVENT_BEFORE_RENDER|EVENT_BEFORE_RENDER]]: コントローラでファイルをレンダリングする前にトリガされます。
このイベントのハンドラは、[[yii\base\ViewEvent::isValid]] を false にセットして、レンダリングのプロセスをキャンセルすることが出来ます。 このイベントのハンドラは、[[yii\base\ViewEvent::isValid]] を false にセットして、レンダリングのプロセスをキャンセルすることが出来ます。
- [[yii\base\View::EVENT_AFTER_RENDER|EVENT_AFTER_RENDER]]: ファイルのレンダリングの後、[[yii\base\View::afterRender()]] を呼ぶことによってトリガされます。 - [[yii\base\View::EVENT_AFTER_RENDER|EVENT_AFTER_RENDER]]: ファイルのレンダリングの後、[[yii\base\View::afterRender()]] を呼ぶことによってトリガされます。
このイベントのハンドラは、レンダリング結果を [[yii\base\ViewEvent::output]] によって取得することが出来、 このイベントのハンドラは、レンダリング結果をプロパティ [[yii\base\ViewEvent::output]] を通じて取得して、それを修正してレンダリング結果を変更することが出来ます。
このプロパティを修正してレンダリング結果を変更することが出来ます。
- [[yii\base\View::EVENT_BEGIN_PAGE|EVENT_BEGIN_PAGE]]: レイアウトの中で [[yii\base\View::beginPage()]] を呼ぶことによってトリガされます。 - [[yii\base\View::EVENT_BEGIN_PAGE|EVENT_BEGIN_PAGE]]: レイアウトの中で [[yii\base\View::beginPage()]] を呼ぶことによってトリガされます。
- [[yii\base\View::EVENT_END_PAGE|EVENT_END_PAGE]]: レイアウトの中で [[yii\base\View::endPage()]] を呼ぶことによってトリガされます。 - [[yii\base\View::EVENT_END_PAGE|EVENT_END_PAGE]]: レイアウトの中で [[yii\base\View::endPage()]] を呼ぶことによってトリガされます。
- [[yii\web\View::EVENT_BEGIN_BODY|EVENT_BEGIN_BODY]]: レイアウトの中で [[yii\web\View::beginBody()]] を呼ぶことによってトリガされます。 - [[yii\web\View::EVENT_BEGIN_BODY|EVENT_BEGIN_BODY]]: レイアウトの中で [[yii\web\View::beginBody()]] を呼ぶことによってトリガされます。
- [[yii\web\View::EVENT_END_BODY|EVENT_END_BODY]]: レイアウトの中で [[yii\web\View::endBody()]] を呼ぶことによってトリガされます。 - [[yii\web\View::EVENT_END_BODY|EVENT_END_BODY]]: レイアウトの中で [[yii\web\View::endBody()]] を呼ぶことによってトリガされます。
例えば、次のコードはページの body の最後に現在の日付を注入するものです: 例えば、次のコードはページの body の最後に現在の日付を注入するものです。
```php ```php
\Yii::$app->view->on(View::EVENT_END_BODY, function () { \Yii::$app->view->on(View::EVENT_END_BODY, function () {
...@@ -698,10 +636,9 @@ $this->registerLinkTag([ ...@@ -698,10 +636,9 @@ $this->registerLinkTag([
## 静的なページをレンダリングする <a name="rendering-static-pages"></a> ## 静的なページをレンダリングする <a name="rendering-static-pages"></a>
静的なページというのは、主たるコンテンツのほとんどが静的なもので、コントローラからプッシュされる動的なデータに 静的なページというのは、主たるコンテンツのほとんどが静的なもので、コントローラからプッシュされる動的なデータにアクセスする必要がないページを指します。
アクセスする必要がないページを指します。
静的なページは、そのコードをビューに置き、そして、コントローラで次のようなコードを使うと表示することが出来ます: 静的なページは、そのコードをビューに置き、そして、コントローラで次のようなコードを使うと表示することが出来ます。
```php ```php
public function actionAbout() public function actionAbout()
...@@ -732,8 +669,7 @@ class SiteController extends Controller ...@@ -732,8 +669,7 @@ class SiteController extends Controller
} }
``` ```
このようにすると、ディレクトリ `@app/views/site/pages` の下に `about` という名前のビューを作成したときに、 このようにすると、ディレクトリ `@app/views/site/pages` の下に `about` という名前のビューを作成したときに、次の URL によってこのビューを表示することが出来るようになります。
次の URL によってこのビューを表示することが出来るようになります:
``` ```
http://localhost/index.php?r=site/page&view=about http://localhost/index.php?r=site/page&view=about
...@@ -748,18 +684,17 @@ http://localhost/index.php?r=site/page&view=about ...@@ -748,18 +684,17 @@ http://localhost/index.php?r=site/page&view=about
ビューはエンドユーザが望む形式でモデルを表現することに対して責任を持ちます。一般的に、ビューは ビューはエンドユーザが望む形式でモデルを表現することに対して責任を持ちます。一般的に、ビューは
* 主として表示目的のコードを含むべきです。例えば、HTML、そしてデータをたどり、書式化してレンダリングする簡単な PHP コードなど。 * 主として表示目的のコードを含むべきです。例えば、HTML、または、データをたどって書式化してレンダリングする簡単な PHP コードなど。
* DB クエリを実行するコードは含むべきではありません。そのようなコードはモデルの中で実行されるべきです。 * DB クエリを実行するコードは含むべきではありません。そのようなコードはモデルの中で実行されるべきです。
* `$_GET``$_POST` のようなリクエストデータに直接アクセスするべきではありません。それはコントローラの仕事です。 * `$_GET``$_POST` のようなリクエストデータに直接アクセスするべきではありません。それはコントローラの仕事です。
リクエストデータが必要な場合は、コントローラからビューにプッシュされるべきです。 リクエストデータが必要な場合は、コントローラからビューにプッシュされるべきです。
* モデルのプロパティを読み出すことが出来ます。しかし、それを修正するべきではありません。 * モデルのプロパティを読み出すことが出来ます。しかし、それを修正するべきではありません。
ビューを管理しやすいものにするために、複雑すぎるビューや、冗長なコードをあまりに多く含むビューを作ることは避けましょう。 ビューを管理しやすいものにするために、複雑すぎるビューや、冗長なコードをあまりに多く含むビューを作ることは避けましょう。
この目的を達するために、次のテクニックを使うことが出来ます: この目的を達するために、次のテクニックを使うことが出来ます。
* 共通の表示セクション (ページのヘッダやフッタなど) を表すために [レイアウト](#layouts) を使う。 * 共通の表示セクション (ページのヘッダやフッタなど) を表すために [レイアウト](#layouts) を使う。
* 複雑なビューはいくつかの小さなビューに分割する。既に説明したレンダリングのメソッドを使えば、 * 複雑なビューはいくつかの小さなビューに分割する。既に説明したレンダリングのメソッドを使えば、小さなビューをレンダリングして大きなビューを組み上げることが出来る。
小さなビューをレンダリングして大きなビューを組み上げることが出来る。
* ビューの構成要素として [ウィジェット](structure-widgets.md) を使う。 * ビューの構成要素として [ウィジェット](structure-widgets.md) を使う。
* ビューでデータを変換し書式化するためのヘルパークラスを作成して使う。 * ビューでデータを変換し書式化するためのヘルパクラスを作成して使う。
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment