The resources in Yii are files related to Web pages, CSS files, javascript files, pictures, videos, and so on, and resources are placed in the Web accessible directory and are directly invoked by the Web server.
It's better to manage resources by program automatically, for example, when you use the Yii\jui\datepicker widget on a page, it automatically contains the CSS and JavaScript files you need, rather than asking you to manually find these files and include, when you upgrade widgets, It will automatically use the new version of the resource file, and in this tutorial we will detail the powerful resource management features that YII provides.
Resource Bundles
Yii manages resources in a resource bundle, which is simply a collection of resources placed in a directory, and when a resource bundle is registered in the view, the CSS and JavaScript files in the package are included when the Web page is rendered.
Defining a resource bundle
The resource bundle is designated as the PHP class that inherits Yii\web\assetbundle, the package name is an automatically loaded PHP class name, and in the resource bundle class, you specify the location of the resource, which CSS and JavaScript files are included, and dependencies on other packages.
The following code defines the primary resource bundle used by the underlying application template:
<?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 ',
];
}
If the Appasset class specifies that the resource file is placed in the @webroot directory, the corresponding URL is @web, the resource bundle contains a CSS file Css/site.css, no JavaScript file, relies on the other two packages Yii\web\yiiasset and Yii\bootstrap\bootstrapasset, the properties of Yii\web\assetbundle are described in more detail as follows:
- Yii\web\assetbundle::sourcepath: Specifies that the package contains the root directory of the resource file and that the property should be set when the root directory cannot be accessed by the Web, otherwise set the Yii\web\assetbundle::basepath property and Yii\ Web\assetbundle::baseurl. Path aliases can be used here;
- Yii\web\assetbundle::basepath: Specifies the directory that contains the resource files in the resource bundle and Web Access, when you specify the Yii\web\assetbundle::sourcepath property, the resource Manager Will publish the package's resources to a Web access and overwrite the attribute, and if your resource file is in a Web accessible directory, you should set this property so that you don't have to publish it again. The path alias can be used here.
Yii\web\assetbundle::baseurl: Specifies the URL corresponding to the Yii\web\assetbundle::basepath directory, similar to Yii\web\assetbundle::basepath, if you specify Yii\web\assetbundle::sourcepath property, the resource Manager publishes these resources and overrides the attribute, where the path alias can be used.
YII\WEB\ASSETBUNDLE::JS: An array of JavaScript files containing the resource bundle, note that the forward slash "/" should be a directory separator, and each JavaScript file can be specified as one of the following two formats:
- The relative path is represented as a local JavaScript file (such as Js/main.js), the actual path of the file is preceded by the Yii\web\assetmanager::basepath, and the actual URL of the file is preceded by the path yii\web\ Assetmanager::baseurl.
- An absolute URL address is represented as an external JavaScript file, such as http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js or// Ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js.
- YII\WEB\ASSETBUNDLE::CSS: An array containing the JavaScript file for the resource bundle, which is the same format as YII\WEB\ASSETBUNDLE::JS.
- Yii\web\assetbundle::d epends: An additional resource bundle that lists the resource bundle dependencies (described in more detail in the last two sections).
- Yii\web\assetbundle::jsoptions: Specifies the option to pass to this method when Yii\web\view::registerjsfile () is called to register the package for each JavaScript file.
- Yii\web\assetbundle::cssoptions: Specifies the option to pass to this method when Yii\web\view::registercssfile () registers the package for each CSS file.
- Yii\web\assetbundle::p ublishoptions: When calling Yii\web\assetmanager::p ublish () to publish the package resource file to the Web directory, specify the option to pass to the method, only if you specify the Yii\web\ Used when Assetbundle::sourcepath properties.
Resource Location
The resources can be divided according to their location:
SOURCE resources: Resource files and PHP source code together, cannot be directly accessed by the Web, in order to use these source resources, they are copied to a Web-accessible web directory to become published resources, this process is called publishing resources, and then detailed.
Publishing resources: Resource files are placed in a web directory that can be accessed directly from the web;
External resources: A resource file is placed on a Web server that is different from your Web application;
When you define a resource bundle class, if you specify the Yii\web\assetbundle::sourcepath attribute, any resource that uses a relative path is treated as a source resource, and if this attribute is not specified, the resource is a publishing resource (and therefore should be specified yii\web\ Assetbundle::basepath and Yii\web\assetbundle::baseurl let Yii know where they are.
It is recommended that you place resource files in the Web directory to avoid unnecessary publishing of resource processes, which is the previous example of specifying Yii\web\assetbundle::basepath instead of Yii\web\assetbundle::sourcepath.
For extensions, the Yii\web\assetbundle::sourcepath attribute must be specified when defining a resource bundle class because both their resources and source code are in directories that cannot be accessed by the Web.
Note: Do not use @webroot/assets for the Yii\web\assetbundle::sourcepath property, which defaults to the Yii\web\assetmanager Resource Manager's path to storing resources after publishing the source resource. All content of the path is considered a temporary file and may be deleted.
Resource Dependencies
When a Web page contains multiple CSS or JavaScript files, they have a certain order of precedence to avoid attribute overrides, for example, the Web page must ensure that the jquery JavaScript file is already included before using the jquery UI widget. We refer to this resource prioritization as resource dependency.
Resource dependencies are specified primarily through the Yii\web\assetbundle::d Epends property, and in the Appasset example, the resource bundle relies on two other resource bundles: Yii\web\yiiasset and Yii\bootstrap\ Bootstrapasset the CSS and JavaScript files for the resource bundle will not be included until these two dependent package files are included.
Resource dependencies are transitive, which means that a person says a relies on b,b C, then a also relies on C.
Resource Options
You can specify yii\web\assetbundle::cssoptions and Yii\web\assetbundle::jsoptions properties to customize how the page contains CSS and JavaScript files, which are passed to the yii\ Web\view::registercssfile () and Yii\web\view::registerjsfile () methods, when the view calls these methods to contain CSS and JavaScript files.
Note: The options set in the resource bundle class are applied to each Css/javascript file in the package, and if you want to use different options for each file, create a different resource bundle and use an option set in each package.
For example, if you only want IE9 or higher browsers to include a CSS file, you can use the following options:
Public $cssOptions = [' Condition ' => ' LTE IE9 '];
This will be the CSS file in the package that is included with the following HTML tags:
<!--[If LTE ie9]>
<link rel= "stylesheet" href= "Path/to/foo.css" >
<![ Endif]-->
The link label contains <noscript> can use the following code:
Public $cssOptions = [' NoScript ' => true];
To include the JavaScript file in the page Head area (the JavaScript file defaults to the end of the body), use the following options:
Public $jsOptions = [' Position ' => \yii\web\view::P Os_head];
Bower and NPM Resources
Most JAVASCRIPT/CSS packages are managed through bower and/or NPM, and if your application or extension uses these packages, it is recommended that you follow these steps to manage the resources in the library:
Modify the applied or extended Composer.json file to include the package in require, use Bower-asset/packagename (Bower package) or Npm-asset/packagename (NPM package) to correspond to the library.
Create a resource bundle class and include the Javascript/css file you want to use for your application or extension into the class, set the Yii\web\assetbundle::sourcepath property to @bower/packagename or @npm/ PackageName, because Bower or NPM packages are installed to the corresponding directories according to the alias composer.
Note: Some packages place their distributed files in a subdirectory, in which case a subdirectory should be specified as the Yii\web\assetbundle::sourcepath property value, for example, Yii\web\jqueryasset use @bower/ Jquery/dist rather than @bower/jquery.
Using Resource bundles
To use a resource bundle, call the Yii\web\assetbundle::register () method in the view to register the resource first, for example, in a view template to register a resource bundle with the following code:
Use App\assets\appasset;
Appasset::register ($this); $this represents a View object
If you register a resource bundle elsewhere, you should provide a view object, such as registering a resource bundle in the Widget class, and you can get the View object by $this->view.
When you register a resource bundle in a view, in the back, Yii registers the resource bundles on which it relies, and if the resource bundle is placed in a directory that is inaccessible to the Web, it is published to an accessible directory, which, when rendered by the view, generates the CSS and JavaScript files that are contained in these registry packages < Link> and <script> tags, the order of these labels depends on the resource bundle dependencies and the order of the YII\WEB\ASSETBUNDLE::CSS and Yii\web\assetbundle::js columns.
Custom Resource Bundles
Yii implements [[Yii\web\assetmanager] to manage application components through an application component named Assetmanager, which enables you to customize the behavior of the resource bundle by configuring the Yii\web\assetmanager::bundles property, for example, The Yii\web\jqueryasset resource bundle uses jquery.js files from the jquery Bower package by default, and you may need to obtain jquery files from the Google server to improve availability and performance. You can configure Assetmanager in the application configuration, as follows:
return [
//...
] Components ' => ['
assetmanager ' => [' bundles ' => [' Yii\web\jqueryasset ' =>] ['
SourcePath ' => null,//must not publish the resource
' JS ' => [
'//AJAX.GOOGLEAPIS.COM/AJAX/LIBS/JQUERY/2.1.1/ Jquery.min.js ',
]
], []
,
]
,]
,];
Multiple resource bundles can be configured through a similar yii\web\assetmanager::bundles, and the array's key should be the resource bundle's class name (without the backslash), and the array's value will be the corresponding configuration array.
Tip: You can determine which resource to use based on criteria, as shown in the following example for how to use jquery.js in the development environment, otherwise use jquery.min.js:
' Yii\web\jqueryasset ' => [
' JS ' =>] [
yii_env_dev? ' Jquery.js ': ' Jquery.min.js '
]
,
You can set the resource bundle name to False to disable one or more resource bundles that you want to disable, and when you register a disabled resource bundle in the view, the view does not contain any resources for the package and does not register the packages on which it relies, for example, to disable Yii\web\jqueryasset, you can use the following configuration:
return [
//...
] Components ' => ['
assetmanager ' => ['
bundles ' =>] [' Yii\web\jqueryasset ' =>
false,
],
],
],
];
You can set the Yii\web\assetmanager::bundles to False to disable all resource bundles.
Resource deployment
Sometimes you want to "fix" the error/incompatibility of resource files in multiple resource bundles, such as package a using the 1.11.1 version of Jquery.min.js, Package B uses the 2.1.1 version of Jquery.js to customize each package to solve the problem by using the resource deployment feature to deploy an incorrect resource as desired, and for this, configure the Yii\web\assetmanager::assetmap property as follows:
return [
//...
] Components ' => [' Assetmanager ' => [' Assetmap ' => [' jquery.js ' => ']//ajax.googleapis.com/
Ajax/libs/jquery/2.1.1/jquery.min.js ',
],
],]
;
Yii\web\assetmanager::assetmap's key is the resource name you want to fix, the value you want to use for the resource path, when the view registers the resource bundle, in Yii\web\assetbundle::css and Yii\web\assetbundle :: JS array and each related resource file will be compared to the deployment, if any of the array keys compared to the resource file's last filename (if there is a prefix of yii\web\assetbundle::sourcepath), the corresponding value is to replace the original resource. For example, the resource file My/path/to/jquery.js match key jquery.js.
Note: Only the resources specified relative to the relative path correspond to the resource deployment, and the alternate resource path can be either an absolute path or a yii\web\assetmanager::basepath-related path.
Resource Publishing
As mentioned earlier, if a resource bundle is placed in a directory that is inaccessible to the Web, the resource is copied to a Web accessible directory when the view registers the resource, a process called a resource publication that Yii\web\assetmanager automatically processes.
Resources are published to the @webroot/assets directory by default, and the corresponding URL is @web/assets, configurable Yii\web\assetmanager::basepath and Yii\web\assetmanager::baseurl property to customize the publish location.
In addition to copying files to publish resources, if the operating system and Web server allow symbolic links to be used, this feature can be enabled by setting Yii\web\assetmanager::linkassets to True.
return [
//...
] Components ' => ['
assetmanager ' => [
' linkassets ' => true,
],
],]
;
Using the above configuration, the resource Manager creates a symbol link to the resource bundle source path to be published, which is faster than copying the file and ensures that the published resource is always up to date.
Common resource Bundles
The YII framework defines many resource bundles, the following resource bundles are most commonly used and can be referenced in your application or extension code.
- Yii\web\yiiasset: Consists primarily of yii.js files that complete the organization of module JavaScript code and also provide special support and other useful features for the Data-method and Data-confirm properties.
- Yii\web\jqueryasset: Contains jquery.js files from the jquery bower package.
- Yii\bootstrap\bootstrapasset: Contains CSS files from the Twitter bootstrap framework.
- Yii\bootstrap\bootstrappluginasset: Contains JavaScript files from the Twitter bootstrap framework to support Bootstrap JavaScript plug-ins.
- Yii\jui\juiasset: Contains CSS and JavaScript files from the jquery UI library.
If your code requires jquery, jquery UI, or Bootstrap, you should try to use these predefined resource bundles instead of creating them yourself, and if the default configuration of these packages does not meet your needs, you can customize the configuration and refer to the custom resource bundle for details.
Resource Conversion
In addition to writing CSS and/or Javascript code directly, developers often use extended syntax to write, and then use special tools to convert them to css/javascript. For example, you can use less or scss for CSS code, and typescript for JavaScript.
Resource files that use the extended syntax can be listed in the YII\WEB\ASSETBUNDLE::CSS and Yii\web\assetbundle::js of the resource bundle, as follows:
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 ',
];
}
When you register one of these resource bundles in the view, the Yii\web\assetmanager Resource Manager automatically runs the preprocessing tool to convert resources using the extended syntax to Css/javascript, which is included in the page when the view eventually renders the page css/ Javascipt file, rather than the original extended syntax code file.
Yii uses the file name extension to indicate which extended syntax is used by the resource, and the following syntax and file name extensions are recognized by default:
- Less:. Less
- SCSS:. scss
- Stylus:. Styl
- Coffeescript:. Coffee
- Typescript:. ts
Yii relies on the installed preprocessing tools to transform resources, for example, to install the LESSC preprocessing command for use with less.
You can configure Yii\web\assetmanager::converter custom preprocessing commands and supported extension syntax as follows:
return ['
components ' => [' Assetmanager ' => ['
Converter ' =>] ['
class ' => ' Yii\web\ Assetconverter ',
' commands ' => [
' less ' => [' css ', ' LESSC {from} {to}--no-color '],
' ts ' => [' js ', ' TSC--out {to} {from} '],],],],]
;
As shown above, the supported extension syntax is specified through the Yii\web\assetconverter::commands property, and the array's key is the file name extension (not preceded by), the value of the array is the target resource file name extension and the command that performs the resource conversion, and the tags in the command {from} and {to will be replaced by the source resource file path and the destination resource file path, respectively.
Add: In addition to the above, there are other ways to handle extended syntax resources, for example, you can use the compilation tools such as grunt to monitor and automatically convert extended syntax resources, at which point you should use the compiled Css/javascript file in the resource bundle instead of the original file.
merging and compressing resources
A Web page can contain many CSS and/or JavaScript files, and the usual way to reduce HTTP requests and the size of these downloads is to merge and compress multiple Css/javascript files into one or fewer files on the page, and use the compressed file instead of the original file.
Add: Merging and compressing resources is usually used in the product online mode, in the development mode using the original Css/javascript more convenient debugging.
Next, you'll introduce a way to merge and compress resource files without having to modify existing code:
Find all the resource bundles in your application that you want to merge and compress,
Divide the packages into one or several groups, noting that each package can belong to only one of the groups,
Merge/compress CSS files into one file in each group, and process JavaScript files in the same way
Define a new resource bundle for each group:
Set the Yii\web\assetbundle::css and Yii\web\assetbundle::js properties as compressed CSS and JavaScript files respectively;
Customize the resource bundles within each group, set the Yii\web\assetbundle::css and Yii\web\assetbundle::js properties of the resource bundle to NULL, and set their yii\web\assetbundle::d epends property to a newly created resource bundle for each group.
In this way, when you register a resource bundle in a view, the registration of the group Resource bundle to which the original package belongs is automatically triggered, and then the page contains the resource file that is merged/compressed instead of the original file.
Example
Use an example to explain this approach:
Identify your application with two pages x and Y, page x using resource bundles a,b and C, page Y using resource bundles b,c and D.
There are two ways to divide these resource bundles, one is to include all the resource bundles in one group, the other is to put (A,B,C) in Group X, (b,c,c) in group Y, which is better? The first advantage is that two pages use the same merged CSS and JavaScript files to make the HTTP cache more efficient, on the other hand, because a single group contains all the files, the merged CSS and Javascipt files will be larger, thus increasing the file transfer time, in this example, We use the first method, which is to include all the packages in a group.
Add: Grouping resource bundles is not worthless, it usually requires analyzing the amount of data from various resources on different pages in the real world, starting with a simple group.
Use tools in all packages (such as Closure Compiler, YUI compressor) to merge and compress CSS and JavaScript files, and note that the merged files meet the dependencies between the packets, for example, if package a relies on b,b dependencies C and D, Then the list of resource files starts with C and D, then B and finally a.
After merging and compacting, you get a CSS file and a JavaScript file, assuming they are named All-xyz.css and All-xyz.js, and XYZ is the timestamp or hash value that makes the file name unique to avoid HTTP cache problems.
Now to the last step, configure the Yii\web\assetmanager Explorer in the application configuration as follows:
return ['
components ' => [' Assetmanager ' => ['
bundles ' =>] [
' All ' => ['
class ' => ' Y Ii\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 ']],
],
],
],
];
As described in the custom resource bundles section, configuration changes the default behavior of each package, especially if packages A, B, C, and D no longer contain any resource files, relying on the package all containing the merged all-xyz.css and all-xyz.js files, Page x contains the two merged files instead of the original files for package A, B, and C, as is the case for page y.
Finally, there is a way to better deal with the above method, in addition to directly modify the application configuration file, you can put the custom package array into a file, in the application configuration according to the criteria include the file, for example:
return [
' components ' => ['
assetmanager ' => ['
bundles ' =>] require (__dir__. '/' . (Yii_env_prod?) ' assets-prod.php ': ' assets-dev.php ')),],],]
;
As shown above, the resource bundle array is stored in the assets-prod.php file in the product online mode, not the product online mode stored in the assets-dev.php file.
Using the Asset command
Yii provides a command called the asset console to automate the operation.
To use this command, you should first create a profile to set which resource packages to merge and how to group, you can use the ASSET/TEMPLATE subcommand to generate a template, and then modify the template to what you want.
Yii asset/template assets.php
This command generates a file named assets.php in the current directory, and the contents of the file are similar to the following:
<?php
/**
* configuration file for console command "Yii asset"
* Note in the console environment, some path aliases such as ' @webroot ' and ' @web ' do not exist
* Please define a path alias that does not exist
*
/return [
//For JavaScript file compression modify Command/callback '
jscompressor ' => ' Java-jar compiler.jar--js { From}--js_output_file {to} ',
//For CSS file compression modify Command/callback
' csscompressor ' => ' Java-jar Yuicompressor.jar--type css {from}-o {to} ',
//List of resource bundles to compress
' bundles ' => [/
/' Yii\web\yiiasset ',
//' Yii\web\jqueryasset ',
],
//resource Bundle Compressed output
' targets ' => [' All
' => ['
class ' = > ' Yii\web\assetbundle ',
' basepath ' => ' @webroot/assets ',
' BaseURL ' => ' @web/assets ',
' js ' = > ' js/all-{hash}.js ',
' css ' => ' css/all-{hash}.css ',
],
],
//Resource Manager configuration:
' Assetmanager ' => [
],
];
You should modify the bundles option of the file to specify which packages you want to merge, and in the targets option you should specify how these packages are grouped, as described above to specify one or more groups.
Note: Because aliases are applied to the console @webroot and @web are not available, they should be specified explicitly in the configuration.
JavaScript files are merged and compressed and written to the Js/all-{hash}.js file, where {hash} is replaced by the hash value of the resulting file.
The Jscompressor and Csscompressor options specify console commands or PHP callback functions to perform JavaScript and CSS merging and compression, and Yii defaults to using closure compiler to merge JavaScript files, using Yui Compressor to merge CSS files, you should manually install these tools or modify the options to use the tools you like.
Depending on the configuration file, you can execute the asset command to merge and compress the resource files and generate a new resource bundle profile assets-prod.php:
Yii Asset assets.php config/assets-prod.php