For example, I created a new page, and I'd like to use, for example, backbone.js, custom css file and some collection of images. Where should I declare all this stuff in Yii2? I found the AppAsset.php module, but this is only for css/js files and I haven't noticed any changes when my css/js files and path were declared there:
class AppAsset extends AssetBundle {
public $basePath = '#webroot';
public $baseUrl = '#web';
public $css = [
'css/site.css',
'js/jquery.mobile-1.4.2.min.css',
];
public $js = [
'js/jsquery-2.1.0.min.js',
'js/jquery.mobile-1.4.2.min.js',
'js/script.js',
];
public $depends = [
'yii\web\YiiAsset',
'yii\bootstrap\BootstrapAsset',
];
}
What am I doing wrong?
It took me a while to figure it out, but below is the relevant part of the Yii2 source code
if ($this->sourcePath !== null && !isset($this->basePath, $this->baseUrl)) {
list ($this->basePath, $this->baseUrl) = $am->publish($this->sourcePath, $this->publishOptions);
}
So Yii2 will publish assets only if $sourcePath is set, and $basePath and $baseUrl are not set(!). The latter tripped me up, and it looks like the same goes for you.
So I have this AppAsset, which duly publishes
use yii\web\AssetBundle;
class AppAsset extends AssetBundle
{
public $sourcePath = '#app/assets/app';
public $css = [
'css/openbook.css',
'fontello/css/fontello.css',
'fontello/css/animation.css'
];
public $js = [
'js/plug.openbook.js',
'js/plug.interpret.js',
'js/plug.drop.message.js'
];
public $depends = [
// 'yii\web\YiiAsset',
// 'yii\bootstrap\BootstrapAsset',
];
}
Of course, I have in the main layout
use frontend\assets\AppAsset;
...
AppAsset::register($this);
to use this AppAsset or any other you should register it in the view
use app\assets\AppAsset;
AppAsset::register($this);
At first, you should create SomeAsset class in your app/assets/ folder with your new js and css files.
You can extend your AppAsset overloading its properties.
Next use this in SomeController
use Yii;
use app\assets\SomeAsset;
and in actionSome like this:
SomeAsset::register(Yii::$app->view);
From personal experience, assets are one of the parts of Yii that I found extremely frustrating.
It is hard to reliably find out where the file is going to be and the switching back and forth with debug mode on and off will create further frustration.
I suggest scrapping the asset handling and just keep all your JS files in a folder, then it can be included like this:
Yii::app()->clientScript->registerScriptFile('/js/jquery.jeditable.mini.js');
Related
I was trying to add an uploadfield to a Custom DataExtension and got the Image field working. However the image i uploaded stays in concept mode, and i have to go to the File tab to publish it. I tried to use the code provided in the Silverstripe documentation but this only seems to work on regular pages. I found a question similar to mine:How to automaticaly publish files uploaded to a dataobject in Silverstripe model admin however this only seems to work on DataObjects.
This is my current code:
<?php
use SilverStripe\Forms\LiteralField;
use SilverStripe\Forms\TextField;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\HTMLEditor\HTMLEditorField;
use SilverStripe\AssetAdmin\Forms\UploadField;
use SilverStripe\Assets\Image;
use SilverStripe\Assets\Storage\AssetStore;
use SilverStripe\Versioned\Versioned;
use SilverStripe\ORM\DataExtension;
class CustomSiteConfig extends DataExtension
{
private static $db = [
];
private static $has_one = [
'Logo' => Image::class
];
private static $owns = [
'Logo'
];
private static $extensions = [
Versioned::class,
];
private static $versioned_gridfield_extensions = true;
public function updateCMSFields(FieldList $fields)
{
$fields->addFieldToTab("Root.Header", LiteralField::create("","<h1>Header</h1>"));
$fields->addFieldToTab("Root.Header", UploadField::create('Logo', 'Logo'));
}
}
Does anyone know a solution?
There's currently a bug that prevents "owned" records to be published if the owning dataobject is not versioned.
I think you're experience this bug, since SiteConfig is not versioned and thus won't publish owned files/images when it's being saved.
Until this bug has been resolved, you could use an onAfterWrite hook in your extension to publish the file:
public function onAfterWrite()
{
if ($this->owner->LogoID) {
$this->owner->Logo()->publishSingle();
}
}
I have a widget that uses assets. The asset look like this:
class publicHeaderNavbarAsset extends AssetBundle {
public $sourcePath = '#app/components/#device';
public $css = [
'styles.css'
];
public $js = [];
public $depends = [];
}
I also have a (bootstrapped) component, defined like that:
class Aliases extends Component {
public function init() {
Yii::setAlias('#device', Utils::device());
}
}
Utils::device() is a function that parses the UA of the device and returns mobile, tablet or desktop, depending on the device type.
The problem is that Yii2 doesn't seem to be converting #device to the value it has. I first thought that it could be my fault, but then I changed the sourcePath to:
public $sourcePath = '#app/components/#app';
just to see if that will trigger an error with a duplicated path (basepath/componenets/basepath), but it didn't.
Is there a way I can change the sourcePath of my asset at runtime? Or maybe make Yii2 parse all the aliases in sourcePath?
Look at the getAlias function http://www.getyii.com/doc-2.0/api/yii-baseyii.html#getAlias()-detail
It will basically not match your second alias in the string you have given it.
You can try setting
Yii::setAlias('#device', '#app/components/' . Utils::device());
and
public $sourcePath = '#device';
This should work as you should be able to set an alias based on another alias
http://www.yiiframework.com/doc-2.0/guide-concept-aliases.html#defining-aliases
I have one asset bundle (AppAsset) which registered in my main layout (main.php) for common assets for the entire application:
class AppAsset extends AssetBundle
{
public $basePath = '#webroot';
public $baseUrl = '#web';
public $css = [
'css/style.css',
];
public $depends = [
'yii\web\JqueryAsset',
'yii\bootstrap\BootstrapAsset',
];
}
But on one certain page (not on entire app!) i need to change my jquery to a lower version and hook up other assets. And i'm registeting another asset bundle which depends on main asset bundle AppAsset in the desired view file :
class GalleryAsset extends AssetBundle
{
public $basePath = '#webroot';
public $baseUrl = '#web';
public $css = [
'css/gamma/style.css',
'css/gamma/noJS.css',
];
public $js = [
'js/gamma/modernizr.custom.70736.js',
'js/gamma/jquery.masonry.min.js',
'js/gamma/jquery.history.js',
'js/gamma/js-url.min.js',
'js/gamma/jquerypp.custom.js',
'js/gamma/gamma.js',
];
public $depends = [
'app\assets\AppAsset',
];
}
The question is how can i change the Jquery's version in child asset bundle GalleryAsset or in one certain view file (page)?
Thank you and God bless helpers.
You can read how to customize asset bundles in offical documentation.
But customizing through application config is not suitable here, because at that moment requested route is unknown.
You can change the necessary asset bundle at runtime using assetManager component:
use Yii;
...
Yii::$app->assetManager->bundles['yii\web\JqueryAsset'] = [
'sourcePath' => null,
'js' => ['jquery.js' => 'https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.js'],
];
Make sure to place this code before registering asset bundle related with that page.
In that case all assets depending on yii\web\JqueryAsset will cause registering older version.
Also I recommend additionally check compatibility of used plugins with this version (it's not that old though).
I would like to use different js files for development and production mode in Yii2. The development mode has lot of files unminified, although the production would have a single file.
The development asset goes like this:
namespace frontend\assets;
use yii\web\AssetBundle;
class AppAsset extends AssetBundle {
public $basePath = '#webroot';
public $baseUrl = '#web';
public $css = [
'css/main.css',
];
public $js = [
'js/app/_variables.js',
'js/app.js',
'js/app/_api_conn.js',
'js/app/_docCookies.js',
'js/app/ ..... .js',
];
public $depends = [
'yii\bootstrap\BootstrapPluginAsset',
];
}
And I would like to have this particular bundle like this in production mode, already merged and minified locally:
namespace frontend\assets;
use yii\web\AssetBundle;
class AppAsset extends AssetBundle {
public $basePath = '#webroot';
public $baseUrl = '#web';
public $css = [
'css/main.css',
];
public $js = [
'js/wfapp_all_min.js',
];
public $depends = [
'yii\bootstrap\BootstrapPluginAsset',
];
}
As the Yii2 documentation explains there is a single method to do this, but I can't find out, where to add it (the example is for jquery asset, but seems right method for my case as well):
'yii\web\JqueryAsset' => [
'js' => [
YII_ENV_DEV ? 'jquery.js' : 'jquery.min.js'
]
],
So what is the proper way to implement this? Thanks in advance!
In case of different amount of files for debug and production servers, you can set them during initialization in init() method:
public function init()
{
$this->js = !YII_DEBUG ? ['js/wfapp_all_min.js'] : [
'js/app/_variables.js',
'js/app.js',
'js/app/_api_conn.js',
'js/app/_docCookies.js',
'js/app/ ..... .js',
];
parent::init();
}
Don't forget to call the parent implementation at the end.
Yii is great but assets is the thing that was always strange for me (since the 1.1 version).
I'm using Yii2 currently with Advanced app template. I want to register some css/js files in frontend main layout view (trying to use HTML5UP Prologue Template).
How it can be done? I placed my css files under frontend/web/css directory, js under frontend/web/js and layout images under frontend/web/images dir.
Under frontend/assets directory I created PrologueAssets class like this:
namespace frontend\assets;
use yii\web\AssetBundle;
class PrologueAssets extends AssetBundle {
public $sourcePath = "#webroot";
public $css = [
'css/skel.css',
'css/style.css',
'css/style-wide.css',
];
public $js = [
'js/jquery.min.js',
'js/jquery.scrolly.min.js',
'js/jquery.scrollzer.min.js',
'js/skel.min.js',
'js/skel-layers.min.js',
'js/init.js',
];
static function register($view) {
die(self::sourcePath);
parent::register($view);
}
}
Unfortunately none of these files are registered. How to do that?
Little second question - how to register css files only if eg IE8 or IE9 is detected?
You should simply try:
class PrologueAssets extends AssetBundle
{
public $basePath = '#webroot';
public $baseUrl = '#web';
public $css = [
...
];
public $js = [
...
];
}
http://www.yiiframework.com/doc-2.0/guide-structure-assets.html
PS : assets management is currently being refactored :
https://github.com/yiisoft/yii2/pull/4855
I wanted to add two files,one under frontend/web/css/custom.css and frontend/web/js/custom.js I just found the frontend/assets/AppAsset.php and added them directly and the two files are loaded for every page i load.
class AppAsset extends AssetBundle
{
public $basePath = '#webroot';
public $baseUrl = '#web';
public $css = [
'css/site.css',
'css/custom.css',
];
public $js = [
'js/custom.js',
];
public $depends = [
'yii\web\YiiAsset',
'yii\bootstrap\BootstrapAsset',
];
}
This is how you register js or css for ie 8 only
namespace app\assets;
use yii\web\AssetBundle;
class IE8Assets extends AssetBundle
{
public $basePath = '#webroot';
public $baseUrl = '#web';
public $css=[
'css/ie8.css'
];
public $cssOptions = ['condition' => 'lte IE9'];
public $js =[
'js/jquery-1.11.3.min.js',
'js/jquery-migrate-1.2.1.min.js',
];
public $jsOptions = ['condition' => 'lte IE9'];
}