Yii2 framework backup
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

649 lines
62 KiB

Ресурсы
======
Ресурс в Yii это файл который может быть задан в Web странице. Это может быть CSS файл, JavaScript файл, изображение или видео файл и т.д. Ресурсы располагаются в Web доступных директориях и обслуживаются непосредственно Web серверами.
Желательно, управлять ресурсами программно. Например, при использовании виджета [[yii\jui\DatePicker]] в странице, автоматически включаются необходимые CSS и JavaScript файлы, вместо того чтобы просить Вас в ручную найти эти файлы и включить их. И когда Вы обновляете виджет до новой версии, будут автоматически использованы новые версии файлов-ресурсов. В этом руководстве будет описана мощная возможность управления ресурсами представленная в Yii.
## Комплекты ресурсов <span id="asset-bundles"></span>
Yii управляет ресурсами как единицей *комплекта ресурсов*. Комплект ресурсов - это простой набор ресурсов расположенных в директории. Когда Вы регистрируете комплект ресурсов в [представлении](structure-views.md), в отображаемой Web странице включается набор CSS и JavaScript файлов.
## Задание Комплекта Ресурсов<span id="defining-asset-bundles"></span>
Комплект ресурсов определяется как PHP класс расширяющийся от [[yii\web\AssetBundle]]. Имя комплекта соответствует полному имени PHP класса (без ведущей обратной косой черты - backslash "\"). Класс комплекта ресурсов должен быть в состоянии [возможности автозагрузки](concept-autoloading.md). При задании комплекта ресурсов обычно указывается где ресурсы находятся, какие CSS и JavaScript файлы содержит комплект, и как комплект зависит от других комплектов.
Следующий код задаёт основной комплект ресурсов используемый в [шаблоне базового приложения](start-installation.md):
```php
<?php
namespace app\assets;
use yii\web\AssetBundle;
class AppAsset extends AssetBundle
{
public $basePath = '@webroot';
public $baseUrl = '@web';
public $css = [
'css/site.css',
];
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]]: задаёт URL соответствующий директории [[yii\web\AssetBundle::basePath|basePath]]. Также как и для [[yii\web\AssetBundle::basePath|basePath]], если Вы задаёте свойство [[yii\web\AssetBundle::sourcePath|sourcePath]] [Менеджер ресурсов](#asset-manager) опубликует ресурсы и перезапишет это свойство соответственно. Здесь могут быть использованы [псевдонимы путей](concept-aliases.md).
* [[yii\web\AssetBundle::js|js]]: массив, перечисляющий JavaScript файлы, содержащиеся в данном комплекте. Заметьте, что только прямая косая черта (forward slash - "/") может быть использована, как разделитель директорий. Каждый 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::css|css]]: массив, перечисляющий CSS файлы, содержащиеся в данном комплекте. Формат этого массива такой же, как и у [[yii\web\AssetBundle::js|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]].
### Расположение ресурсов<span id="asset-locations"></span>
Ресурсы, в зависимости от их расположения, могут быть классифицированы как:
* исходные ресурсы: файлы ресурсов, расположенные вместе с исходным кодом PHP, которые не могут быть непосредственно доступны через Web. Для того, чтобы использовать исходные ресурсы на странице, они должны быть скопированы в Web директорию и превратиться в так называемые опубликованные ресурсы. Этот процесс называется *публикацией ресурсов*, который более подробно описан ниже
* опубликованные ресурсы: файлы ресурсов, расположенные в Web директории и, таким образом, могут быть напрямую доступны через Web.
* внешние ресурсы: файлы ресурсов, расположенные на другом Web сервере, отличного от веб-хостинга вашего приложения.
При определении класса комплекта ресурсов, если Вы задаёте свойство [[yii\web\AssetBundle::sourcePath|sourcePath]], это означает, что любые перечисленные ресурсы, используя относительные пути, будут рассматриваться как исходные ресурсы. Если Вы не задаёте данное свойство, это означает, что эти ресурсы - это опубликованные ресурсы (в этом случае Вам следует указать [[yii\web\AssetBundle::basePath|basePath]] и [[yii\web\AssetBundle::baseUrl|baseUrl]], чтобы дать знать Yii где ресурсы располагаются).
Рекомендуется размещать ресурсы, принадлежащие приложению, в Web директорию, для того, чтобы избежать не нужного процесса публикации ресурсов. Вот почему `AppAsset` в предыдущем примере задаёт [[yii\web\AssetBundle::basePath|basePath]] вместо [[yii\web\AssetBundle::sourcePath|sourcePath]].
Для [расширений](structure-extensions.md), в связи с тем, что их ресурсы располагаются вместе с их исходным кодом в директориях, которые не являются веб-доступными, необходимо указать свойство [[yii\web\AssetBundle::sourcePath|sourcePath]] при задании класса комплекта ресурсов для них.
> Note: Не используйте `@webroot/assets` как [[yii\web\AssetBundle::sourcePath|source path]]. Эта директория по умолчанию используется менеджером ресурсов [[yii\web\AssetManager|asset manager]] для сохранения файлов ресурсов, опубликованных из их исходного месторасположения. Любое содержимое этой директории расценивается как временное и может быть удалено.
### Зависимости ресурсов <span id="asset-dependencies"></span>
Когда Вы включаете несколько CSS или JavaScript файлов в Web страницу, они должны следовать в определенном порядке, <b> чтобы избежать переопределения при выдаче</b>. Например, если Вы используете виджет jQuery UI в Web странице, вы должны убедиться, что jQuery JavaScript файл был включен до jQuery UI JavaScript файла. Мы называем такой порядок зависимостью между ресурсами.
Зависимости ресурсов в основном указываются через свойство [[yii\web\AssetBundle::depends]]. Например в `AppAsset`, комплект ресурсов зависит от двух других комплектов ресурсов: [[yii\web\YiiAsset]] и [[yii\bootstrap\BootstrapAsset]], что обозначает, что CSS и JavaScript файлы `AppAsset` будут включены *после* файлов этих двух комплектов зависимостей.
Зависимости ресурсов являются также зависимыми. Это значит, что если комплект А зависит от В, который зависит от С, то А тоже зависит от С.
### Параметры ресурсов <span id="asset-options"></span>
Вы можете задать свойства [[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-файла в комплекте. Если Вы хотите использовать различные параметры для разных файлов, Вы должны создать раздельные комплекты ресурсов, и использовать одну установку параметров для каждого комплекта.
Например, условно включим CSS файл для браузера IE9 или ниже. Для этого Вы можете использовать следующий параметр:
```php
public $cssOptions = ['condition' => 'lte IE9'];
```
Это вызовет CSS файл из комплекта, который будет включен в страницу, используя следующие HTML теги:
```html
<!--[if lte IE9]>
<link rel="stylesheet" href="path/to/foo.css">
<![endif]-->
```
Для того чтобы обернуть созданную CSS ссылку в тег `<noscript>`, Вы можете настроить `cssOptions` следующим образом:
```php
public $cssOptions = ['noscript' => true];
```
Для включения JavaScript файла в head раздел страницы (по умолчанию, JavaScript файлы включаются в конец раздела body) используйте следующий параметр:
```php
public $jsOptions = ['position' => \yii\web\View::POS_HEAD];
```
По умолчанию, когда комплект ресурсов публикуется, всё содержимое в заданной директории [[yii\web\AssetBundle::sourcePath]] будет опубликовано. Вы можете настроить это поведение, сконфигурировав свойство [[yii\web\AssetBundle::publishOptions|publishOptions]]. Например, опубликовать одну или несколько поддиректорий [[yii\web\AssetBundle::sourcePath]] в классе комплекта ресурсов Вы можете в следующим образом:
```php
<?php
namespace app\assets;
use yii\web\AssetBundle;
class FontAwesomeAsset extends AssetBundle
{
public $sourcePath = '@bower/font-awesome';
public $css = [
'css/font-awesome.min.css',
];
public function init()
{
parent::init();
$this->publishOptions['beforeCopy'] = function ($from, $to) {
$dirname = basename(dirname($from));
return $dirname === 'fonts' || $dirname === 'css';
};
}
}
```
В выше указанном примере определён комплект ресурсов для [пакета "fontawesome"](http://fontawesome.io/). Задан параметр публикации `beforeCopy`, здесь только `fonts` и `css` поддиректории будут опубликованы.
### Bower и NPM Ресурсы<span id="bower-npm-assets"></span>
Большинство JavaScript/CSS пакетов управляются [Bower](http://bower.io/) и/или [NPM](https://www.npmjs.org/).
Если Вашим приложением или расширением используется такой пакет, то рекомендуется следовать следующим этапам для управления ресурсами библиотеки:
1. Исправить файл `composer.json` Вашего приложения или расширения и включить пакет в список в раздел `require`. Следует использовать `bower-asset/PackageName` (для Bower пакетов) или `npm-asset/PackageName` (для NPM пакетов) для обращения к соответствующей библиотеке.
2. Создать класс комплекта ресурсов и перечислить JavaScript/CSS файлы, которые Вы планируете использовать в Вашем приложении или расширении. Вы должны задать свойство [[yii\web\AssetBundle::sourcePath|sourcePath]] как `@bower/PackageName` или `@npm/PackageName`.
Это происходит потому, что Composer устанавливает Bower или NPM пакет в директорию, соответствующую этим псевдонимам.
> Note: В некоторых пакетах файлы дистрибутива могут находиться в поддиректории. В этом случае, Вы должны задать поддиректорию как значение [[yii\web\AssetBundle::sourcePath|sourcePath]]. Например, [[yii\web\JqueryAsset]] использует `@bower/jquery/dist` вместо `@bower/jquery`.
## Использование Комплекта Ресурсов<span id="using-asset-bundles"></span>
Для использования комплекта ресурсов, зарегистрируйте его в [представлении](structure-views.md) вызвав метод [[yii\web\AssetBundle::register()]]. Например, комплект ресурсов в представлении может быть зарегистрирован следующим образом:
```php
use app\assets\AppAsset;
AppAsset::register($this); // $this - представляет собой объект представления
```
> Info: Метод [[yii\web\AssetBundle::register()]] возвращает объект комплекта ресурсов, содержащий информацию о публикуемых ресурсах, таких как [[yii\web\AssetBundle::basePath|basePath]] или [[yii\web\AssetBundle::baseUrl|baseUrl]].
Если Вы регистрируете комплект ресурсов в других местах (т.е. не в представлении), Вы должны обеспечить необходимый объект представления. Например, при регистрации комплекта ресурсов в классе [widget](structure-widgets.md), Вы можете взять за объект представления `$this->view`.
Когда комплект ресурсов регистрируется в представлении, Yii регистрирует все зависимые от него комплекты ресурсов. И, если комплект ресурсов расположен в директории не доступной из Web, то он будет опубликован в Web директории. Затем, когда представление отображает страницу, сгенерируются теги `<link>` и `<script>` для CSS и JavaScript файлов, перечисленных в регистрируемых комплектах. Порядок этих тегов определён зависимостью среди регистрируемых комплектов, и последовательность ресурсов перечислена в [[yii\web\AssetBundle::css]] и [[yii\web\AssetBundle::js]] свойствах.
### Динамические Комплекты Ресурсов <span id="dynamic-asset-bundles"></span>
Поскольку комплект ресурсов это обычный PHP класс, он может содержать дополнительную логику, связанную с ним, и может
корректировать свои внутренние параметры динамически. Например, вы можете использовать сложную JavaScript библиотеку,
которая предоставляет интернационализацию через отдельные исходные файлы: по одному на каждый поддерживаемый язык.
Таким образом, вам нужно добавить определенный '.js' файл на вашу страницу, чтобы применить перевод для библиотеки.
Этого можно достичь, переопределив метод [[yii\web\AssetBundle::init()]]:
```php
namespace app\assets;
use yii\web\AssetBundle;
use Yii;
class SophisticatedAssetBundle extends AssetBundle
{
public $sourcePath = '/path/to/sophisticated/src';
public $js = [
'sophisticated.js' // file, which is always used
];
public function init()
{
parent::init();
$this->js[] = 'i18n/' . Yii::$app->language . '.js'; // dynamic file added
}
}
```
Конкретный комплект ресурсов может быть также изменен через его экземпляр, возвращенный методом [[yii\web\AssetBundle::register()]].
Например:
```php
use app\assets\SophisticatedAssetBundle;
use Yii;
$bundle = SophisticatedAssetBundle::register(Yii::$app->view);
$bundle->js[] = 'i18n/' . Yii::$app->language . '.js'; // dynamic file added
```
> Замечание: несмотря на то что динамическая корректрировка комплекта ресурсов поддерживается, ее использование - это
**плохая** практика, которая может привести к неожиданным побочных эффектам, и которой следует избегать.
### Настройка Комплектов Ресурсов <span id="customizing-asset-bundles"></span>
Yii управляет комплектами ресурсов через компонент приложения называемый `assetManager`, который реализован в [[yii\web\AssetManager]]. Путём настройки свойства [[yii\web\AssetManager::bundles]], возможно настроить поведение комплекта ресурсов. Например, комплект ресурсов [[yii\web\JqueryAsset]] по умолчанию использует `jquery.js` файл из установленного jquery Bower пакета. Для повышения доступности и производительности, можно использовать версию jquery на Google хостинге.
Это может быть достигнуто, настроив `assetManager` в конфигурации приложения следующим образом:
```php
return [
// ...
'components' => [
'assetManager' => [
'bundles' => [
'yii\web\JqueryAsset' => [
'sourcePath' => null, // не опубликовывать комплект
'js' => [
'//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js',
]
],
],
],
],
];
```
Можно сконфигурировать несколько комплектов ресурсов аналогично через [[yii\web\AssetManager::bundles]]. Ключи массива должны быть именами класса (без впереди стоящей обратной косой черты) комплектов ресурсов, а значения массивов должны соответствовать [конфигурации массивов](concept-configurations.md).
> Совет: Можно условно выбрать, какой из ресурсов будет использован в комплекте ресурсов. Следующий пример показывает, как можно использовать в разработке окружения `jquery.js` или `jquery.min.js` в противном случае:
> ```php
> 'yii\web\JqueryAsset' => [
> 'js' => [
> YII_ENV_DEV ? 'jquery.js' : 'jquery.min.js'
> ]
> ],
> ```
Можно запретить один или несколько комплектов ресурсов, связав `false` с именами комплектов ресурсов, которые Вы хотите сделать недоступными. Когда Вы регистрируете недоступный комплект ресурсов в представлении, обратите внимание, что зависимость комплектов будет зарегистрирована, и представление также не включит ни один из ресурсов комплекта в отображаемую страницу. Например, для запрета [[yii\web\JqueryAsset]] можно использовать следующую конфигурацию:
```php
return [
// ...
'components' => [
'assetManager' => [
'bundles' => [
'yii\web\JqueryAsset' => false,
],
],
],
];
```
Можно также запретить *все* комплекты ресурсов, установив [[yii\web\AssetManager::bundles]] как `false`.
Имейте в виду, что настройки, установленный через [[yii\web\AssetManager::bundles]], применяются в момент создания комплекта
ресурсов, т.е. в момент срабатывания конструктора. Таким образом, любые изменения, которые произведены над экземпляром
комплекта ресурсов после этого, перекроют настройки, установленные на уровне [[yii\web\AssetManager::bundles]].
В частности, изменения, произведенные внутри метода [[yii\web\AssetBundle::init()]] или после регистрации комплекта ресурсов,
имеют приоритет над настройками `AssetManager`.
Ниже приведены примеры, в которых значения, установленные через [[yii\web\AssetManager::bundles]] не возымеют никакого эффекта:
```php
// Program source code:
namespace app\assets;
use yii\web\AssetBundle;
use Yii;
class LanguageAssetBundle extends AssetBundle
{
// ...
public function init()
{
parent::init();
$this->baseUrl = '@web/i18n/' . Yii::$app->language; // can NOT be handled by `AssetManager`!
}
}
// ...
$bundle = \app\assets\LargeFileAssetBundle::register(Yii::$app->view);
$bundle->baseUrl = YII_DEBUG ? '@web/large-files': '@web/large-files/minified'; // can NOT be handled by `AssetManager`!
// Application config :
return [
// ...
'components' => [
'assetManager' => [
'bundles' => [
'app\assets\LanguageAssetBundle' => [
'baseUrl' => 'http://some.cdn.com/files/i18n/en' // makes NO effect!
],
'app\assets\LargeFileAssetBundle' => [
'baseUrl' => 'http://some.cdn.com/files/large-files' // makes NO effect!
],
],
],
],
];
```
### Привязка ресурсов<span id="asset-mapping"></span>
Иногда необходимо исправить пути до файлов ресурсов, в нескольких комплектах ресурсов. Например, комплект А использует `jquery.min.js` версии 1.11.1, а комплект В использует `jquery.js` версии 2.1.1. Раньше Вы могли решить данную проблему, настраивая каждый комплект ресурсов по отдельности, но более простой способ - использовать *asset map* возможность, чтобы найти неверные ресурсы и исправить их. Сделать это можно, сконфигурировав свойство [[yii\web\AssetManager::assetMap]] следующим образом:
```php
return [
// ...
'components' => [
'assetManager' => [
'assetMap' => [
'jquery.js' => '//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js',
],
],
],
];
```
Ключи [[yii\web\AssetManager::assetMap|assetMap]] - это имена ресурсов, которые Вы хотите исправить, а значения - это требуемые пути для ресурсов. Когда регистрируется комплект ресурсов в представлении, каждый соответствующий файл ресурса в [[yii\web\AssetBundle::css|css]] или [[yii\web\AssetBundle::js|js]] массивах будет рассмотрен в соответствии с этой привязкой. И, если какой-либо из ключей найден, как последняя часть пути до файла ресурса (путь на который начинается с [[yii\web\AssetBundle::sourcePath]] по возможности), то соответствующее значение заменит ресурс и будет зарегистрировано в представлении. Например, путь до файла ресурса `my/path/to/jquery.js` - это соответствует ключу `jquery.js`.
> Note: Ресурсы заданные только с использованием относительного пути могут использоваться в привязке ресурсов. Пути ресурсов должны быть абсолютные URLs или путь относительно [[yii\web\AssetManager::basePath]].
### Публикация Ресурсов<span id="asset-publishing"></span>
Как уже было сказано выше, если комплект ресурсов располагается в директории которая не доступна из Web, эти ресурсы будут скопированы в Web директорию, когда комплект будет зарегистрирован в представлении. Этот процесс называется *публикацией ресурсов*, его автоматически выполняет [[yii\web\AssetManager|asset manager]].
По умолчанию, ресурсы публикуются в директорию `@webroot/assets` которая соответствует URL `@web/assets`. Можно настроить это местоположение сконфигурировав свойства [[yii\web\AssetManager::basePath|basePath]] и [[yii\web\AssetManager::baseUrl|baseUrl]].
Вместо публикации ресурсов путём копирования файлов, можно рассмотреть использование символических ссылок, если Ваша операционная система или Web сервер это разрешают. Эта функция может быть включена путем установки [[yii\web\AssetManager::linkAssets|linkAssets]] в `true`.
```php
return [
// ...
'components' => [
'assetManager' => [
'linkAssets' => true,
],
],
];
```
С конфигурацией, установленной выше, менеджер ресурсов будет создавать символические ссылки на исходные пути комплекта ресурсов когда он будет публиковаться. Это быстрее, чем копирование файлов, а также может гарантировать, что опубликованные ресурсы всегда up-to-date(обновлённые/свежие).
### Перебор Кэша<span id="cache-busting"></span>
Для Web приложения запущенного в режиме продакшена, считается нормальной практикой разрешить HTTP кэширование для ресурсов и других статичных источников. Недостаток такой практики в том, что всякий раз, когда изменяется ресурс и разворачивается продакшен, пользователь может по-прежнему использовать старую версию ресурса вследствие HTTP кэширования. Чтобы избежать этого, можно использовать возможность перебора кэша, которая была добавлена в версии 2.0.3, для этого можно настроить [[yii\web\AssetManager]] следующим образом:
```php
return [
// ...
'components' => [
'assetManager' => [
'appendTimestamp' => true,
],
],
];
```
Делая таким образом, к URL каждого опубликованного ресурса будет добавляться временная метка его последней модификации. Например, URL для `yii.js` может выглядеть как `/assets/5515a87c/yii.js?v=1423448645"`, где параметр `v` представляет собой временную метку последней модификации файла `yii.js`. Теперь если изменить ресурс, его URL тоже будет изменен, это означает что клиент получит последнюю версию ресурса.
## Обычное Использование Комплекта Ресурсов<span id="common-asset-bundles"></span>
Код ядра Yii содержит большое количество комплектов ресурсов. Среди них, следующие комплекты широко используются и могут упоминаться в Вашем приложении или коде расширения:
- [[yii\web\YiiAsset]]: Включает основной `yii.js` файл который реализует механизм организации JavaScript кода в модулях. Также обеспечивает специальную поддержку для `data-method` и `data-confirm` атрибутов и содержит другие полезные функции.
- [[yii\web\JqueryAsset]]: Включает `jquery.js` файл из jQuery Bower пакета.
- [[yii\bootstrap\BootstrapAsset]]: Включает CSS файл из Twitter Bootstrap фреймворка.
- [[yii\bootstrap\BootstrapPluginAsset]]: Включает JavaScript файл из Twitter Bootstrap фреймворка для поддержки Bootstrap JavaScript плагинов.
- [[yii\jui\JuiAsset]]: Включает CSS и JavaScript файлы из jQuery UI библиотеки.
Если Ваш код зависит от jQuery, jQuery UI или Bootstrap, Вам необходимо использовать эти предопределенные комплекты ресурсов, а не создавать свои собственные варианты. Если параметры по умолчанию этих комплектов не удовлетворяют Вашим нуждам, Вы можете настроить их как описано в подразделе [Настройка Комплектов Ресурсов](#customizing-asset-bundles).
## Преобразование Ресурсов<span id="asset-conversion"></span>
Вместо того, чтобы напрямую писать CSS и/или JavaScript код, разработчики часто пишут его в некотором <b>расширенном синтаксисе</b> и используют специальные инструменты конвертации в CSS/JavaScript. Например, для CSS кода можно использовать [LESS](http://lesscss.org/) или [SCSS](http://sass-lang.com/); а для JavaScript можно использовать [TypeScript](http://www.typescriptlang.org/).
Можно перечислить файлы ресурсов в <b>расширенном синтаксисе</b> в [[yii\web\AssetBundle::css|css]] и [[yii\web\AssetBundle::js|js]] свойствах из комплекта ресурсов. Например,
```php
class AppAsset extends AssetBundle
{
public $basePath = '@webroot';
public $baseUrl = '@web';
public $css = [
'css/site.less',
];
public $js = [
'js/site.ts',
];
public $depends = [
'yii\web\YiiAsset',
'yii\bootstrap\BootstrapAsset',
];
}
```
Когда Вы регистрируете такой комплект ресурсов в представлении, [[yii\web\AssetManager|asset manager]] автоматически запустит нужные инструменты препроцессора и конвертирует ресурсы в CSS/JavaScript, если их расширенный синтаксис распознан. Когда представление окончательно отобразит страницу, в неё будут включены файлы CSS/JavaScript, вместо оригинальных ресурсов в расширенном синтаксисе.
Yii использует имена расширений файлов для идентификации расширенного синтаксиса внутри ресурса. По умолчанию признаны следующие синтаксисы и имена расширений файлов:
- [LESS](http://lesscss.org/): `.less`
- [SCSS](http://sass-lang.com/): `.scss`
- [Stylus](http://learnboost.github.io/stylus/): `.styl`
- [CoffeeScript](http://coffeescript.org/): `.coffee`
- [TypeScript](http://www.typescriptlang.org/): `.ts`
Yii ориентируется на установленные инструменты конвертации ресурсов препроцессора. Например, используя [LESS](http://lesscss.org/), Вы должны установить команду `lessc` препроцессора.
Вы можете настроить команды препроцессора и поддерживать расширенный синтаксис сконфигурировав [[yii\web\AssetManager::converter]] следующим образом:
```php
return [
'components' => [
'assetManager' => [
'converter' => [
'class' => 'yii\web\AssetConverter',
'commands' => [
'less' => ['css', 'lessc {from} {to} --no-color'],
'ts' => ['js', 'tsc --out {to} {from}'],
],
],
],
],
];
```
В примере выше, Вы задали поддержку расширенного синтаксиса через [[yii\web\AssetConverter::commands]] свойство.
Ключи массива - это имена расширений файлов (без ведущей точки), а значения массива - это образующийся файл ресурса имён расширений и команд для выполнения конвертации ресурса. Маркеры `{from}` и `{to}` в командах будут заменены соответственно исходным путём файла ресурсов и путём назначения файла ресурсов.
> Note: Существуют другие способы работы с ресурсами расширенного синтаксиса, кроме того, который указан выше.
Например, Вы можете использовать инструменты построения, такие как [grunt](http://gruntjs.com/) для отслеживания и автоматической конвертации ресурсов расширенного синтаксиса. В этом случае, Вы должны перечислить конечные CSS/JavaScript файлы в комплекте ресурсов вместо исходных файлов.
## Объединение и Сжатие Ресурсов<span id="combining-compressing-assets"></span>
Web страница может включать много CSS и/или JavaScript файлов. Чтобы сократить количество HTTP запросов и общий размер загрузки этих файлов, общепринятой практикой является объединение и сжатие нескольких CSS/JavaScript файлов в один или в более меньшее количество, а затем включение этих сжатых файлов вместо исходных в Web страницы.
> Note: Комбинирование и сжатие ресурсов обычно необходимо, когда приложение находится в режиме продакшена.
В режиме разработки, использование исходных CSS/JavaScript файлов часто более удобно для отладочных целей.
Далее, мы представим подход комбинирования и сжатия файлов ресурсов без необходимости изменения Вашего существующего кода приложения.
1. Найдите все комплекты ресурсов в Вашем приложении, которые Вы планируете скомбинировать и сжать.
2. Распределите эти комплекты в одну или несколько групп. Обратите внимание, что каждый комплект может принадлежать только одной группе.
3. Скомбинируйте/сожмите CSS файлы каждой группы в один файл. Сделайте то же самое для JavaScript файлов.
4. Определите новый комплект ресурсов для каждой группы:
* Или установите [[yii\web\AssetBundle::css|css]] и [[yii\web\AssetBundle::js|js]] свойства. Соответствующие CSS и JavaScript файлы будут объединены.
* Или настройте комплекты ресурсов каждой группы, установив их [[yii\web\AssetBundle::css|css]] и [[yii\web\AssetBundle::js|js]] свойства как пустые, и установите их [[yii\web\AssetBundle::depends|depends]] свойство как новый комплект ресурсов, созданный для группы.
Используя этот подход, при регистрации комплекта ресурсов в представлении, автоматически регистрируется новый комплект ресурсов для группы, к которому исходный комплект принадлежит. В результате скомбинированные/сжатые файлы ресурсов включаются в страницу вместо исходных.
### Пример <span id="example"></span>
Давайте рассмотрим пример, чтобы объяснить вышеуказанный подход.
Предположим, ваше приложение имеет две страницы, X и Y. Страница X использует комплект ресурсов A, B и C, в то время, как страница Y использует комплект ресурсов, B, C и D.
У Вас есть два пути, чтобы разделить эти комплекты ресурсов. Первый - использовать одну группу, включающую в себя все комплекты ресурсов. Другой путь - положить комплект А в группу Х, D в группу Y, а (B, C) в группу S. Какой из этих вариантов лучше? Это зависит. Первый способ имеет преимущество в том, что в обоих страницах одинаково скомбинированы файлы CSS и JavaScript, что делает HTTP кэширование более эффективным. С другой стороны, поскольку одна группа содержит все комплекты, размер скомбинированных CSS и JavaScript файлов будет больше, и таким образом увеличится время отдачи файла (загрузки страницы). Для простоты в этом примере, мы будем использовать первый способ, то есть использовать единую группу, содержащую все пакеты.
> Note: Разделение комплекта ресурсов на группы это не тривиальная задача. Это, как правило, требует анализа реальных данных о трафике различных ресурсов на разных страницах. В начале вы можете начать с одной группы, для простоты.
Используйте существующие инструменты (например [Closure Compiler](https://developers.google.com/closure/compiler/),
[YUI Compressor](https://github.com/yui/yuicompressor/)) для объединения и сжатия CSS и JavaScript файлов во всех комплектах. Обратите внимание, что файлы должны быть объединены в том порядке, который удовлетворяет зависимости между комплектами. Например, если комплект A зависит от В, который зависит от С и D, то Вы должны перечислить файлы ресурсов начиная с С и D, затем B, и только после этого А.
После объединения и сжатия, Вы получите один CSS файл и один JavaScript файл. Предположим, они названы как `all-xyz.css` и `all-xyz.js`, где `xyz` это временная метка или хэш, который используется, чтобы создать уникальное имя файла, чтобы избежать проблем с HTTP кэшированием.
Сейчас мы находимся на последнем шаге. Настройте [[yii\web\AssetManager|asset manager]] в конфигурации вашего приложения, как показано ниже:
```php
return [
'components' => [
'assetManager' => [
'bundles' => [
'all' => [
'class' => 'yii\web\AssetBundle',
'basePath' => '@webroot/assets',
'baseUrl' => '@web/assets',
'css' => ['all-xyz.css'],
'js' => ['all-xyz.js'],
],
'A' => ['css' => [], 'js' => [], 'depends' => ['all']],
'B' => ['css' => [], 'js' => [], 'depends' => ['all']],
'C' => ['css' => [], 'js' => [], 'depends' => ['all']],
'D' => ['css' => [], 'js' => [], 'depends' => ['all']],
],
],
],
];
```
Как объяснено в подразделе [Настройка Комплектов Ресурсов](#customizing-asset-bundles), приведенная выше конфигурация
изменяет поведение по умолчанию каждого комплекта. В частности, комплекты A, B, C и D не имеют больше никаких файлов ресурсов. Теперь они все зависят от `all` комплекта, который содержит скомбинированные `all-xyz.css` и `all-xyz.js` файлы. Следовательно, для страницы X, вместо включения исходных файлов ресурсов из комплектов A, B и C, только два этих объединённых файла будут включены, то же самое произойдёт и со страницей Y.
Есть еще один трюк, чтобы сделать работу вышеуказанного подхода более отлаженной. Вместо изменения конфигурационного файла приложения напрямую, можно поставить комплект массива настроек в отдельный файл, и условно включить этот файл в конфигурацию приложения. Например,
```php
return [
'components' => [
'assetManager' => [
'bundles' => require(__DIR__ . '/' . (YII_ENV_PROD ? 'assets-prod.php' : 'assets-dev.php')),
],
],
];
```
То есть, массив конфигурации комплекта ресурсов сохраняется в `assets-prod.php` для режима продакшена, и в `assets-dev.php` для режима не продакшена (разработки).
> Замечание: этот механизм объединения комплектов ресурсов основан на способности [[yii\web\AssetManager::bundles]] перекрывать
поля регистрируемых комплектов ресурсов. Однако, как уже было сказано выше, эта возможность не распространяется на
изменения, внесенные в комплекты ресурсов на уровне метода [[yii\web\AssetBundle::init()]] ил после регистрации. Вам
следует избегать использования динамических комплектов ресурсов в процессе объединения.
### Использование команды `asset`<span id="using-asset-command"></span>
Yii предоставляет консольную команду с именем `asset` для автоматизации подхода, который мы только что описали.
Чтобы использовать эту команду, Вы должны сначала создать файл конфигурации для описания того, как комплекты ресурсов должны быть скомбинированы, и как они должны быть сгруппированы. Затем Вы можете использовать подкомманду `asset/template`, чтобы сгенерировать первый шаблон и затем отредактировать его под свои нужды.
```
yii asset/template assets.php
```
Данная команда сгенерирует файл с именем `assets.php` в текущей директории. Содержание этого файла можно увидеть ниже:
```php
<?php
/**
* Файл конфигурации команды консоли "yii asset".
* Обратите внимание, что в консольной среде, некоторые псевдонимы путей, такие как "@webroot' и '@web ",
* не могут быть использованы.
* Пожалуйста, определите отсутствующие псевдонимы путей.
*/
return [
// Настроить команду/обратный вызов для сжатия файлов JavaScript:
'jsCompressor' => 'java -jar compiler.jar --js {from} --js_output_file {to}',
// Настроить команду/обратный вызов для сжатия файлов CSS:
'cssCompressor' => 'java -jar yuicompressor.jar --type css {from} -o {to}',
// Whether to delete asset source after compression:
'deleteSource' => false,
// Список комплектов ресурсов для сжатия:
'bundles' => [
// 'yii\web\YiiAsset',
// 'yii\web\JqueryAsset',
],
// Комплект ресурса после сжатия:
'targets' => [
'all' => [
'class' => 'yii\web\AssetBundle',
'basePath' => '@webroot/assets',
'baseUrl' => '@web/assets',
'js' => 'js/all-{hash}.js',
'css' => 'css/all-{hash}.css',
],
],
// Настройка менеджера ресурсов:
'assetManager' => [
],
];
```
Вы должны изменить этот файл и указать в `bundles` параметре, какие комплекты Вы планируете объединить. В параметре `targets` вы должны указать, как комплекты должны быть поделены в группы. Вы можете указать одну или несколько групп, как уже было сказано выше.
> Note: Так как псевдонимы путей `@webroot` и `@web` не могут быть использованы в консольном приложении, Вы должны явно задать их в файле конфигурации.
JavaScript файлы объединены, сжаты и записаны в `js/all-{hash}.js`, где {hash} перенесён из хэша результирующего файла.
Параметры `jsCompressor` и `cssCompressor` указывают на консольные команды или обратный вызов PHP, выполняющие JavaScript и CSS объединение/сжатие. По умолчанию Yii использует [Closure Compiler](https://developers.google.com/closure/compiler/) для объединения JavaScript файлов и [YUI Compressor](https://github.com/yui/yuicompressor/) для объединения CSS файлов. Вы должны установить эти инструменты вручную или настроить данные параметры, чтобы использовать ваши любимые инструменты.
Вы можете запустить команду `asset` с файлом конфигурации для объединения и сжатия файлов ресурсов, а затем создать новый файл конфигурации комплекта ресурса `assets-prod.php`:
```
yii asset assets.php config/assets-prod.php
```
Сгенерированный файл конфигурации может быть включен в конфигурацию приложения, как описано в последнем подразделе.
> Примечание: в случае если вы перенастраиваете комплекты ресурсов через [[yii\web\AssetManager::bundles]] или
[[yii\web\AssetManager::assetMap]], и хотите, чтобы эти настройки применились для исходных файлов для сжатия,
вы должны занести эти опции в раздел `assetManager` файла кофигурации для команды `asset`.
> Замечание: составляя набор исходных комплектов ресурсов для сжатия, следует избегать использования таких, чьи параметры
могут изменяться динамически (т.е. на уровне метода `init()` или после регистрации), поскольку они могут функционировать
неправильно после сжатия.
> Для справки: Команда `asset` является не единственной опцией для автоматического процесса объединения и сжатия ресурсов.
Вы можете также использовать такой замечательный инструмент запуска приложений как [grunt](http://gruntjs.com/) для достижения той же цели.
### Группировка Комплектов Ресурсов <span id="grouping-asset-bundles"></span>
В последнем подразделе, мы пояснили, как объединять все комплекты ресурсов в единый в целях минимизации HTTP запросов для файлов ресурсов, упоминавшихся в приложении. Это не всегда желательно на практике. Например, представьте себе, что Ваше приложение содержит "front end", а также и "back end", каждый из которых использует свой набор JavaScript и CSS файлов. В этом случае, объединение всех комплектов ресурсов с обеих сторон в один не имеет смысла потому, что комплекты ресурсов для "front end" не используются в "back end", и это будет бесполезной тратой трафика - отправлять "back end" ресурсы, когда страница из "front end" будет запрошена.
Для решения вышеуказанной проблемы, вы можете разделить комплекты по группам и объединить комплекты ресурсов для каждой группы. Следующая конфигурация показывает, как Вы можете объединять комплекты ресурсов:
```php
return [
...
// Укажите выходной комплект для групп:
'targets' => [
'allShared' => [
'js' => 'js/all-shared-{hash}.js',
'css' => 'css/all-shared-{hash}.css',
'depends' => [
// Включаем все ресурсы поделённые между 'backend' и 'frontend'
'yii\web\YiiAsset',
'app\assets\SharedAsset',
],
],
'allBackEnd' => [
'js' => 'js/all-{hash}.js',
'css' => 'css/all-{hash}.css',
'depends' => [
// Включаем только 'backend' ресурсы:
'app\assets\AdminAsset'
],
],
'allFrontEnd' => [
'js' => 'js/all-{hash}.js',
'css' => 'css/all-{hash}.css',
'depends' => [], // Включаем все оставшиеся ресурсы
],
],
...
];
```
Как вы можете видеть, комплекты ресурсов поделены на три группы: `allShared`, `allBackEnd` и `allFrontEnd`. Каждая из которых зависит от соответствующего набора комплектов ресурсов. Например, `allBackEnd` зависит от `app\assets\AdminAsset`. При запуске команды `asset` с данной конфигурацией будут объединены комплекты ресурсов согласно приведенной выше спецификации.
> Для справки: Вы можете оставить `depends` конфигурацию пустой для одного из намеченных комплектов. Поступая таким образом, данный комплект ресурсов будет зависеть от всех остальных комплектов ресурсов, от которых другие целевые комплекты не зависят.