アセット
========
Yii では、アセットは、ウェブ・ページで参照できるファイルを意味します。アセットは CSS ファイルであったり、JavaScript ファイルであったり、画像やビデオのファイルであったりします。
アセットはウェブでアクセス可能なディレクトリに配置され、ウェブ・サーバによって直接に提供されます。
たいていの場合、アセットはプログラム的に管理する方が望ましいものです。
例えば、ページの中で [[yii\jui\DatePicker]] ウィジェットを使うとき、このウィジェットは必要な CSS と JavaScript のファイルを自動的にインクルードします。
あなたに対して、手作業で必要なファイルを探してインクルードするように要求したりはしません。
そして、このウィジェットを新しいバージョンにアップグレードしたときは、自動的に新しいバージョンのアセット・ファイルが使用されるようになります。
このチュートリアルでは、Yii によって提供される強力なアセット管理機能について説明します。
## アセット・バンドル
Yii はアセットを *アセット・バンドル* を単位として管理します。アセット・バンドルは、簡単に言えば、
あるディレクトリの下に集められた一群のアセットです。
[ビュー](structure-views.md) の中でアセット・バンドルを登録すると、バンドルの中の CSS や JavaScript のファイルがレンダリングされるウェブ・ページに挿入されます。
## アセット・バンドルを定義する
アセット・バンドルは [[yii\web\AssetBundle]] から拡張された PHP クラスとして定義されます。
バンドルの名前は、対応する PHP クラスの完全修飾名 (先頭のバック・スラッシュを除く) です。
アセット・バンドル・クラスは [オートロード可能](concept-autoloading.md) でなければなりません。
アセット・バンドル・クラスは、通常、アセットがどこに置かれているか、バンドルがどういう CSS や JavaScript のファイルを含んでいるか、そして、バンドルが他のバンドルにどのように依存しているかを定義します。
以下のコードは [ベーシック・プロジェクト・テンプレート](start-installation.md) によって使用されているメインのアセット・バンドルを定義するものです。
```php
'print'],
];
public $js = [
];
public $depends = [
'yii\web\YiiAsset',
'yii\bootstrap\BootstrapAsset',
];
}
```
上の `AppAsset` クラスは、アセット・ファイルが `@webroot` ディレクトリの下に配置されており、それが URL `@web` に対応することを定義しています。
バンドルは一つだけ CSS ファイル `css/site.css` を含み、JavaScript ファイルは含みません。
バンドルは、他の二つのバンドル、すなわち [[yii\web\YiiAsset]] と [[yii\bootstrap\BootstrapAsset]] に依存しています。
以下、[[yii\web\AssetBundle]] のプロパティに関して、更に詳細に説明します。
* [[yii\web\AssetBundle::sourcePath|sourcePath]]: このバンドルのアセット・ファイルを含むルート・ディレクトリを指定します。
ルート・ディレクトリがウェブ・アクセス可能でない場合に、このプロパティをセットしなければなりません。
そうでない場合は、代りに、[[yii\web\AssetBundle::basePath|basePath]] と [[yii\web\AssetBundle::baseUrl|baseUrl]] のプロパティをセットしなければなりません。
[パス・エイリアス](concept-aliases.md) をここで使うことが出来ます。
* [[yii\web\AssetBundle::basePath|basePath]]: このバンドルのアセット・ファイルを含むウェブ・アクセス可能なディレクトリを指定します。
[[yii\web\AssetBundle::sourcePath|sourcePath]] プロパティをセットした場合は、[アセット・マネージャ](#asset-manager) がバンドルに含まれるファイルをウェブ・アクセス可能なディレクトリに発行して、
その結果、このプロパティを上書きします。
アセット・ファイルが既にウェブ・アクセス可能なディレクトリにあり、アセットの発行が必要でない場合に、このプロパティをセットしなければなりません。
[パス・エイリアス](concept-aliases.md) をここで使うことが出来ます。
* [[yii\web\AssetBundle::baseUrl|baseUrl]]: [[yii\web\AssetBundle::basePath|basePath]] ディレクトリに対応する URL を指定します。
[[yii\web\AssetBundle::basePath|basePath]] と同じように、[[yii\web\AssetBundle::sourcePath|sourcePath]] プロパティをセットした場合は、
[アセット・マネージャ](#asset-manager) がアセットを発行して、その結果、このプロパティを上書きします。
[パス・エイリアス](concept-aliases.md) をここで使うことが出来ます。
* [[yii\web\AssetBundle::css|css]]: このバンドルに含まれている CSS ファイルをリストする配列です。
ディレクトリの区切りとしてフォワード・スラッシュ "/" だけを使わなければならないことに注意してください。
それぞれのファイルは、個別に、パス文字列、または、パス文字列と属性のタグと値を一緒に含む配列によって指定することが出来ます。
* [[yii\web\AssetBundle::js|js]]: このバンドルに含まれる JavaScript ファイルをリストする配列です。
この配列の形式は、[[yii\web\AssetBundle::css|css]] の配列の形式と同じです。
それぞれの JavaScript ファイルは、以下の二つの形式のどちらかによって指定することが出来ます。
- ローカルの JavaScript ファイルを表す相対パス (例えば `js/main.js`)。
実際のファイルのパスは、この相対パスの前に [[yii\web\AssetManager::basePath]] を付けることによって決定されます。
また、実際の URL は、この相対パスの前に [[yii\web\AssetManager::baseUrl]] を付けることによって決定されます。
- 外部の JavaScript ファイルを表す絶対 URL。
例えば、`http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js` や
`//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js` など。
* [[yii\web\AssetBundle::depends|depends]]: このバンドルが依存しているアセット・バンドルの名前をリストする配列です
(バンドルの依存関係については、すぐ後で説明します)。
* [[yii\web\AssetBundle::jsOptions|jsOptions]]: このバンドルにある *全て* の JavaScript ファイルについて、
それを登録するときに呼ばれる [[yii\web\View::registerJsFile()]] メソッドに渡されるオプションを指定します。
* [[yii\web\AssetBundle::cssOptions|cssOptions]]: このバンドルにある *全て* の CSS ファイルについて、
それを登録するときに呼ばれる [[yii\web\View::registerCssFile()]] メソッドに渡されるオプションを指定します。
* [[yii\web\AssetBundle::publishOptions|publishOptions]]: ソースのアセット・ファイルをウェブ・ディレクトリに発行するときに呼ばれる
[[yii\web\AssetManager::publish()]] メソッドに渡されるオプションを指定します。
これは [[yii\web\AssetBundle::sourcePath|sourcePath]] プロパティを指定した場合にだけ使用されます。
### アセットの配置場所
アセットは、配置場所を基準にして、次のように分類することが出来ます。
* ソース・アセット: アセット・ファイルは、ウェブ経由で直接にアクセスすることが出来ない PHP ソース・コードと一緒に配置されています。
ページの中でソース・アセットを使用するためには、ウェブ・ディレクトリにコピーして、いわゆる発行されたアセットに変換しなければなりません。
このプロセスは、すぐ後で詳しく説明しますが、*アセット発行* と呼ばれます。
* 発行されたアセット: アセット・ファイルはウェブ・ディレクトリに配置されており、したがってウェブ経由で直接にアクセスすることが出来ます。
* 外部アセット: アセット・ファイルは、あなたのウェブ・アプリケーションをホストしているのとは別のウェブ・サーバ上に
配置されています。
アセット・バンドル・クラスを定義するときに、[[yii\web\AssetBundle::sourcePath|sourcePath]] プロパティを指定した場合は、
相対パスを使ってリストに挙げられたアセットは全てソース・アセットであると見なされます。
このプロパティを指定しなかった場合は、アセットは発行されたアセットであることになります
(したがって、[[yii\web\AssetBundle::basePath|basePath]] と [[yii\web\AssetBundle::baseUrl|baseUrl]] を指定して、アセットがどこに配置されているかを Yii に知らせなければなりません)。
アプリケーションに属するアセットは、不要なアセット発行プロセスを避けるために、ウェブ・ディレクトリに置くことが推奨されます。
前述の例において `AppAsset` が [[yii\web\AssetBundle::sourcePath|sourcePath]] ではなく
[[yii\web\AssetBundle::basePath|basePath]] を指定しているのは、これが理由です。
[エクステンション](structure-extensions.md) の場合は、
アセットがソース・コードと一緒にウェブからアクセス出来ないディレクトリに配置されているため、
アセット・バンドル・クラスを定義するときには [[yii\web\AssetBundle::sourcePath|sourcePath]] プロパティを指定しなければなりません。
> Note: `@webroot/assets` を [[yii\web\AssetBundle::sourcePath|ソース・パス]] として使ってはいけません。
このディレクトリは、デフォルトでは、[[yii\web\AssetManager|アセット・マネージャ]] がソースの配置場所から発行されたアセット・ファイルを保存する場所として使われます。
このディレクトリの中のファイルはすべて一時的なものと見なされており、
削除されることがあります。
### アセットの依存関係
ウェブ・ページに複数の CSS や JavaScript ファイルをインクルードするときは、オーバーライドの問題を避けるために、一定の順序に従わなければなりません。
例えば、ウェブ・ページで jQuery UI ウィジェットを使おうとするときは、jQuery JavaScript ファイルが
jQuery UI JavaScript ファイルより前にインクルードされることを保証しなければなりません。
このような順序付けをアセット間の依存関係と呼びます。
アセットの依存関係は、主として、[[yii\web\AssetBundle::depends]] プロパティによって指定されます。
`AppAsset` の例では、このアセット・バンドルは他の二つのアセット・バンドル、すなわち、[[yii\web\YiiAsset]] と [[yii\bootstrap\BootstrapAsset]] に依存しています。
このことは、`AppAsset` の CSS と JavaScript ファイルが、依存している二つのアセット・バンドルにあるファイルの *後に*
インクルードされることを意味します。
アセットの依存関係は中継されます。つまり、バンドル A が B に依存し、B が C に依存していると、A は C にも依存していることになります。
### アセットのオプション
[[yii\web\AssetBundle::cssOptions|cssOptions]] および [[yii\web\AssetBundle::jsOptions|jsOptions]] のプロパティを指定して、
CSS と JavaScript ファイルがページにインクルードされる方法をカスタマイズすることが出来ます。
これらのプロパティの値は、[ビュー](structure-views.md) が CSS と JavaScript ファイルをインクルードするために、[[yii\web\View::registerCssFile()]] および
[[yii\web\View::registerJsFile()]] メソッドを呼ぶときに、それぞれ、オプションとして引き渡されます。
> Note: バンドル・クラスでセットしたオプションは、バンドルの中の *全て* の CSS/JavaScript ファイルに適用されます。
いろいろなファイルに別々のオプションを使用したい場合は、上述した [[yii\web\AssetBundle::css|css] の形式を使うか、
または、別々のアセット・バンドルを作成して、個々のバンドルの中では、一組のオプションを使うようにしなければなりません。
例えば、IE9 以下のブラウザに対して CSS ファイルを条件的にインクルードするために、次のオプションを使うことが出来ます。
```php
public $cssOptions = ['condition' => 'lte IE9'];
```
こうすると、バンドルの中の CSS ファイルは下記の HTML タグを使ってインクルードされるようになります。
```html
```
生成された CSS のリンクタグを `