How can we add minification in yii2 frontend application? - php

How to add minfication for css and js files or can i add minify them and add in single file .I have added some css and js file for full application and others are page wise?

AssetBundle represents a collection of asset files, such as CSS, JS, etc.
An asset bundle can depend on other asset bundles. When registering an asset bundle with a view, all its dependent asset bundles will be automatically registered.
please refer below link
Yii2 AssetBundle API DOC
AssetBundle Example
In Your Yii2 Basic Application
Yii2 Basic Application Asset Bundle Example
In Your Yii2 Advanced Application
First create one AppAsset AssetBundule in your frontend->assets->AppAsset.php.
<?php
namespace frontend\assets;
use yii\web\AssetBundle;
class AppAsset extends AssetBundle
{
public $basePath = '#webroot';
public $baseUrl = '#web';
public $css = [
....
css file here
....
];
public $js = [
....
js file here
....
];
public $jsOptions = [
....
js options here
....
];
public $depends = [
....
dependent asset bundles here
eg: 'yii\bootstrap\BootstrapAsset'
....
];
}
?>
Now register the AppAsset in your view file
<?php
use frontend\assets\AppAsset;
AppAsset::register($this);
?>
And Also Register Single js and css file
Single Js ans Css File Register

You can use https://github.com/skeeks-semenov/yii2-assets-auto-compress
It is easy and fast to configure. Once installed you only need to update your config file.
i.e
'components' => [
'assetsAutoCompress' => [
'class' => '\skeeks\yii2\assetsAuto\AssetsAutoCompressComponent',
],
and then bootstrap it.
'bootstrap' => ['log', 'assetsAutoCompress'],
That's it then you are ready to go.

Related

Cannot set "AppAsset baseurl" after settting "request baseUrl" in Yii2 advanced(php framework)

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

yii2 - RBAC - is it shared between backend and frontend?

I have just discovered and started using Role Based Access control.
Since I am using an advanced template for yii2, I am wondering if roles and permissions are shared between backend and frontend tiers or if they are separated.
For example
<?php
namespace app\commands;
use Yii;
use yii\console\Controller;
class RbacController extends Controller
{
public function actionInit()
{
$auth = Yii::$app->authManager;
// add "createPost" permission
$createPost = $auth->createPermission('createPost');
$createPost->description = 'Create a post';
$auth->add($createPost);
// add "author" role and give this role the "createPost" permission
$author = $auth->createRole('author');
$auth->add($author);
$auth->addChild($author, $createPost);
}
}
would author and createpost be available for both backend and frontend?
thank you!
The RBAC componet are base on common part .. typically if they are base on DB you use common models and shared the related db table ..
You can declare this element in component section of main.php in cofig area and if you do this in common dir this component si correctly shared between both the enviroment (frontend , backend) and eventually between all apps you distribute you projectc..
eg : common/config/main.php
'components' => [
.....
'authManager' => [
'class' => 'yii\rbac\DbManager',
'cache' => 'cache',
....
],
this mean they could be naturally shared between frontend and backend ..

Placing a widget inside a custom widget with custom itemView yii2

I want to create a custom widget named 'IssueList' which will extend 'ListView'.
<?php
namespace frontend\components;
use yii\base\Widget;
use yii\widgets\ListView;
class IssueList extends Widget{
public $dataProvider;
public function init(){
parent::init();
}
public function run(){
return ListView::widget([
'dataProvider' => $this->dataProvider,
'itemOptions' => [
'class' => 'item issue-item'
],
'options' => [
'class' => 'issue_list'
],
'itemView' => '_issueListView',
'layout' => '{items}{pager}',
]);
}
}?>
However the ListView has a custom itemView. When rendering the widget I get this error
The view file does not exist:
/var/www/clients/client1/web1/frontend/views/comments/_issueListView.php
Its obviously looking in the wrong directory, how do I change this?
itemView is passed to yii\base\View render() which is responsible for rendering view. So you can change view path how you want, using aliases if needed:
Renders a view.
The view to be rendered can be specified in one of the following
formats:
path alias (e.g. "#app/views/site/index");
absolute path within application (e.g. "//site/index"): the view name starts with double slashes. The actual view file will be looked
for under the view path of the application.
absolute path within current module (e.g. "/site/index"): the view name starts with a single slash. The actual view file will be looked
for under the view path of the current module.
relative view (e.g. "index"): the view name does not start with # or /. The corresponding view file will be looked for under the view path
of the view $context. If $context is not given, it will be looked for
under the directory containing the view currently being rendered
(i.e., this happens when rendering a view within another view).
If you want it to be more dynamic, you can pass closure to itemView with the following signature:
function ($model, $key, $index, $widget) {
...
}
See docs for itemView here.
Besides the API Documentation, rendering views and specifying paths is described in official docs in Views (Rendering Views) section.

Setting aliases in Yii2 within the app config file

I'm trying to set an alias in Yii2 but I'm getting a Invalid Parameter / Invalid path alias for the below code that is placed in the app config file:
'aliases' => [
// Set the editor language dir
'#editor_lang_dir' => '#webroot/scripts/sceditor/languages/',
],
If I remove the # it works.
I noticed you can do this:
Yii::setAlias('#foobar', '#foo/bar');
...but I would prefer to set it within the app config file. Is this not possible? If so, how?
Yii2 basic application
To set inside config file, write this inside $config array
'aliases' => [
'#name1' => 'path/to/path1',
'#name2' => 'path/to/path2',
],
Ref: http://www.yiiframework.com/doc-2.0/guide-structure-applications.html
But as mentioned here,
The #yii alias is defined when you include the Yii.php file in your entry script. The rest of the aliases are defined in the application constructor when applying the application configuration.
If you need to use predefined alias, write one component and link it in config bootstrap array
namespace app\components;
use Yii;
use yii\base\Component;
class Aliases extends Component
{
public function init()
{
Yii::setAlias('#editor_lang_dir', Yii::getAlias('#webroot').'/scripts/sceditor/languages/');
}
}
and inside config file, add 'app\components\Aliases' to bootstrap array
'bootstrap' => [
'log',
'app\components\Aliases',
],
In config folder create file aliases.php. And put this:
Yii::setAlias('webroot', dirname(dirname(__DIR__)) . '/web');
Yii::setAlias('editor_lang_dir', '#webroot/scripts/sceditor/languages/');
In web folder in index.php file put:
require(__DIR__ . '/../config/aliases.php');
Before:
(new yii\web\Application($config))->run();
If run echo in view file:
echo Yii::getAlias('#editor_lang_dir');
Show like this:
C:\OpenServer\domains\yii2_basic/web/scripts/sceditor/languages/
#webroot alias is not available at this point, it is defined during application bootstrap :
https://github.com/yiisoft/yii2/blob/2.0.3/framework/web/Application.php#L60
No need to define this alias yourself, you should simply use another one :
'aliases' => [
// Set the editor language dir
'#editor_lang_dir' => '#app/web/scripts/sceditor/languages/',
],
To improve on #vitalik_74's answer
you can place it in config/web.php instead(if you are using the basic yii app, I'm not sure about the main config file in the advance version, but the same applies, just put the require on the main config file) so that it gets shorten to:
require(__DIR__ . '/aliases.php');

Loading core scripts such as jQuery in Yii 2

I've been having a hard time trying to figure out how to load jQuery or other CORE scripts in Yii 2.
In Yii 1 it seemed this was the way:
<?php Yii::app()->clientScript->registerCoreScript("jquery"); ?>
In Yii 2, $app is a property of Yii, not a method, so the above naturally doesn't work, but changing it to:
<?php Yii::$app->clientScript->registerCoreScript("jquery"); ?>
produces this error:
Getting unknown property: yii\web\Application::clientScript
I couldn't find any documentation for Yii 2 about loading core scripts, so I tried the below:
<?php $this->registerJsFile(Yii::$app->request->baseUrl . '/js/jquery.min.js', array('position' => $this::POS_HEAD), 'jquery'); ?>
Whilst this loads jQuery in the head, a second version of jQuery is also loaded by Yii when needed and hence causes conflict errors.
Additionally, I don't want to use Yii's implementation of jQuery, I would prefer to maintain my own and hence that is why I am doing this.
How can I load jQuery and other core files without Yii loading duplicate copies of them when it needs them?
In order to disable Yii2's default assets you can refer to this question:
Yii2 disable Bootstrap Js, JQuery and CSS
Anyway, Yii2's asset management way is different from Yii 1.x.x. First you need to create an AssetBundle. As official guide example, create an asset bundle like below in ``:
namespace app\assets\YourAssetBundleName;
use yii\web\AssetBundle;
class YourAssetBundleName extends AssetBundle
{
public $basePath = '#webroot';
public $baseUrl = '#web';
public $css = [
'path/file.css',//or files
];
public $js=[
'path/file.js' //or files
];
//if this asset depends on other assets you may populate below array
public $depends = [
];
}
Then, to publish them on your views:
use app\assets\YourAssetBundleName;
YourAssetBundleName::register($this);
Which $this refers to current view object.
On the other hand, if you need to only register JS files into a view, you may use:
$this->registerJsFile('path/to/file.js');
yii\web\View::registerJsFile()
And if you need to only register CSS files into a view, you may use:
$this->registerCssFile('path/to/file.css');
yii\web\View::registerCssFile()
You can remove the core jQuery from loading like so:
config/web.php
'assetManager' => [
'bundles' => [
// you can override AssetBundle configs here
'yii\web\JqueryAsset' => [
'sourcePath' => null,
'js' => []
],
],
],

Categories