diff --git a/extensions/bootstrap/composer.json b/extensions/bootstrap/composer.json index 8b717c846f..ba3a3263ad 100644 --- a/extensions/bootstrap/composer.json +++ b/extensions/bootstrap/composer.json @@ -1,29 +1,29 @@ { - "name": "yiisoft/yii2-bootstrap", - "description": "The Twitter Bootstrap extension for the Yii framework", - "keywords": ["yii2", "bootstrap"], - "type": "yii2-extension", - "license": "BSD-3-Clause", - "support": { - "issues": "https://github.com/yiisoft/yii2/issues?labels=ext%3Abootstrap", - "forum": "http://www.yiiframework.com/forum/", - "wiki": "http://www.yiiframework.com/wiki/", - "irc": "irc://irc.freenode.net/yii", - "source": "https://github.com/yiisoft/yii2" - }, - "authors": [ - { - "name": "Qiang Xue", - "email": "qiang.xue@gmail.com" - } - ], - "require": { - "yiisoft/yii2": "*", - "twbs/bootstrap": "3.2.* | 3.1.* | 3.0.*" - }, - "autoload": { - "psr-4": { - "yii\\bootstrap\\": "" - } - } + "name": "yiisoft/yii2-bootstrap", + "description": "The Twitter Bootstrap extension for the Yii framework", + "keywords": ["yii2", "bootstrap"], + "type": "yii2-extension", + "license": "BSD-3-Clause", + "support": { + "issues": "https://github.com/yiisoft/yii2/issues?labels=ext%3Abootstrap", + "forum": "http://www.yiiframework.com/forum/", + "wiki": "http://www.yiiframework.com/wiki/", + "irc": "irc://irc.freenode.net/yii", + "source": "https://github.com/yiisoft/yii2" + }, + "authors": [ + { + "name": "Qiang Xue", + "email": "qiang.xue@gmail.com" + } + ], + "require": { + "yiisoft/yii2": "*", + "twbs/bootstrap": "3.2.* | 3.1.* | 3.0.*" + }, + "autoload": { + "psr-4": { + "yii\\bootstrap\\": "" + } + } } diff --git a/framework/web/AssetBundle.php b/framework/web/AssetBundle.php index eb2bea9e0e..b37ed8ea1a 100644 --- a/framework/web/AssetBundle.php +++ b/framework/web/AssetBundle.php @@ -29,8 +29,8 @@ class AssetBundle extends Object * @var string the directory that contains the asset files in this bundle. * * 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. + * to form an absolute file path. If this property is null (meaning not set), it will be filled with the value of + * [[AssetManager::basePath]] when the bundle is being loaded by [[AssetManager::getBundle()]]. * * You can use either a directory or an alias of the directory. */ @@ -40,7 +40,8 @@ class AssetBundle extends Object * * 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. + * If this property is null (meaning not set), it will be filled with the value of + * [[AssetManager::baseUrl]] when the bundle is being loaded by [[AssetManager::getBundle()]]. * * You can use either a URL or an alias of the URL. */ @@ -59,17 +60,22 @@ 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]] and [[baseUrl]], - * or a URL representing an external JavaScript file. + * @var array list of JavaScript files that this bundle contains. Each JavaScript file can be + * specified in one of the following formats: * - * Note that only forward slash "/" can be used as directory separators. + * - an absolute URL representing an external asset. For example, + * `//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js` or + * `http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js`. + * - a path relative to [[basePath]] and [[baseUrl]]: for example, `js/main.js`. There should be no leading slash. + * - a path relative to [[AssetManager::basePath]] and [[AssetManager::baseUrl]]: for example, + * `@/jquery/dist/jquery.js`. The path must begin with `@/`. + * + * Note that only forward slash "/" should 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]] and [[baseUrl]], - * or a URL representing an external CSS file. + * @var array list of CSS files that this bundle contains. Each CSS file can be specified + * in one of the three formats as explained in [[js]]. * * Note that only forward slash "/" can be used as directory separator. */ diff --git a/framework/web/AssetManager.php b/framework/web/AssetManager.php index 84b4786863..225a1dba05 100644 --- a/framework/web/AssetManager.php +++ b/framework/web/AssetManager.php @@ -10,31 +10,24 @@ namespace yii\web; use Yii; use yii\base\Component; use yii\base\InvalidConfigException; -use yii\base\InvalidParamException; -use yii\helpers\FileHelper; use yii\helpers\Url; /** - * AssetManager manages asset bundles and asset publishing. + * AssetManager manages asset bundle configuration and loading. * * AssetManager is configured as an application component in [[\yii\web\Application]] by default. * You can access that instance via `Yii::$app->assetManager`. * * You can modify its configuration by adding an array to your application config under `components` - * as it is shown in the following example: + * as shown in the following example: * - * ~~~ + * ```php * 'assetManager' => [ * 'bundles' => [ * // you can override AssetBundle configs here * ], - * //'linkAssets' => true, - * // ... * ] - * ~~~ - * - * @property AssetConverterInterface $converter The asset converter. Note that the type of this property - * differs in getter and setter. See [[getConverter()]] and [[setConverter()]] for details. + * ``` * * @author Qiang Xue * @since 2.0 @@ -42,10 +35,19 @@ use yii\helpers\Url; class AssetManager extends Component { /** - * @var array list of available asset bundles. The keys are the class names (**without leading backslash**) - * of the asset bundles, and the values are either the configuration arrays for creating the [[AssetBundle]] - * objects or the corresponding asset bundle instances. For example, the following code disables - * the bootstrap css file used by Bootstrap widgets (because you want to use your own styles): + * @var array|boolean list of asset bundle configurations. This property is provided to customize asset bundles. + * When a bundle is being loaded by [[getBundle()]], if it has a corresponding configuration specified here, + * the configuration will be applied to the bundle. + * + * The array keys are the asset bundle names, which typically are asset bundle class names without leading backslash. + * The array values are the corresponding configurations. If a value is false, it means the corresponding asset + * bundle is disabled and [[getBundle()]] should return null. + * + * If this this property is false, it means the whole asset bundle feature is disabled and [[getBundle()]] + * will always return null. + * + * The following example shows how to disable the bootstrap css file used by Bootstrap widgets + * (because you want to use your own styles): * * ~~~ * [ @@ -64,8 +66,25 @@ class AssetManager extends Component * @return string the base URL through which the published asset files can be accessed. */ public $baseUrl = '@web/assets'; + /** + * @var array mapping from source asset files (keys) to target asset files (values). + * When an asset bundle is being loaded by [[getBundle()]], each of its asset files (listed in either + * [[AssetBundle::css]] or [[AssetBundle::js]] will be examined to see if it matches any key + * in this map. If so, the corresponding value will be used to replace the asset file. + * + * Note that the target asset files should be either absolute URLs or paths relative to [[baseUrl]] and [[basePath]]. + * + * In the following example, any occurrence of `jquery.min.js` will be replaced with `jquery/dist/jquery.js`. + * + * ```php + * [ + * 'jquery.min.js' => 'jquery/dist/jquery.js', + * ] + * ``` + */ public $assetMap = []; + /** * Initializes the component. * @throws InvalidConfigException if [[basePath]] is invalid @@ -140,12 +159,33 @@ class AssetManager extends Component protected function getAssetUrl($bundle, $file) { + if (($mappedFile = $this->mapAsset($file)) !== false) { + return Url::isRelative($mappedFile) ? $this->baseUrl . '/' . $mappedFile : $mappedFile; + } + if (strncmp($file, '@/', 2) === 0) { $file = $this->baseUrl . substr($file, 1); } elseif (Url::isRelative($file)) { $file = $bundle->baseUrl . '/' . $file; } - // todo: assetMap + return $file; } + + protected function mapAsset($file) + { + if (isset($this->assetMap[$file])) { + return $this->assetMap[$file]; + } + + $n = strlen($file); + foreach ($this->assetMap as $from => $to) { + $n2 = strlen($from); + if ($n2 <= $n && substr_compare($file, $from, $n - $n2, $n2) === 0) { + return $to; + } + } + + return false; + } }