How to make selective asset redefinition in Yii2? - yii2

I want to overwrite a css code of an existing asset, for example “kartik\form\ActiveFormAsset”. If i follow the official guide, i will do this:
'components' => [
'assetManager' => [
'bundles' => [
'kartik\form\ActiveFormAsset' => [
'sourcePath' => null, // do not publish the bundle
'basePath' => '#webroot',
'baseUrl' => '#web',
'css' => [
'/custom.css',
]
],
],
],
],
But it automatically changes a path to a js file which i want to keep up-to-date and don’t do any changes.
So, how to overwrite asset only for css, not for js?

If you don't need an asset assignment or you want overwrite the assignmente you could try using registering scripts in your view .
$this->registerCssFile("#web/css/themes/black-and-white.css", [
'depends' => [\yii\bootstrap\BootstrapAsset::class],
'media' => 'print',
], 'css-print-theme');
see yii2 guide and reference for this
https://www.yiiframework.com/doc/guide/2.0/en/output-client-scripts
https://www.yiiframework.com/doc/api/2.0/yii-web-view

Related

Using different value for same key in yii2 i18n

i', trying to incorporate multi-language functionality into my project and i have a situation whereby the same key has multiple meaning and i wounder how to fix this for example i have in my project
return[
'Home' => '首页', //meaning ‘Home page’
]`
Now the case is i also have some over words with Home as the key but have another meaning like thus
'Home' => '主队', //meaning ‘Home team’
how can actualize this using the same key "Home" but giving them different meaning on different part of my project
There are two options how to deal with situation like that.
Using categories
The proper way would be using different categories for different meanings. To do that you have to configure the translations for two (or more) different categories, for example like that.
'components' => [
// ...
'i18n' => [
'translations' => [
'app*' => [
'class' => 'yii\i18n\PhpMessageSource',
'fileMap' => [
'app' => 'app.php',
'app/match' => 'match.php',
],
],
],
],
],
Your app.php translation file will look like this
return [
'Home' => '首页', //meaning ‘Home page’
];
And your match.php translation file will look like this:
return [
'Home' => '主队', //meaning ‘Home team’
];
Then you will call translations like this where the meaning is home page:
Yii::t('app', 'Home');
And like this where the meaning is home team:
Yii::t('app/match', 'Home');
If you are using yii message command to generate translation files you might need to set the fileMap in it's config to make sure all files are generated properly.
Forcing translations for source language
This way is more like hack than proper solution. You can force the i18n component to translate text even if the source and app language are same. You can use that to have two different keys that are same in the english translations but different in other.
The configuration would look like:
'components' => [
// ...
'i18n' => [
'translations' => [
'app*' => [
'class' => 'yii\i18n\PhpMessageSource',
'forceTranslation' => true,
'fileMap' => [
'app' => 'app.php',
],
],
],
],
],
The english app.php translation file:
return [
'Home page' => 'Home',
'Home team' => 'Home',
];
The chinese app.php translation file:
return [
'Home page' => '首页',
'Home team' => '主队',
];
You will use Yii::t('app', 'Home page') or Yii::t('app', 'Home team') in your code.

YII2 How to allow debug/default/toolbar in accesscontrol

I have the following configuration in the web.php file to force users to login first before using the app.
'as access' => [
'class' => \yii\filters\AccessControl::className(), //AccessControl::className(),
'rules' => [
[
'actions' => ['login', 'error'],
'allow' => true,
],
[
'actions' => ['logout', 'index'], // add all actions to take guest to login page
'allow' => true,
'roles' => ['#'],
],
],
],
However I get a Forbidden (#403) error in the http://localhost/yii2/debug/default/toolbar?tag=58759099581f2
How to allow in that in the rules?
First of all, this config is incorrect. This part:
[
'actions' => ['logout', 'index'], // add all actions to take guest to login page
'allow' => true,
'roles' => ['#'],
],
will additionally allow only logout and index actions to authenticated users. It needs to be changed to:
[
'allow' => true,
'roles' => ['#'],
],
to allow access to the entire site. Then you can customize access further in AccessControl or actions of specific controllers. So debug is not the only forbidden page in your case.
I think it was copy pasted from this answer to related question here on SO.
And by the way debug is already enabled in application config in basic app:
if (YII_ENV_DEV) {
// configuration adjustments for 'dev' environment
$config['bootstrap'][] = 'debug';
$config['modules']['debug'] = [
'class' => 'yii\debug\Module',
// uncomment the following to add your IP if you are not connecting from localhost.
//'allowedIPs' => ['127.0.0.1', '::1'],
];
// Below Gii is enabled too, code is omitted for brevity
}
So when user is authenticated, you will have access to debug module without any problems.
Note: With this configuration login and error actions of every controller are allowed to non-authenticated users. Be careful with that. There is a chance of actions with similar names exist in other controllers.
Update: Actually you can go further and make this solution more flexible with $matchCallback:
'as access' => [
'class' => \yii\filters\AccessControl::className(),
'rules' => [
[
'matchCallback' => function ($rule, $action) {
$allowedControllers = [
'debug/default',
];
$allowedActions = [
'site/login',
'site/error',
];
$isAllowedController = in_array($action->controller->uniqueId, $allowedControllers);
$isAllowedAction = in_array($action->uniqueId, $allowedActions);
return $isAllowedController || $isAllowedAction;
},
'allow' => true,
],
[
'allow' => true,
'roles' => ['#'],
],
],
],
Place fully allowed controllers in $allowedControllers list (prefix it with module name if it's inside a module) to allow them completetely (allow all actions).
Place allowed actions in $allowedActions list (prefix it with controller name and with module name if it belongs to a module).
That way you can have full access to debug module on local server on every page (including login and error) which can be useful.
Also this prevents from action names coincidence from different modules / controllers.
You have to enable the toolbar action web.php config file:
'rules' => [
[
'actions' => ['login', 'error', 'toolbar'],
'allow' => true,
],

Yii2 ActiveFormAsset dependencies

I'm foregoing Yii2's bundled jQuery and Bootstrap assets in exchange for ones I've bundled myself using npm/browserify So step one was to remove jQuery and Bootstrap from yii\web\YiiAsset via the config:
'components' => [
'assetManager' => [
'bundles' => [
'yii\web\JqueryAsset' => [
'js'=>[]
],
'yii\bootstrap\BootstrapPluginAsset' => [
'js'=>[]
],
'yii\bootstrap\BootstrapAsset' => [
'css' => [],
],
],
],
...
]
I want to put this in the footer, obviously, but it needs to load before any other assets so that jQuery is available to them.
Here's my AssetBundle:
class AppAssets extends AssetBundle
{
public $basePath = '#webroot';
public $baseUrl = '#web';
public $depends = [
'app\assets\CustomAssets',
'yii\web\YiiAsset',
];
}
With my CustomAssets bundle (that contains my own JS and CSS) declared first in depends, I think this would work, but I also have an ActiveForm on the page, and this registers its own asset bundle, which is dependent on the various Yii assets. Here's where I embed that form:
<?php $form = ActiveForm::begin(['id' => 'contact-form']); ?>
...
<?php ActiveForm::end(); ?>
Is there a way I can override the depends on ActiveFormAsset so that it also depends on my scripts?
Since asset bundle dependencies are transitive, it occurred to me that in the same way I'm overriding the config for the Jquery and Bootstrap bundles, I can override the config for yii\web\YiiAsset like so:
'components' => [
'assetManager' => [
'bundles' => [
...
'yii\web\YiiAsset' => [
'depends' => [
'app\assets\CustomAssets',
],
],
],
],
...
]
So when ActiveFormAsset tries to load yii\web\YiiAsset, it processes the dependency on my own scripts/styles, and also covers any other assets that get loaded and might depend on yii\web\YiiAsset.
what i did was replacing shipped assets, instead of killing them:
'bundles' => [
'yii\bootstrap\BootstrapAsset' => ['class' => 'common\assets\BootstrapAsset',],
'yii\bootstrap\BootstrapPluginAsset' => ['class' => 'common\assets\BootstrapPluginAsset',],
],

how can I access frontend module from backend in yii2?

I have created 'contact_us' CRUD in frontend. Now I want to show listing of that contact_us (i.e. index.php) in backend. how can I access it?
You should add a new urlMangerBackend in urlManager component in your frontend application /config/main.php
and then refer to this in your createUrl
return [
....
'components' => [
'urlManager' => [
// your normal frontend URL rules
],
'urlManagerBackend' => [
'class' => 'yii\web\urlManager',
'baseUrl' => '/yourapp/backend/web',
'enablePrettyUrl' => true,
'showScriptName' => true,
],
],
];
and you can invoke this way
Yii::$app->urlManagerBackend->createUrl();

Yii2 Theme Integration not working?

Yii2 Theme Integration ?
'view' => [
'theme' => [
'pathMap' => ['#app/views' => '#app/admin/views'],
'baseUrl' => '#web/admin',
],
],
Hope you are using the advanced template
add a folder themes in the backend folder
make a subfolder with the theme name and make sure you have the layouts folder in that folder
ie
your new layout folder path will be
backend/themes/themefoldername/layouts
in the folder backend/config/main.php
'components' => [
'view' => [
'theme' => [
'basePath' => '#backend/themes/themefoldername',
'baseUrl' => '#backend/themes/themefoldername',
'pathMap' => [
'#backend/views' => '#backend/themes/themefoldername',
],
],
],...
if you want to keep it in the web folder also you can do that,but make sure you change the path accordingly
In advance template there is separate configuration for frontend and backend theme integration.
Frontend theme integration => "frontend/config/main.php" file :
'components' => [
'view' => [
'theme' => [
'pathMap' => [
'#frontend/views' => '#themes/frontend/views', // need to // set alias first in your bootstrap.php file
],
],
],
],
Backend theme integration => "backend/config/main.php" file :
'components' => [
'view' => [
'theme' => [
'pathMap' => [
'#backend/views' => '#themes/backend/views', // need to set // alias first in your "common/config/bootstrap.php" file
],
],
],
],
While coding take care of comments and directory paths and no need to write baseUrl or basePath.
create "themes" directory in web directory and create theme there.
then include this code in your main config file.
'view' => [
'theme' => [
'baseUrl' => '#web/themes/yourthemename',
'pathMap' => [
'#app/views' => [
'#webroot/themes/yourthemename/views',
]
],
],
]
use this code in your web.php file.
'view' => [
'theme' => [
'class' => yii\base\Theme::className(),
'basePath' => '#app/themes/themename',
'baseUrl' =>'#web/themes/themename',
],
],
Here is my code which i normally use for themeing. You can set param in params file and add theme name there or directly in the below code.
'view' => [
'theme' => [
'pathMap' => ['#app/views' => '#webroot/themes/themename/views'],
'baseUrl' => '#web/themes/themename',
],
],
if you are using yii2 basic then in config/web.php write this
return [
'components' => [
'view' => [
'theme' => [
'basePath' => '#app/themes/basic',
'baseUrl' => '#web/themes/basic',
'pathMap' => [
'#app/views' => '#app/themes/basic',
],
],
],
],
];
I have the adminlte theme this be find the vendor folder,
then in the config/main.php added this:
'components' => [
'view' => [
'theme' => [
'pathMap' => [
'#app/views' => '#vendor/dmstr/yii2-adminlte-asset/example-views/yiisoft/yii2-app'
],
],
],
In basic installation under config/web.php add the code under component block.
'components' => [
................
....................
'view' => [
'theme' => [
'pathMap' => [
'#app/views' => '#app/themes/mytheme',
'#app/modules' => '#app/themes/mytheme/modules',
],
'baseUrl' => '#web/themes/mytheme',
],
],
...........
]
Refer below link for install theme and setup.
http://banoprogrammer.blogspot.in/2017/07/backend-theme-installation.html
I set up a theme for my frontend using the advanced template. My themes are located in the themes folder which I created for storing the themes. eg. web/themes/cerulean. There are NO physical view folders under any of the individual theme folders as might be suggested by some of the key/value pairs that I have seen eg. ['#app/views' => '#webroot/themes/themename/views]. In fact, my code runs with and without value's views subfolder. This is my working code => #webroot/themes/cerulean as opposed to #webroot/themes/cerulean/views but it does need key's views subfolder. ie. #app/views. I have tested both of these variations and they both work so do not be concerned whether you have a view on the end of the value or not.
Because I am using a theme for the frontend I have replaced #app/views as above with #frontend/views. This is my code in my frontend/config/main.php file.
'view' => [
'theme' => [
'pathMap' => ['#frontend/views' => '#webroot/themes/cerulean',],
'baseUrl' => '#web/themes/cerulean',
],
],
This is the code in my frontend\assets\appasset.php file:
namespace frontend\assets;
use yii\web\AssetBundle;
use Yii;
Yii::setAlias('#themes', Yii::$app->view->theme->baseUrl);
/**
* Main frontend application asset bundle.
*/
class AppAsset extends AssetBundle
{
public $basePath = '#webroot';
//public $baseUrl = '#web';
public $baseUrl = '#themes';
public $css = [
'css/site.css',
];
public $js = [
];
public $depends = [
'yii\web\YiiAsset',
'yii\bootstrap\BootstrapAsset',
];
}
You will notice above that I have substituted the
public $baseUrl = '#web';
with an alias #themes which I have set at the top namely...
Yii::setAlias('#themes', Yii::$app->view->theme->baseUrl);
The baseurl in the code above is now set to #themes which actually represents #web/themes/cerulean' taken from the 'view' => 'theme' setting located in the main.php file under frontend/config.