Commit f51a2635 by Qiang Xue

new asset management WIP

parent 280c2ca0
{
"directory" : "web/assets"
}
\ No newline at end of file
{
"name": "yii2-basic",
"version": "1.0.0",
"dependencies": {
},
"devDependencies": {
}
}
......@@ -30,7 +30,7 @@ instead of adding a new one. If you don't provide it, the JS code itself will be
An external script can be added like the following:
```php
$this->registerJsFile('http://example.com/js/main.js', [JqueryAsset::className()]);
$this->registerJsFile('http://example.com/js/main.js', ['depends' => [JqueryAsset::className()]]);
```
The arguments for [[yii\web\View::registerJsFile()|registerJsFile()]] are similar to those for
......@@ -76,16 +76,19 @@ If you want to specify additional properties of the style tag, pass an array of
If you need to make sure there's only a single style tag use fourth argument as was mentioned in meta tags description.
```php
$this->registerCssFile("http://example.com/css/themes/black-and-white.css", [BootstrapAsset::className()], ['media' => 'print'], 'css-print-theme');
$this->registerCssFile("http://example.com/css/themes/black-and-white.css", [
'depends' => [BootstrapAsset::className()],
'media' => 'print',
], 'css-print-theme');
```
The code above will add a link to CSS file to the head section of the page.
* The first argument specifies the CSS file to be registered.
* The second argument specifies that this CSS file depends on [[yii\bootstrap\BootstrapAsset|BootstrapAsset]], meaning it will be added
AFTER the CSS files in [[yii\bootstrap\BootstrapAsset|BootstrapAsset]]. Without this dependency specification, the relative order
between this CSS file and the [[yii\bootstrap\BootstrapAsset|BootstrapAsset]] CSS files would be undefined.
* The third argument specifies the attributes for the resulting `<link>` tag.
* The second argument specifies the HTML attributes for the resulting `<link>` tag. The option `depends`
is specially handled. It specifies which asset bundles this CSS file depends on. In this case, the dependent
asset bundle is [[yii\bootstrap\BootstrapAsset|BootstrapAsset]]. This means the CSS file will be added
*after* the CSS files in [[yii\bootstrap\BootstrapAsset|BootstrapAsset]].
* The last argument specifies an ID identifying this CSS file. If it is not provided, the URL of the CSS file will be
used instead.
......
......@@ -76,7 +76,7 @@ class can be placed anywhere but the convention for it is to be under `assets` d
Additionally you may specify `$jsOptions`, `$cssOptions` and `$publishOptions` that will be passed to
[[yii\web\View::registerJsFile()]], [[yii\web\View::registerCssFile()]] and [[yii\web\AssetManager::publish()]]
respectively during registering and publising an asset. For more details on this see [Setting special options](#setting-special-options).
respectively during registering and publishing an asset. For more details on this see [Setting special options](#setting-special-options).
[alias]: basics.md#path-aliases "Yii Path alias"
......@@ -89,16 +89,16 @@ following way:
```php
class LanguageAsset extends AssetBundle
{
public $language;
public static $language;
public $sourcePath = '@app/assets/language';
public $js = [
];
public function registerAssetFiles($view)
public function init()
{
$language = $this->language ? $this->language : Yii::$app->language;
parent::init();
$language = self::$language ? self::$language : Yii::$app->language;
$this->js[] = 'language-' . $language . '.js';
parent::registerAssetFiles($view);
}
}
```
......@@ -106,7 +106,8 @@ class LanguageAsset extends AssetBundle
In order to set language use the following code when registering an asset bundle in a view:
```php
LanguageAsset::register($this)->language = $language;
LanguageAsset::$language = $language;
LanguageAsset::register($this);
```
......
......@@ -319,11 +319,10 @@ PHP;
$url = ArrayHelper::remove($params, 'url');
$key = ArrayHelper::remove($params, 'key', null);
$depends = ArrayHelper::remove($params, 'depends', null);
if (isset($params['position']))
$params['position'] = $this->getViewConstVal($params['position'], View::POS_END);
Yii::$app->getView()->registerJsFile($url, $depends, $params, $key);
Yii::$app->getView()->registerJsFile($url, $params, $key);
}
/**
......@@ -379,9 +378,8 @@ PHP;
$url = ArrayHelper::remove($params, 'url');
$key = ArrayHelper::remove($params, 'key', null);
$depends = ArrayHelper::remove($params, 'depends', null);
Yii::$app->getView()->registerCssFile($url, $depends, $params, $key);
Yii::$app->getView()->registerCssFile($url, $params, $key);
}
/**
......
......@@ -319,4 +319,15 @@ class BaseUrl
return $url;
}
/**
* Returns a value indicating whether a URL is relative.
* A relative URL does not have host info part.
* @param string $url the URL to be checked
* @return boolean whether the URL is relative
*/
public static function isRelative($url)
{
return strncmp($url, '//', 2) && strpos($url, '://') === false;
}
}
......@@ -26,41 +26,21 @@ use yii\base\Object;
class AssetBundle extends Object
{
/**
* @var string the root directory of the source asset files. A source asset file
* is a file that is part of your source code repository of your Web application.
* @var string the directory that contains the asset files in this bundle.
*
* You must set this property if the directory containing the source asset files
* is not Web accessible (this is usually the case for extensions).
*
* By setting this property, the asset manager will publish the source asset files
* to a Web-accessible directory [[basePath]].
*
* You can use either a directory or an alias of the directory.
*/
public $sourcePath;
/**
* @var string the Web-accessible directory that contains the asset files in this bundle.
*
* If [[sourcePath]] is set, this property will be *overwritten* by [[AssetManager]]
* when it publishes the asset files from [[sourcePath]].
*
* If the bundle contains any assets that are specified in terms of relative file path,
* then this property must be set either manually or automatically (by [[AssetManager]] via
* asset publishing).
* The value of this property can be prefixed to every relative asset file path listed in [[js]] and [[css]]
* to form an absolute file path. If this property is null (meaning not set), the value of
* [[AssetManager::basePath]] will be used instead.
*
* You can use either a directory or an alias of the directory.
*/
public $basePath;
/**
* @var string the base URL that will be prefixed to the asset files for them to
* be accessed via Web server.
* @var string the base URL for the relative asset files listed in [[js]] and [[css]].
*
* If [[sourcePath]] is set, this property will be *overwritten* by [[AssetManager]]
* when it publishes the asset files from [[sourcePath]].
*
* If the bundle contains any assets that are specified in terms of relative file path,
* then this property must be set either manually or automatically (by asset manager via
* asset publishing).
* The value of this property will be prefixed to every relative asset file path listed in [[js]] and [[css]]
* when they are being registered in a view so that they can be Web accessible.
* If this property is null (meaning not set), the value of [[AssetManager::baseUrl]] will be used instead.
*
* You can use either a URL or an alias of the URL.
*/
......@@ -80,16 +60,16 @@ class AssetBundle extends Object
public $depends = [];
/**
* @var array list of JavaScript files that this bundle contains. Each JavaScript file can
* be either a file path (without leading slash) relative to [[basePath]] or a URL representing
* an external JavaScript file.
* be either a file path (without leading slash) relative to [[basePath]] and [[baseUrl]],
* or a URL representing an external JavaScript file.
*
* Note that only forward slash "/" can be used as directory separator.
* Note that only forward slash "/" can be used as directory separators.
*/
public $js = [];
/**
* @var array list of CSS files that this bundle contains. Each CSS file can
* be either a file path (without leading slash) relative to [[basePath]] or a URL representing
* an external CSS file.
* be either a file path (without leading slash) relative to [[basePath]] and [[baseUrl]],
* or a URL representing an external CSS file.
*
* Note that only forward slash "/" can be used as directory separator.
*/
......@@ -104,15 +84,11 @@ class AssetBundle extends Object
* when registering the CSS files in this bundle.
*/
public $cssOptions = [];
/**
* @var array the options to be passed to [[AssetManager::publish()]] when the asset bundle
* is being published.
*/
public $publishOptions = [];
/**
* @param View $view
* Registers this asset bundle with a view.
* @param View $view the view to be registered with
* @return static the registered asset bundle instance
*/
public static function register($view)
......@@ -126,9 +102,6 @@ class AssetBundle extends Object
*/
public function init()
{
if ($this->sourcePath !== null) {
$this->sourcePath = rtrim(Yii::getAlias($this->sourcePath), '/\\');
}
if ($this->basePath !== null) {
$this->basePath = rtrim(Yii::getAlias($this->basePath), '/\\');
}
......@@ -136,58 +109,4 @@ class AssetBundle extends Object
$this->baseUrl = rtrim(Yii::getAlias($this->baseUrl), '/');
}
}
/**
* Registers the CSS and JS files with the given view.
* @param \yii\web\View $view the view that the asset files are to be registered with.
*/
public function registerAssetFiles($view)
{
foreach ($this->js as $js) {
if ($js[0] !== '/' && $js[0] !== '.' && strpos($js, '://') === false) {
$view->registerJsFile($this->baseUrl . '/' . $js, [], $this->jsOptions);
} else {
$view->registerJsFile($js, [], $this->jsOptions);
}
}
foreach ($this->css as $css) {
if ($css[0] !== '/' && $css[0] !== '.' && strpos($css, '://') === false) {
$view->registerCssFile($this->baseUrl . '/' . $css, [], $this->cssOptions);
} else {
$view->registerCssFile($css, [], $this->cssOptions);
}
}
}
/**
* Publishes the asset bundle if its source code is not under Web-accessible directory.
* It will also try to convert non-CSS or JS files (e.g. LESS, Sass) into the corresponding
* CSS or JS files using [[AssetManager::converter|asset converter]].
* @param AssetManager $am the asset manager to perform the asset publishing
*/
public function publish($am)
{
if ($this->sourcePath !== null && !isset($this->basePath, $this->baseUrl)) {
list ($this->basePath, $this->baseUrl) = $am->publish($this->sourcePath, $this->publishOptions);
}
$converter = $am->getConverter();
foreach ($this->js as $i => $js) {
if (strpos($js, '/') !== 0 && strpos($js, '://') === false) {
if (isset($this->basePath, $this->baseUrl)) {
$this->js[$i] = $converter->convert($js, $this->basePath);
} else {
$this->js[$i] = '/' . $js;
}
}
}
foreach ($this->css as $i => $css) {
if (strpos($css, '/') !== 0 && strpos($css, '://') === false) {
if (isset($this->basePath, $this->baseUrl)) {
$this->css[$i] = $converter->convert($css, $this->basePath);
} else {
$this->css[$i] = '/' . $css;
}
}
}
}
}
......@@ -15,8 +15,7 @@ namespace yii\web;
*/
class JqueryAsset extends AssetBundle
{
public $sourcePath = '@vendor/yiisoft/jquery';
public $js = [
'jquery.js',
'jquery/dist/jquery.js',
];
}
......@@ -8,9 +8,9 @@
namespace yii\web;
use Yii;
use yii\helpers\ArrayHelper;
use yii\helpers\Html;
use yii\base\InvalidConfigException;
use yii\helpers\Url;
/**
* View represents a view object in the MVC pattern.
......@@ -261,7 +261,7 @@ class View extends \yii\base\View
foreach ($bundle->depends as $dep) {
$this->registerAssetFiles($dep);
}
$bundle->registerAssetFiles($this);
$this->getAssetManager()->registerAssetFiles($this, $bundle);
}
unset($this->assetBundles[$name]);
}
......@@ -360,23 +360,27 @@ class View extends \yii\base\View
/**
* Registers a CSS file.
* @param string $url the CSS file to be registered.
* @param array $depends the names of the asset bundles that this CSS file depends on
* @param array $options the HTML attributes for the link tag.
* Please refer to [[Html::cssFile()]] for supported options.
* @param array $options the HTML attributes for the link tag. Please refer to [[Html::cssFile()]] for
* the supported options. The following options are specially handled and are not treated as HTML attributes:
*
* - `depends`: array, specifies the names of the asset bundles that this CSS file depends on.
*
* @param string $key the key that identifies the CSS script file. If null, it will use
* $url as the key. If two CSS files are registered with the same key, the latter
* will overwrite the former.
*/
public function registerCssFile($url, $depends = [], $options = [], $key = null)
public function registerCssFile($url, $options = [], $key = null)
{
$url = Yii::getAlias($url);
$key = $key ?: $url;
$depends = ArrayHelper::remove($options, 'depends', []);
if (empty($depends)) {
$this->cssFiles[$key] = Html::cssFile($url, $options);
} else {
$am = $this->getAssetManager();
$am->bundles[$key] = new AssetBundle([
'css' => [Url::to($url)],
$this->getAssetManager()->bundles[$key] = new AssetBundle([
'baseUrl' => '',
'css' => [$url],
'cssOptions' => $options,
'depends' => (array) $depends,
]);
......@@ -414,14 +418,14 @@ class View extends \yii\base\View
/**
* Registers a JS file.
* @param string $url the JS file to be registered.
* @param array $depends the names of the asset bundles that this JS file depends on
* @param array $options the HTML attributes for the script tag. A special option
* named "position" is supported which specifies where the JS script tag should be inserted
* in a page. The possible values of "position" are:
* @param array $options the HTML attributes for the script tag. The following options are specially handled
* and are not treated as HTML attributes:
*
* - [[POS_HEAD]]: in the head section
* - [[POS_BEGIN]]: at the beginning of the body section
* - [[POS_END]]: at the end of the body section. This is the default value.
* - `depends`: array, specifies the names of the asset bundles that this JS file depends on.
* - `position`: specifies where the JS script tag should be inserted in a page. The possible values are:
* * [[POS_HEAD]]: in the head section
* * [[POS_BEGIN]]: at the beginning of the body section
* * [[POS_END]]: at the end of the body section. This is the default value.
*
* Please refer to [[Html::jsFile()]] for other supported options.
*
......@@ -429,18 +433,19 @@ class View extends \yii\base\View
* $url as the key. If two JS files are registered with the same key, the latter
* will overwrite the former.
*/
public function registerJsFile($url, $depends = [], $options = [], $key = null)
public function registerJsFile($url, $options = [], $key = null)
{
$url = Yii::getAlias($url);
$key = $key ?: $url;
$depends = ArrayHelper::remove($options, 'depends', []);
if (empty($depends)) {
$position = isset($options['position']) ? $options['position'] : self::POS_END;
unset($options['position']);
$position = ArrayHelper::remove($options, 'position', self::POS_END);
$this->jsFiles[$position][$key] = Html::jsFile($url, $options);
} else {
$am = $this->getAssetManager();
$am->bundles[$key] = new AssetBundle([
'js' => [Url::to($url)],
$this->getAssetManager()->bundles[$key] = new AssetBundle([
'baseUrl' => '',
'js' => [$url],
'jsOptions' => $options,
'depends' => (array) $depends,
]);
......
......@@ -15,9 +15,8 @@ namespace yii\web;
*/
class YiiAsset extends AssetBundle
{
public $sourcePath = '@yii/assets';
public $js = [
'yii.js',
'yii2/assets/yii.js',
];
public $depends = [
'yii\web\JqueryAsset',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment