Commit 2f526521 by Qiang Xue

new asset WIP

parent f6e1d572
{ {
"directory" : "web/assets" "directory" : "assets"
} }
{ {
"name": "yii2-advanced-backend", "name": "yii2-advanced",
"version": "1.0.0", "version": "1.0.0",
"dependencies": { "dependencies": {
}, },
......
...@@ -18,6 +18,9 @@ ...@@ -18,6 +18,9 @@
* 'setCookieValidationKey' => [ * 'setCookieValidationKey' => [
* // list of config files that need to be inserted with automatically generated cookie validation keys * // list of config files that need to be inserted with automatically generated cookie validation keys
* ], * ],
* 'createSymlink' => [
* // list of symlinks to be created. Keys are symlinks, and values are the targets.
* ],
* ], * ],
* ]; * ];
* ``` * ```
...@@ -38,6 +41,10 @@ return [ ...@@ -38,6 +41,10 @@ return [
'backend/config/main-local.php', 'backend/config/main-local.php',
'frontend/config/main-local.php', 'frontend/config/main-local.php',
], ],
'createSymlink' => [
'frontend/web/assets' => 'assets',
'backend/web/assets' => 'assets',
],
], ],
'Production' => [ 'Production' => [
'path' => 'prod', 'path' => 'prod',
...@@ -54,5 +61,9 @@ return [ ...@@ -54,5 +61,9 @@ return [
'backend/config/main-local.php', 'backend/config/main-local.php',
'frontend/config/main-local.php', 'frontend/config/main-local.php',
], ],
'createSymlink' => [
'frontend/web/assets' => 'assets',
'backend/web/assets' => 'assets',
],
], ],
]; ];
{
"directory" : "web/assets"
}
\ No newline at end of file
{
"name": "yii2-advanced-frontend",
"version": "1.0.0",
"dependencies": {
},
"devDependencies": {
}
}
...@@ -193,3 +193,13 @@ function setCookieValidationKey($root, $paths) ...@@ -193,3 +193,13 @@ function setCookieValidationKey($root, $paths)
file_put_contents($file, $content); file_put_contents($file, $content);
} }
} }
function createSymlink($links)
{
foreach ($links as $link => $target) {
echo " symlink $target as $link\n";
if (!is_link($link)) {
symlink($target, $link);
}
}
}
...@@ -78,22 +78,27 @@ class DatePicker extends InputWidget ...@@ -78,22 +78,27 @@ class DatePicker extends InputWidget
public function run() public function run()
{ {
echo $this->renderWidget() . "\n"; echo $this->renderWidget() . "\n";
$containerID = $this->inline ? $this->containerOptions['id'] : $this->options['id']; $containerID = $this->inline ? $this->containerOptions['id'] : $this->options['id'];
$language = $this->language ? $this->language : Yii::$app->language; $language = $this->language ? $this->language : Yii::$app->language;
if ($language != 'en-US') { if ($language != 'en-US') {
$view = $this->getView(); $view = $this->getView();
DatePickerLanguageAsset::register($view); $bundle = DatePickerLanguageAsset::register($view);
if ($bundle->autoGenerate) {
$am = $view->getAssetManager();
$view->registerJsFile($am->getAssetUrl("jquery-ui/ui/i18n/datepicker-$language.js"), [
'depends' => [JuiAsset::className()],
]);
}
$options = Json::encode($this->clientOptions); $options = Json::encode($this->clientOptions);
$view->registerJs("$('#{$containerID}').datepicker($.extend({}, $.datepicker.regional['{$language}'], $options));"); $view->registerJs("$('#{$containerID}').datepicker($.extend({}, $.datepicker.regional['{$language}'], $options));");
$options = $this->clientOptions;
$this->clientOptions = false; // the datepicker js widget is already registered
$this->registerWidget('datepicker', $containerID);
$this->clientOptions = $options;
} else { } else {
$this->registerWidget('datepicker', $containerID); $this->registerClientOptions('datepicker', $containerID);
} }
$this->registerClientEvents('datepicker', $containerID);
JuiAsset::register($this->getView());
} }
/** /**
......
...@@ -15,9 +15,15 @@ use yii\web\AssetBundle; ...@@ -15,9 +15,15 @@ use yii\web\AssetBundle;
*/ */
class DatePickerLanguageAsset extends AssetBundle class DatePickerLanguageAsset extends AssetBundle
{ {
public $js = [ /**
'jquery.ui.datepicker-i18n.js', * @var boolean whether to automatically generate the needed language js files.
]; * If this is true, the language js files will be determined based on the actual usage of [[DatePicker]]
* and its language settings. If this is false, you should explicitly specify the language js files via [[js]].
*/
public $autoGenerate = true;
/**
* @inheritdoc
*/
public $depends = [ public $depends = [
'yii\jui\JuiAsset', 'yii\jui\JuiAsset',
]; ];
......
...@@ -9,6 +9,7 @@ namespace yii\web; ...@@ -9,6 +9,7 @@ namespace yii\web;
use Yii; use Yii;
use yii\base\Object; use yii\base\Object;
use yii\helpers\Url;
/** /**
* AssetBundle represents a collection of asset files, such as CSS, JS, images. * AssetBundle represents a collection of asset files, such as CSS, JS, images.
...@@ -115,4 +116,61 @@ class AssetBundle extends Object ...@@ -115,4 +116,61 @@ class AssetBundle extends Object
$this->baseUrl = rtrim(Yii::getAlias($this->baseUrl), '/'); $this->baseUrl = rtrim(Yii::getAlias($this->baseUrl), '/');
} }
} }
/**
* @param View $view
*/
public function registerAssetFiles($view)
{
$manager = $view->getAssetManager();
foreach ($this->js as $js) {
$view->registerJsFile($this->getAssetUrl($js, $manager), $this->jsOptions);
}
foreach ($this->css as $css) {
$view->registerCssFile($this->getAssetUrl($css, $manager), $this->cssOptions);
}
}
/**
* Returns the actual URL for the specified asset.
* The actual URL is obtained by prepending either [[baseUrl]] or [[AssetManager::baseUrl]] to the given asset path.
* @param string $asset the asset path. This should be one of the assets listed in [[js]] or [[css]].
* @param AssetManager $manager the asset manager
* @return string the actual URL for the specified asset.
*/
protected function getAssetUrl($asset, $manager)
{
if (($actualAsset = $manager->resolveAsset($asset)) !== false) {
return Url::isRelative($actualAsset) ? $manager->baseUrl . '/' . $actualAsset : $actualAsset;
}
if (strncmp($asset, '@/', 2) === 0) {
return $manager->baseUrl . substr($asset, 1);
} elseif (Url::isRelative($asset)) {
return $this->baseUrl . '/' . $asset;
} else {
return $asset;
}
}
/**
* Returns the actual file path for the specified asset.
* @param string $asset the asset path. This should be one of the assets listed in [[js]] or [[css]].
* @param AssetManager $manager the asset manager
* @return string|boolean the actual file path, or false if the asset is specified as an absolute URL
*/
public function getAssetPath($asset, $manager)
{
if (($actualAsset = $manager->resolveAsset($asset)) !== false) {
return Url::isRelative($actualAsset) ? $manager->basePath . '/' . $actualAsset : false;
}
if (strncmp($asset, '@/', 2) === 0) {
return $manager->basePath . substr($asset, 1);
} elseif (Url::isRelative($asset)) {
return $this->basePath . '/' . $asset;
} else {
return false;
}
}
} }
...@@ -10,7 +10,6 @@ namespace yii\web; ...@@ -10,7 +10,6 @@ namespace yii\web;
use Yii; use Yii;
use yii\base\Component; use yii\base\Component;
use yii\base\InvalidConfigException; use yii\base\InvalidConfigException;
use yii\helpers\Url;
/** /**
* AssetManager manages asset bundle configuration and loading. * AssetManager manages asset bundle configuration and loading.
...@@ -84,6 +83,8 @@ class AssetManager extends Component ...@@ -84,6 +83,8 @@ class AssetManager extends Component
*/ */
public $assetMap = []; public $assetMap = [];
private $_dummyBundles = [];
/** /**
* Initializes the component. * Initializes the component.
...@@ -114,7 +115,7 @@ class AssetManager extends Component ...@@ -114,7 +115,7 @@ class AssetManager extends Component
public function getBundle($name) public function getBundle($name)
{ {
if ($this->bundles === false) { if ($this->bundles === false) {
return null; return $this->loadDummyBundle($name);
} elseif (!isset($this->bundles[$name])) { } elseif (!isset($this->bundles[$name])) {
return $this->bundles[$name] = $this->loadBundle($name); return $this->bundles[$name] = $this->loadBundle($name);
} elseif ($this->bundles[$name] instanceof AssetBundle) { } elseif ($this->bundles[$name] instanceof AssetBundle) {
...@@ -122,7 +123,7 @@ class AssetManager extends Component ...@@ -122,7 +123,7 @@ class AssetManager extends Component
} elseif (is_array($this->bundles[$name])) { } elseif (is_array($this->bundles[$name])) {
return $this->bundles[$name] = $this->loadBundle($name, $this->bundles[$name]); return $this->bundles[$name] = $this->loadBundle($name, $this->bundles[$name]);
} elseif ($this->bundles[$name] === false) { } elseif ($this->bundles[$name] === false) {
return null; return $this->loadDummyBundle($name);
} else { } else {
throw new InvalidConfigException("Invalid asset bundle configuration: $name"); throw new InvalidConfigException("Invalid asset bundle configuration: $name");
} }
...@@ -143,49 +144,42 @@ class AssetManager extends Component ...@@ -143,49 +144,42 @@ class AssetManager extends Component
return $bundle; return $bundle;
} }
/** protected function loadDummyBundle($name)
* @param View $view
* @param AssetBundle $bundle
*/
public function registerAssetFiles($view, $bundle)
{ {
foreach ($bundle->js as $js) { if (!isset($this->_dummyBundles[$name])) {
$view->registerJsFile($this->getAssetUrl($bundle, $js), $bundle->jsOptions); $this->_dummyBundles[$name] = $this->loadBundle($name, [
} 'js' => [],
foreach ($bundle->css as $css) { 'css' => [],
$view->registerCssFile($this->getAssetUrl($bundle, $css), $bundle->cssOptions); 'depends' => [],
]);
} }
return $this->_dummyBundles[$name];
} }
protected function getAssetUrl($bundle, $file) public function resolveAsset($asset)
{ {
if (($mappedFile = $this->mapAsset($file)) !== false) { if (isset($this->assetMap[$asset])) {
return Url::isRelative($mappedFile) ? $this->baseUrl . '/' . $mappedFile : $mappedFile; return $this->assetMap[$asset];
} }
if (strncmp($file, '@/', 2) === 0) { $n = strlen($asset);
$file = $this->baseUrl . substr($file, 1);
} elseif (Url::isRelative($file)) {
$file = $bundle->baseUrl . '/' . $file;
}
return $file;
}
protected function mapAsset($file)
{
if (isset($this->assetMap[$file])) {
return $this->assetMap[$file];
}
$n = strlen($file);
foreach ($this->assetMap as $from => $to) { foreach ($this->assetMap as $from => $to) {
$n2 = strlen($from); $n2 = strlen($from);
if ($n2 <= $n && substr_compare($file, $from, $n - $n2, $n2) === 0) { if ($n2 <= $n && substr_compare($asset, $from, $n - $n2, $n2) === 0) {
return $to; return $to;
} }
} }
return false; return false;
} }
public function getAssetUrl($asset)
{
return $this->baseUrl . '/' . ltrim($asset, '/');
}
public function getAssetPath($asset)
{
return $this->basePath . '/' . ltrim($asset, '/');
}
} }
...@@ -261,7 +261,7 @@ class View extends \yii\base\View ...@@ -261,7 +261,7 @@ class View extends \yii\base\View
foreach ($bundle->depends as $dep) { foreach ($bundle->depends as $dep) {
$this->registerAssetFiles($dep); $this->registerAssetFiles($dep);
} }
$this->getAssetManager()->registerAssetFiles($this, $bundle); $bundle->registerAssetFiles($this);
} }
unset($this->assetBundles[$name]); unset($this->assetBundles[$name]);
} }
...@@ -380,7 +380,7 @@ class View extends \yii\base\View ...@@ -380,7 +380,7 @@ class View extends \yii\base\View
} else { } else {
$this->getAssetManager()->bundles[$key] = new AssetBundle([ $this->getAssetManager()->bundles[$key] = new AssetBundle([
'baseUrl' => '', 'baseUrl' => '',
'css' => [$url], 'css' => [ltrim($url, '/')],
'cssOptions' => $options, 'cssOptions' => $options,
'depends' => (array) $depends, 'depends' => (array) $depends,
]); ]);
...@@ -445,7 +445,7 @@ class View extends \yii\base\View ...@@ -445,7 +445,7 @@ class View extends \yii\base\View
} else { } else {
$this->getAssetManager()->bundles[$key] = new AssetBundle([ $this->getAssetManager()->bundles[$key] = new AssetBundle([
'baseUrl' => '', 'baseUrl' => '',
'js' => [$url], 'js' => [ltrim($url, '/')],
'jsOptions' => $options, 'jsOptions' => $options,
'depends' => (array) $depends, 'depends' => (array) $depends,
]); ]);
......
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