Yii2 How to correctly register a CSS file - yii2

I'm trying to register a CSS file in this way
$this->registerCssFile('../node_modules/fullcalendar/dist/fullcalendar.css', [
'depends' => [\yii\web\JqueryAsset::className()]
]);
But I get the error:
Failed to load a resource.
For instance, I know that I am standing at web folder, so that's why I wrote the above code in that way.
I tried without the registerCssFile and I achieved it writing directly this in the view file:
<link href="../node_modules/fullcalendar/dist/fullcalendar.css" rel="stylesheet">
Therefore I think the error is in the registerCssFile cause when I inspect in the browser this method add a slash (/) before all the relative path:
<link href="/../node_modules/fullcalendar/dist/fullcalendar.css" rel="stylesheet">
Anyway, THE QUESTION is how can I do to achieve it with regiserCssFile(the correct way)?
Or how can I remove that slash?
Just in case:
/yii2app
|_/views
|_/whatever
|_myview.php
|_/web
|_/node_modules
|_/fullcalendar
|_/dist
|_fullcalendar.css

The first thing that I would advise you is to move the folder inside the web directory and remove the trailing ../ from the URL.
Like below
$this->registerCssFile('node_modules/fullcalendar/dist/fullcalendar.css', [
'depends' => [\yii\web\JqueryAsset::className()]
]);
The /yii2app/web directory is where your application Entry script is running from so you do not need to provide a path relative to the view file, but the web directory.
Otherwise, use AssetManager to load assets from outside the web directory and use the $sourcePath option to use the directory outside the web.
see below a demo for Asset manager.
namespace app\assets;
use Yii;
use yii\web\AssetBundle;
use yii\web\View;
// set #themes alias so we do not have to update baseUrl every time we change themes
Yii::setAlias('#themes', Yii::$app->view->theme->baseUrl);
/**
* Main frontend application asset bundle.
*/
class FullCalendarAsset extends AssetBundle
{
public $sourcePath = '#app/node_modules/';
public $css = [
'fullcalendar/dist/_fullcalendar.css',
];
public $js = [
];
public $depends = [
'yii\web\YiiAsset',
'yii\bootstrap\BootstrapAsset',
'yii\bootstrap\BootstrapPluginAsset',
];
}
place the above file inside the app/assets directory and then inside your view
use app\assets\FullCalendarAsset;
FullCalendarAsset::register($this);
you should learn about the application LIFE CYCLE.

Related

appendTimestamp and registerAssetBundle

I am using the following configurations to add the timestamp in the assets path via asset manager.
'assetManager' => [
'appendTimestamp' => true,
appAsset.php
class AppAsset extends AssetBundle
{
public $basePath = '#webroot';
public $baseUrl = '#web';
public $css = [
'/css/style.css'
];
}
In view
AppAsset::register($this);
But in html I still see '/css/style.css' without timestamp.
I saw solution
https://github.com/yiisoft/yii2/issues/9101#issuecomment-267274327
$file = '/css/style.css';
$asset = new \yii\web\AssetBundle(
[
'js' => [ltrim($file, '/')],
'basePath' => '#webroot',
'baseUrl' => '/'
]
);
$this->getAssetManager()->bundles[$file] = $asset;
$this->registerAssetBundle($file);
This example is work. '/css/style.css?v=12557565'
Is there any method write registerAssetBundle() not in a view files?
First of all, what is public $sourcePath = '#frontend/assets';? it is not the correct path this path actually has your Asset.php files, not the source files. According to the documentation
sourcePath: specifies the root directory that contains the asset
files in this bundle. This property should be set if the root
directory is not Web accessible. Otherwise, you should set the
basePath property and baseUrl, instead. Path aliases can be used here.
Just place your .css files under frontend/web/css and .js under frontend/web/js and remove the sourcePath you do not need it as looking at your code, only in case if you had your source files under frontend/themes/basic then you would use sourcePath like public $sourcePath = '#frontend/themes/basic/'; because this path isnt under the web accessable directory
And for adding the timestamp You do not have to do anything other than adding the appendTimestamp options under the components section in the assetManager, make sure you are adding assetManager under components. and it will automatically start adding ?v=125453612 with all CSS and js files
your AppAsset.php
class AppAsset extends AssetBundle
{
public $basePath = '#webroot';
public $baseUrl = '#web';
public $css = [
'css/style.css'
];
}
frontend/config/main.php
'components' => [
..........
..........
'assetManager' => [
'appendTimestamp' => true
]
..........
..........
],
and your file will start looking like this
I can show you a live example of the same site if you want to have a look into the view-source
EDIT
As you provided the source code screen grab and looking at your code I can tell that you are using trailing slash / with your files, remove the trailing slashes from your source files path, I also overlooked it the first glance but then looking the code i couldn't find any other thing than this one that could be wrong. they should be like this
'css/new.css',
'css/new2.css',
and same for the js files too.
Try write public $css and public $js without forst slash ("js/.." instead "/js/..").

Yii2 location from dependencies in custom asset

I have a path something like /actions/users/someaction in the frontend and I want to use the Bootstrap-Asset (located in /backend/web/assets/xxxxxx/) from the backend.
So I created an asset called "ActionAsset" with following content:
class ActionAsset extends AssetBundle
{
public $basePath = '#backend';
public $baseUrl = '#web/backend';
public $css = [
'css/external.css',
'css/overwrite-bootstrap.css',
];
public $js = [
];
public $depends = [
'yii\web\YiiAsset',
'yii\bootstrap\BackendBootstrapAsset',
];
}
The included css are just working fine, but the dependencies are always saved in /frontend/web/assets/.
My question is (and I really searched for weeks) how to change this location to /backend/web/assets.
You need to define $sourcePath. Yii2 AssetManager will copy (or symlink) your assets in your current web/assets/ folder.
From the docs
sourcePath: specifies the root directory that contains the asset files in this bundle. This property should be set if the root directory is not Web accessible. Otherwise, you should set the basePath property and baseUrl, instead. Path aliases can be used here.
So change your code to:
class ActionAsset extends AssetBundle
{
public $sourcePath = '<path to your asste content>';
public $css = [
'css/external.css',
'css/overwrite-bootstrap.css',
];
public $js = [
];
public $depends = [
'yii\web\YiiAsset',
'yii\bootstrap\BackendBootstrapAsset',
];
}
Or: Just overwrite your asstetbundle in #frontend/asset and set $sourcePath property accordingly:
class FrontendActionAsset extends ActionAsset
{
public $sourcePath = '<path to your asste content>'; //you don't need more
}
Asset Publishing
As aforementioned, if an asset bundle is located in a directory that is not Web accessible, its assets will be copied to a Web directory when the bundle is being registered with a view. This process is called asset publishing, and is done automatically by the asset manager.
By default, assets are published to the directory #webroot/assets which corresponds to the URL #web/assets. You may customize this location by configuring the basePath and baseUrl properties.
Instead of publishing assets by file copying, you may consider using symbolic links, if your OS and Web server allow. This feature can be enabled by setting linkAssets to be true.
return [
// ...
'components' => [
'assetManager' => [
'linkAssets' => true,
],
],
];
With the above configuration, the asset manager will create a symbolic link to the source path of an asset bundle when it is being published. This is faster than file copying and can also ensure that the published assets are always up-to-date.
https://www.yiiframework.com/doc/guide/2.0/en/structure-assets

How to add assetbundle js/css add only in one page in yii2?

I have added fullcalendar js/css in vendor/bower folder. I want to add this into just one page.
I read abt AssestBundle on this link - http://www.yiiframework.com/doc-2.0/guide-structure-assets.html
But this add in all the pages.
In Yii 2 framework asset bundles is recommended way of working with js / css. It's not limited to just adding to all pages. You can use it only in specific view.
Example of asset bundle for JsTree plugin:
<?php
namespace backend\assets;
use yii\web\AssetBundle;
class JsTreeAsset extends AssetBundle
{
public $sourcePath = '#bower_components/jstree/dist';
public $js = [
'jstree.min.js',
];
public $css = [
'themes/default/style.min.css',
];
public $depends = [
'yii\web\JqueryAsset',
];
}
In this example, #bower_components alias is used, in order to get it working you also need to register it in application bootstrap file (in advanced application template this file is common/config/bootstrap.php):
Yii::setAlias('bower_components', dirname(dirname(__DIR__)) . '/bower_components');
Then, in view where you need to use it, call register() method of this asset bundle and pass current view:
use backend\assets\JsTreeAsset;
...
JsTreeAsset::register($this);
The files in default asset bundle (AppAsset) which included in application templates are loaded in every view because it's registered in application layout and layout is applied to all views.

Theme based module's views in yii2

I am using Yii2 Advanced Template. I have created user module inside /frontend/modules/ directory. without theme integration, views are called from /modules/user/views/ directory.
Currently, I have created three different themes inside /frontend directory. So I would like to access views from theme directory for User Module. How it would be possible?
It is possible to set layout for module by
$this->layoutPath = \Yii::getAlias('/themes/classic/views/layouts/');
$this->layout = 'userLayout';
But How views can be accessed from theme directory for module?
Please suggest possible solutions..
I found solution to my question. I have implemented following way.
Added Layout path in Module.php after init() method.
public function init()
{
parent::init();
$this->layoutPath = \Yii::getAlias('#app/themes/classic/views/layouts/');
$this->layout = 'userLayout';
}
and
added theme configuration with module views in main.php config file
'view' => [
'theme' => [
'pathMap' => [
'#app/views' =>'#app/themes/classic/views/',
'#app/modules'=>'#app/themes/classic/modules',
'#app/widgets'=>'#app/themes/classic/widgets'
],
'baseUrl'=>"/themes/classic",
],
],

Yii2 - Include JS Script Only For Specific View

I want to include my js script specific.js for a specific view having action id specific-action-id. I don't want the specific.js to be included in every page.
For including a js script for the whole site I normally have to edit AppAsset.php. For this purpose, what should I do?
You should simply register this js file in your view, e.g. :
$this->registerJsFile('#web/js/specific.js');
Read more : http://www.yiiframework.com/doc-2.0/guide-output-client-scripts.html#registering-scripts
It is highly recommended to use asset bundles to register external JS files rather than registerJsFile() because these allow better flexibility and more granular dependency configuration. Also using asset bundles allows you to combine and compress multiple JS files, which is desirable for high traffic websites.
So you can create a new AppAsset file and put your css and javascript files in it.
Create the Asset Bundle
In the \assets directory, we create StatusAsset.php:
<?php
/**
* #link http://www.yiiframework.com/
* #copyright Copyright (c) 2008 Yii Software LLC
* #license http://www.yiiframework.com/license/
*/
namespace app\assets;
use yii\web\AssetBundle;
/**
* #author Qiang Xue <qiang.xue#gmail.com>
* #since 2.0
*/
class StatusAsset extends AssetBundle
{
public $basePath = '#webroot';
public $baseUrl = '#web';
public $css = [];
public $js = [
'/js/jquery.simplyCountable.js',
'/js/twitter-text.js',
'/js/twitter_count.js',
'/js/status-counter.js',
];
public $depends = [
'yii\web\YiiAsset',
'yii\bootstrap\BootstrapAsset',
];
}
In your view file
use app\assets\StatusAsset;
StatusAsset::register($this);
Resources
http://www.yiiframework.com/doc-2.0/guide-output-client-scripts.html
https://code.tutsplus.com/tutorials/how-to-program-with-yii2-working-with-asset-bundles--cms-23226
#soju is right. But you also can create specific asset bundles for use specific views. Your specific js files can be a file group on this situation you can use asset bundles and can use any views which you want.