资源 ====== 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 ``` 为链接标签包含 `