Assets
======
An asset in Yii is a file that may be referenced in a Web page. It can be a CSS file, a JavaScript file, an image
or video file, etc. Assets are located in Web-accessible directories and are directly served by Web servers.
It is often preferable to manage assets programmatically. For example, when you use the [[yii\jui\DatePicker]] widget
in a page, it will automatically include the required CSS and JavaScript files, instead of asking you to manually
find these files and include them. And when you upgrade the widget to a new version, it will automatically use
the new version of the asset files. In this tutorial, we will describe the powerful asset management capability
provided in Yii.
## Asset Bundles
Yii manages assets in the unit of *asset bundle*. An asset bundle is simply a collection of assets located
in a directory. When you register an asset bundle in a [view](structure-views.md), it will include the CSS and
JavaScript files in the bundle in the rendered Web page.
## Defining Asset Bundles
Asset bundles are specified as PHP classes extending from [[yii\web\AssetBundle]]. The name of a bundle is simply
its corresponding PHP class name which should be [autoloadable](concept-autoloading.md). In an asset bundle class,
you would typically specify where the assets are located, what CSS and JavaScript files the bundle contains, and
how the bundle depends on other bundles.
The following code defines the main asset bundle used by [the basic application template](start-installation.md):
```php
Assets, based on their location, can be classified as:
* source assets: the asset files are located together with PHP source code which cannot be directly accessed via Web.
In order to use source assets in a page, they should be copied to a Web directory and turned into the so-called
published assets. This process is called *asset publishing* which will be described in detail shortly.
* published assets: the asset files are located in a Web directory and can thus be directly accessed via Web.
* external assets: the asset files are located on a Web server that is different from the one hosting your Web
application.
When defining an asset bundle class, if you specify the [[yii\web\AssetBundle::sourcePath|sourcePath]] property,
it means any assets listed using relative paths will be considered as source assets. If you do not specify this property,
it means those assets are published assets (you should therefore specify [[yii\web\AssetBundle::basePath|basePath]] and
[[yii\web\AssetBundle::baseUrl|baseUrl]] to let Yii know where they are located.)
It is recommended that you place assets belonging to an application in a Web directory to avoid the unnecessary asset
publishing process. This is why `AppAsset` in the prior example specifies [[yii\web\AssetBundle::basePath|basePath]]
instead of [[yii\web\AssetBundle::sourcePath|sourcePath]].
For [extensions](structure-extensions.md), because their assets are located together with their source code
in directories that are not Web accessible, you have to specify the [[yii\web\AssetBundle::sourcePath|sourcePath]]
property when defining asset bundle classes for them.
> Note: Do not use `@webroot/assets` as the [[yii\web\AssetBundle::sourcePath|source path]].
This directory is used by default by the [[yii\web\AssetManager|asset manager]] to save the asset files
published from their source location. Any content in this directory are considered temporarily and may be subject
to removal.
### Asset Dependencies
When you include multiple CSS or JavaScript files in a Web page, they have to follow certain orders to avoid
overriding issues. For example, if you are using a jQuery UI widget in a Web page, you have to make sure
the jQuery JavaScript file is included before the jQuery UI JavaScript file. We call such ordering the dependencies
among assets.
Asset dependencies are mainly specified through the [[yii\web\AssetBundle::depends]] property.
In the `AppAsset` example, the asset bundle depends on two other asset bundles: [[yii\web\YiiAsset]] and
[[yii\bootstrap\BootstrapAsset]], which means the CSS and JavaScript files in `AppAsset` will be included *after*
those files in the two dependent bundles.
Asset dependencies are transitive. This means if bundle A depends on B which depends on C, A will depend on C, too.
### Asset Options
You can specify the [[yii\web\AssetBundle::cssOptions|cssOptions]] and [[yii\web\AssetBundle::jsOptions|jsOptions]]
properties to customize the way that CSS and JavaScript files are included in a page. The values of these properties
will be passed to the [[yii\web\View::registerCssFile()]] and [[yii\web\View::registerJsFile()]] methods, respectively, when
they are called by the [view](structure-views.md) to include CSS and JavaScript files.
> Note: The options you set in a bundle class apply to *every* CSS/JavaScript file in the bundle. If you want to
use different options for different files, you should create separate asset bundles, and use one set of options
in each bundle.
For example, to conditionally include a CSS file for browsers that are IE9 or above, you can use the following option:
```php
public $cssOptions = ['condition' => 'lte IE9'];
```
This will cause a CSS file in the bundle to be included using the following HTML tags:
```html
```
To wrap link tag with `