资源
======
Yii 中的资源是和 Web 页面相关的文件,可为 CSS 文件,JavaScript 文件,图片或视频等,
资源放在 Web 可访问的目录下,直接被 Web 服务器调用。
通过程序自动管理资源更好一点,例如,当你在页面中使用 [[yii\jui\DatePicker]] 小部件时,
它会自动包含需要的 CSS 和 JavaScript 文件,
而不是要求你手工去找到这些文件并包含,
当你升级小部件时,它会自动使用新版本的资源文件,
在本教程中,我们会详述 Yii 提供的强大的资源管理功能。
## 资源包
Yii 在*资源包*中管理资源,资源包简单的说就是放在一个目录下的资源集合,
当在[视图](structure-views.md)中注册一个资源包,
在渲染 Web 页面时会包含包中的 CSS 和 JavaScript 文件。
## 定义资源包
资源包指定为继承 [[yii\web\AssetBundle]] 的 PHP 类,
包名为可[自动加载](concept-autoloading.md)的 PHP 类名,
在资源包类中,要指定资源所在位置,
包含哪些 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]]:指定包包含资源文件的根目录,
当根目录不能被 Web 访问时该属性应设置,否则,应设置
[[yii\web\AssetBundle::basePath|basePath]] 属性和 [[yii\web\AssetBundle::baseUrl|baseUrl]]。
[路径别名](concept-aliases.md) 可在此处使用;
* [[yii\web\AssetBundle::basePath|basePath]]:指定包含资源包中资源文件并可Web访问的目录,
当指定 [[yii\web\AssetBundle::sourcePath|sourcePath]] 属性,
[资源管理器](#asset-manager) 会发布包的资源到一个可 Web 访问并覆盖该属性,
如果你的资源文件在一个 Web 可访问目录下,应设置该属性,这样就不用再发布了。
[路径别名](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 文件的数组。
请注意,只应使用正斜杠“/”作为目录分隔符。
每个 JavaScript 文件可指定为以下两种格式之一:
- 相对路径表示为本地 JavaScript 文件 (如 `js/main.js`),文件实际的路径在该相对路径前加上
[[yii\web\AssetManager::basePath]],文件实际的 URL
在该路径前加上 [[yii\web\AssetManager::baseUrl]]。
- 绝对 URL 地址表示为外部 JavaScript 文件,如
`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]]:当调用 [[yii\web\View::registerJsFile()]] 注册该包 *每个* JavaScript 文件时,
指定传递到该方法的选项。
* [[yii\web\AssetBundle::cssOptions|cssOptions]]:当调用 [[yii\web\View::registerCssFile()]] 注册该包 *每个* CSS 文件时,
指定传递到该方法的选项。
* [[yii\web\AssetBundle::publishOptions|publishOptions]]:当调用 [[yii\web\AssetManager::publish()]] 发布该包资源文件到 Web 目录时
指定传递到该方法的选项,仅在指定了
[[yii\web\AssetBundle::sourcePath|sourcePath]] 属性时使用。
### 资源位置
资源根据它们的位置可以分为:
* 源资源: 资源文件和 PHP 源代码放在一起,不能被 Web 直接访问,为了使用这些源资源,
它们要拷贝到一个可 Web 访问的 Web 目录中
成为发布的资源,这个过程称为*发布资源*,随后会详细介绍。
* 发布资源: 资源文件放在可通过 Web 直接访问的 Web 目录中;
* 外部资源: 资源文件放在与你的 Web 应用不同的
Web 服务器上;
当定义资源包类时候,如果你指定了[[yii\web\AssetBundle::sourcePath|sourcePath]] 属性,
就表示任何使用相对路径的资源会被当作源资源;
如果没有指定该属性,就表示这些资源为发布资源(因此应指定[[yii\web\AssetBundle::basePath|basePath]] 和
[[yii\web\AssetBundle::baseUrl|baseUrl]] 让 Yii 知道它们的位置)。
推荐将资源文件放到 Web 目录以避免不必要的发布资源过程,这就是之前的例子:指定
[[yii\web\AssetBundle::basePath|basePath]]
而不是 [[yii\web\AssetBundle::sourcePath|sourcePath]].
对于[扩展](structure-extensions.md)来说,
由于它们的资源和源代码都在不能Web访问的目录下,
在定义资源包类时必须指定[[yii\web\AssetBundle::sourcePath|sourcePath]]属性。
> Note: [[yii\web\AssetBundle::sourcePath|source path]] 属性不要用 `@webroot/assets`,该路径默认为
[[yii\web\AssetManager|asset manager]] 资源管理器将源资源发布后存储资源的路径,
该路径的所有内容会认为是临时文件,
可能会被删除。
### 资源依赖
当 Web 页面包含多个 CSS 或 JavaScript 文件时,
它们有一定的先后顺序以避免属性覆盖,
例如,Web 页面在使用 jQuery UI 小部件前必须确保 jQuery JavaScript 文件已经被包含了,
我们称这种资源先后次序称为资源依赖。
资源依赖主要通过 [[yii\web\AssetBundle::depends]] 属性来指定,
在 `AppAsset` 示例中,资源包依赖其他两个资源包:
[[yii\web\YiiAsset]] 和 [[yii\bootstrap\BootstrapAsset]]
也就是该资源包的 CSS 和 JavaScript 文件要在这两个依赖包的文件包含*之后*才包含。
资源依赖关系是可传递,也就是说 A 依赖 B,B 依赖 C,那么 A 也依赖 C。
### 资源选项
可指定 [[yii\web\AssetBundle::cssOptions|cssOptions]] 和 [[yii\web\AssetBundle::jsOptions|jsOptions]]
属性来自定义页面包含 CSS 和 JavaScript 文件的方式,
这些属性值会分别传递给 [[yii\web\View::registerCssFile()]] 和 [[yii\web\View::registerJsFile()]] 方法,
在[视图](structure-views.md)调用这些方法包含 CSS 和 JavaScript 文件时。
> Note: 在资源包类中设置的选项会应用到该包中 *每个* CSS/JavaScript 文件,
如果想对每个文件使用不同的选项,
应创建不同的资源包并在每个包中使用一个选项集。
例如,只想 IE9 或更高的浏览器包含一个 CSS 文件,可以使用如下选项:
```php
public $cssOptions = ['condition' => 'lte IE9'];
```
这会使包中的 CSS 文件使用以下 HTML 标签包含进来:
```html
```
为链接标签包含 `