I have folder (e.x.: /modules/admin/static/) out of web/ and I specified sourcePath: /modules/admin/static/.
Yii generating assets files in web/assets/13dfh1/.
But I want to change this folder to web/static/assets/13dfh1/.
I want have url: http://example.com/static/assets/13dfh1/.
baseUrl and basePath ignored if specified sourcePath.
It's must for another depends, such as YiIAsset, debug, and etc.
Please, help me.
P.S. Sorry for my egnlish )
If you want change the asset folder you can change the basePath in assetManager in your \config\main.php
'components' => [
'assetManager' => [
'basePath' => '#webroot/your-assets-dir',
],
.......
Else you can do it by the code
\Yii:$app->assetManager->basePath = '#webroot/your-assets-dir';
Related
I'm using Yii2 advanced, which have frontend and backend, I'm using two domain to access frontend and backend respectively.
For some reason, I add a baseUrl(/admin) to backend, which will cause links like http://backend.example.com/controller/action change to backend.example.com/admin/controller/action, after this changing, the page can be load correctly
'components' => [
'request' => [
'csrfParam' => '_csrf-backend',
//All requests will add "/admin",e.g:
//backend.example.com/controller/action will change to
//backend.example.com/admin/controller/action
'baseUrl' => '/admin',
],
],
But it caused another problem: assets can't load cause it add /admin too
I tried changing the baseUrl of AppAssets in backend/assets/AppAsset.php, but not working
<?php
namespace backend\assets;
use yii\web\AssetBundle;
/**
* Main backend application asset bundle.
*/
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',
];
}
It acts like $baseUrl doesn't exists, no matter what value I set to $baseUrl, the page just keep requesting /admin/assets/86321cf/xxxx.js, how can I remove the /admin by modifying settings in backend/assets/AppAsset.php?
If I use the registerJsFile() method to register js to the page
$this->registerJsFile('plugins/ImageViewer/imageviewer.min.js', ['position' => View::POS_END, 'depends'=>JqueryAsset::class]);
it's loading the correct path(which means not adding /admin to the path)
So I was wondering how can I let the page load correct path of assets by changing configurations of backend/assets/AppAsset.php or can I solve it by changing configurations in other file?
$baseUrl in asset - specifies the URL corresponding to the directory basePath. Like basePath, if you specify the sourcePath property, the asset manager will publish the assets and overwrite this property accordingly.
try to write #app/backend/web in baseUrl
since it seems to me that #web after being assigned to the request will be equal to / admin
OK, after massive searching and asking people, I solve this myself, it turns out that we can set the $baseUrl of backend/assets/AppAsset.php in main.php in this way
'components' => [
'assetManager' => [
//after settting components.request.baseUrl='/admin', the assets url will automatically add "/admin" to its url
//to avoid this, we can set the asset baseUrl in components.assetManager.baseUrl, set it to '/assets'
'baseUrl' => '/assets',
],
'request' => [
'csrfParam' => '_csrf-backend',
//All requests will add "/admin",e.g:
//www.example.com/controller/action will change to
//www.example.com/admin/controller/action
'baseUrl' => '/admin',
],
// other configs....
],
These two link inspired me:
Yii - Assets
Override Yii2 assetManager config in controller
how I can load an external-site module? I have a common module I need to load in distinct Yii2 sites, like advanced-template my idea is to have a common dir where store generic modules wich I can load to each site. A file system structure can be like this:
/
site-1/
(loads modules from common-modules dir for site-1)
site-2/
(loads modules from common-modules dir for site-2)
common_sites_modules/
module-1/
module-2/
carrello/
Carrello.php
Each site in his configuration have to load modules from common-modules/
Is possible to implement this structure?
Edit 1
The configuration:
'cart' => [
'class' => dirname(dirname(dirname(__DIR__))) . '/common_sites_modules/carrello/Carrello',
'params' =>[
...
],
'components' => [
...
],
],
and this is the first line of the class Carrello.php:
<?php
namespace common_sites_modules\carrello;
...
The top bar of editor with the path of the class and the error returned by Yii:
Edit 2:
Thanks to #Yupik for support and suggests, the new settings:
bootstrap.php:
Yii::setAlias('#common-modules', dirname(dirname(dirname(__DIR__))) . '/common_sites_modules');
main-local.php:
'class' => '#common-modules\carrello\Carrello',
The generated error:
Like suggested in the comments the solution is to declare an alias and then use the name of alias for call the module. Like suggested by #Yupik I've set in the common/config/bootstrap.php an alias as follow:
Yii::setAlias('#common_modules', dirname(dirname(dirname(__DIR__))) . '/common_modules');
In the main configuration:
'carrello' => [
'class' => ''common_modules\carrello\Carrello',
...
]
Obviously namespace have to be configured based on the position on filesystem.
Thanks for the suggestions
Yes, we can do this by making a symlink of common_sites_modules directory in both site folder (site1, site2).
I am using Yii2 and have been reading about theming and theme inheritance; however have some questions:
Consider the following example:
'view' => [
'theme' => [
'pathMap' => [
'#app/views' => [
'#app/themes/current',
'#app/themes/default',
],
],
'baseUrl' => '#web/themes/current',
'basePath' => '#webroot/themes/current',
],
],
Now, imagine we request the theme file foo; as I understand it this will first be looked for in the following order:
#app/themes/current/foo.php
#app/themes/default/foo.php
#app/views/foo.php
Now imagine foo.php isn't found in the #app/themes/current/ theme, so it would use the file found in #app/themes/default/.
Now, considering the baseUrl and basePath settings I am a little confused how these are used in these situations.
Now, imagine foo.php references an image file inside the file, wouldn't this still attempt to find #web/themes/current/images/myImage.jpg rather than #web/themes/default/images/myImage.jpg?
In this case, basePath is worthless. Because basePath is only applied when
pathMap is empty.
basePath is not a fallback, It is a shortcut of pathMap, quick use when you only have one theme.
'pathMap' => [
'#app/views' => [
'#app/themes/current/views',
],
],
Equivalent to:
'basePath' => '#app/themes/current',
(Yii understands that folder #app/themes/current/views exist)
baseUrl: It is returned when you call $this->theme->getBaseUrl() in view file. Less worth with multi theme.
About fallback for static files. Theming fallback is not designed for this purpose.
Point your links inside file like this exmaple from docs:
$theme = $this->theme;
// returns: $theme->baseUrl . '/img/logo.gif'
$url = $theme->getUrl('img/logo.gif');
// returns: $theme->basePath . '/img/logo.gif'
$file = $theme->getPath('img/logo.gif');
It will get file from current theme directory.
Everytime I update my css or js files in infoweb\menu\module\assets, I have to empty the backend\web\assets folder
is there a way to automatically clear the assets cache?
Add this in your view:
use vendor\myVendorName\myPackageName\assets\AppAsset;
AppAsset::register($this);
Add this in your config:
'components' => [
'assetManager' => [
'linkAssets' => true,
],
]
Empty assets folder, and refresh, done
there is additional property as
if (YII_ENV_DEV) {
...;
...;
...;
$config['components']['assetManager']['forceCopy'] = true;
...;
...;
}
to publish files even there are published before
If you enviroment is production I recommend to use Cache Busting :
return [
// ...
'components' => [
'assetManager' => [
'appendTimestamp' => true,
],
],
];
for more information about assets, read the Assets Yii2 documentation.
If you are developing your own plugin, you can force publish assets per bundle
(note: $sourcePath should be set)
<?php
namespace app\components\forms\redactorAssets;
use yii\web\AssetBundle;
class RedactorCutAsset extends AssetBundle {
public $sourcePath = '#app/components/forms/redactorAssets/assets';
public $js = [
'cut.js',
];
public $publishOptions = [
'forceCopy'=>true,
];
}
sudo rm -rf frontend/web/assets/*
sudo chmod 777 frontend/web/assets
./yii cache/flush-all
If this does not work:
sudo rm -rf vendor/*
composer install
I use CClientScript::registerScriptFile method in my view files:
Yii::app()->clientScript->registerScriptFile(
$this->getAssetsBase() . '/js/script.js'
);
If I modified script.js, after next page reload I will see all changes
For css files - CClientScript::registerCssFile
Yii::app()->clientScript->registerCssFile(
$this->getAssetsBase() . '/css/style.css'
);
UPDATE: if you use yii 2.0 beta, you can read some information about changes in mechanic of client helpers here: link
The AssetManager will create a hash based on the file modification time. The modification time of a directory does not change when any file is changed.
If you have an AssetBundle that has a directory as $sourcePath, the modification time of the directory is used, the hash will not change, and nothing gets copied to the web/assets directory.
I suggest overriding AssetManager::hash() in a subclass or write a function for AssetManager::$hashCallback:
'components' => [
'assetManager' => [
'hashCallback' => function($path) {
// if: $path is directory: figure out when files were changed in directory
// else: use original hash function in \yii\web\AssetManager
}
],
]
For a sample implementation for finding the max modified date over all asset files in a bundle you could look at this comment by wookie # http://php.net/manual/en/function.filemtime.php#35779
Note that modification to any asset file will create a new directory in web/assets, and regular cleanup will remain necessary. However, browser cache aside, refreshing the page will follow the latest changes.
I configure the assetManager::forceCopy=true in main-local.php for the dev environment like this
return [
'components' => [
...
'assetManager' => [
'forceCopy' => true,
]
...
],
];
I'm following the method described here to have my control panel in backend folder.
The problem is I don't want to create two assets folders so I want to set assetManager baseUrl property in my backend/config/main.php but I'm enable to get the URL of the backend in the config. I don't want it hard coded because I need the code to be portable.
What can I do?
Thanks.
You can configure asset manager's baseUrl in /backend/config/main.php
'components' => array(
...
'assetManager' => array(
'class' => 'CAssetManager',
'baseUrl' => 'frontend.assets'
),
...